mirror of
				https://github.com/boostorg/smart_ptr.git
				synced 2025-11-04 01:31:51 +01:00 
			
		
		
		
	Compare commits
	
		
			215 Commits
		
	
	
		
			boost-1.34
			...
			boost-1.49
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					ed70b77d8b | ||
| 
						 | 
					3090f6f4af | ||
| 
						 | 
					40073ef64f | ||
| 
						 | 
					b9970eda45 | ||
| 
						 | 
					9147489b4c | ||
| 
						 | 
					d1348ea05e | ||
| 
						 | 
					90db9a6435 | ||
| 
						 | 
					1c208ad3ea | ||
| 
						 | 
					5fc9bf5bc5 | ||
| 
						 | 
					c846d230f0 | ||
| 
						 | 
					7b097467d6 | ||
| 
						 | 
					7cb040edb0 | ||
| 
						 | 
					d6ac116b71 | ||
| 
						 | 
					8abc8889d1 | ||
| 
						 | 
					c5b47e2136 | ||
| 
						 | 
					7c0815c567 | ||
| 
						 | 
					210288f02e | ||
| 
						 | 
					cf7b6904e8 | ||
| 
						 | 
					b978919dd1 | ||
| 
						 | 
					1086aff971 | ||
| 
						 | 
					445e8d1728 | ||
| 
						 | 
					545745d649 | ||
| 
						 | 
					d71cc6ab08 | ||
| 
						 | 
					0d77fd0678 | ||
| 
						 | 
					6ca6d3ce6f | ||
| 
						 | 
					cfc82854d3 | ||
| 
						 | 
					b9d77d877e | ||
| 
						 | 
					1f50e3abe4 | ||
| 
						 | 
					697f338510 | ||
| 
						 | 
					f4386409d9 | ||
| 
						 | 
					ba349679f3 | ||
| 
						 | 
					a3b84f8586 | ||
| 
						 | 
					b0fd8a6b08 | ||
| 
						 | 
					4f5062004a | ||
| 
						 | 
					f040bed751 | ||
| 
						 | 
					2f8945a885 | ||
| 
						 | 
					2bd0778778 | ||
| 
						 | 
					eec640bfd7 | ||
| 
						 | 
					754fd941ee | ||
| 
						 | 
					e94f64039d | ||
| 
						 | 
					63b17c24ea | ||
| 
						 | 
					8a421c2098 | ||
| 
						 | 
					5fa1cbf6e1 | ||
| 
						 | 
					9f30442d1e | ||
| 
						 | 
					a4293f9dfa | ||
| 
						 | 
					28de0cb1e3 | ||
| 
						 | 
					a1b4fc8d95 | ||
| 
						 | 
					77971c6ff5 | ||
| 
						 | 
					1742c37942 | ||
| 
						 | 
					31e06b4a1d | ||
| 
						 | 
					22f1b092c9 | ||
| 
						 | 
					5a2771e585 | ||
| 
						 | 
					dad59f3325 | ||
| 
						 | 
					bad394b1e9 | ||
| 
						 | 
					f93110620a | ||
| 
						 | 
					6be1e3fceb | ||
| 
						 | 
					cf91287732 | ||
| 
						 | 
					0da6902267 | ||
| 
						 | 
					10f6ff8b77 | ||
| 
						 | 
					13f91c15f0 | ||
| 
						 | 
					a2c5208b8e | ||
| 
						 | 
					55583ac749 | ||
| 
						 | 
					c40b306647 | ||
| 
						 | 
					d9b9921d23 | ||
| 
						 | 
					6f91ea87c3 | ||
| 
						 | 
					ed79000ea8 | ||
| 
						 | 
					6e804e64b8 | ||
| 
						 | 
					395766e2d3 | ||
| 
						 | 
					774332f85a | ||
| 
						 | 
					f5990cab65 | ||
| 
						 | 
					6175baf858 | ||
| 
						 | 
					2fb567b3f2 | ||
| 
						 | 
					2b25579338 | ||
| 
						 | 
					a97cd2d0cc | ||
| 
						 | 
					e3b9389a24 | ||
| 
						 | 
					6ba78f76f6 | ||
| 
						 | 
					8c7954a53a | ||
| 
						 | 
					556b9fe563 | ||
| 
						 | 
					77ab953171 | ||
| 
						 | 
					991b02b03e | ||
| 
						 | 
					31d0c48f18 | ||
| 
						 | 
					1b49f08cb8 | ||
| 
						 | 
					034c12d244 | ||
| 
						 | 
					f884c53bd6 | ||
| 
						 | 
					07b4c17980 | ||
| 
						 | 
					1bc4f16ff8 | ||
| 
						 | 
					774a8d330c | ||
| 
						 | 
					0fd94d6d56 | ||
| 
						 | 
					866590ee97 | ||
| 
						 | 
					2a92df56f2 | ||
| 
						 | 
					a9cd84f43d | ||
| 
						 | 
					366472fc35 | ||
| 
						 | 
					2bfe13c9c4 | ||
| 
						 | 
					83e2510ce5 | ||
| 
						 | 
					31685fe551 | ||
| 
						 | 
					05e050abe0 | ||
| 
						 | 
					d261079616 | ||
| 
						 | 
					d52878df88 | ||
| 
						 | 
					4b0490c0ae | ||
| 
						 | 
					2f1b1acc7a | ||
| 
						 | 
					f0f9f72be6 | ||
| 
						 | 
					efdc390bc9 | ||
| 
						 | 
					d13f1d8694 | ||
| 
						 | 
					83c43617af | ||
| 
						 | 
					da323af72d | ||
| 
						 | 
					0c4aaef77c | ||
| 
						 | 
					440fcb7ba0 | ||
| 
						 | 
					18a6c1add8 | ||
| 
						 | 
					357d3c4d54 | ||
| 
						 | 
					4bb747fb27 | ||
| 
						 | 
					f13591ef2b | ||
| 
						 | 
					e3422efec6 | ||
| 
						 | 
					a01e4c3f83 | ||
| 
						 | 
					6f8dc5923c | ||
| 
						 | 
					7dc6b3d810 | ||
| 
						 | 
					2251b1d2df | ||
| 
						 | 
					8b3907ae81 | ||
| 
						 | 
					77f2d3f614 | ||
| 
						 | 
					93545d5cf2 | ||
| 
						 | 
					9e92c6354c | ||
| 
						 | 
					e12ed6864b | ||
| 
						 | 
					b541145a60 | ||
| 
						 | 
					ca344809ba | ||
| 
						 | 
					7802c695ef | ||
| 
						 | 
					71fa2cd658 | ||
| 
						 | 
					04be979670 | ||
| 
						 | 
					35f2af947c | ||
| 
						 | 
					3a578ac7c1 | ||
| 
						 | 
					9365853fde | ||
| 
						 | 
					16828c9c0a | ||
| 
						 | 
					2fe899cdfe | ||
| 
						 | 
					b45d011d5a | ||
| 
						 | 
					4094c23537 | ||
| 
						 | 
					f85a1bf406 | ||
| 
						 | 
					dbd62686a3 | ||
| 
						 | 
					e4f638025c | ||
| 
						 | 
					d8296b3933 | ||
| 
						 | 
					b4885a1dd6 | ||
| 
						 | 
					748b1baee8 | ||
| 
						 | 
					4880292c07 | ||
| 
						 | 
					6b25c57712 | ||
| 
						 | 
					373c52efa3 | ||
| 
						 | 
					acb6824ef7 | ||
| 
						 | 
					316d00c3fc | ||
| 
						 | 
					515be965bd | ||
| 
						 | 
					6ef32e1627 | ||
| 
						 | 
					2452705117 | ||
| 
						 | 
					bb076d67e6 | ||
| 
						 | 
					b08789b784 | ||
| 
						 | 
					5df69a8946 | ||
| 
						 | 
					dc6a8f0696 | ||
| 
						 | 
					af7d4fabad | ||
| 
						 | 
					d17a096407 | ||
| 
						 | 
					d7448b5746 | ||
| 
						 | 
					f22516d650 | ||
| 
						 | 
					b30aa1468a | ||
| 
						 | 
					5b17f88f0e | ||
| 
						 | 
					1c2d780f9e | ||
| 
						 | 
					2eb3991630 | ||
| 
						 | 
					3a4dc43924 | ||
| 
						 | 
					a055d9829e | ||
| 
						 | 
					f596092bac | ||
| 
						 | 
					4ba016d29e | ||
| 
						 | 
					7ca6d86bdc | ||
| 
						 | 
					b2a3c9e59d | ||
| 
						 | 
					60ae24f4ae | ||
| 
						 | 
					dba6ebbb01 | ||
| 
						 | 
					d2194e3b24 | ||
| 
						 | 
					5ab6b24856 | ||
| 
						 | 
					e6f6ec9fa3 | ||
| 
						 | 
					f854829d86 | ||
| 
						 | 
					7b5beeedde | ||
| 
						 | 
					9e41d1f194 | ||
| 
						 | 
					f49a2fb1e1 | ||
| 
						 | 
					87c6b6b403 | ||
| 
						 | 
					9db307eda5 | ||
| 
						 | 
					5a85c1f0f2 | ||
| 
						 | 
					f5ce4dbc4c | ||
| 
						 | 
					b2354d0a5e | ||
| 
						 | 
					e0ca42bb88 | ||
| 
						 | 
					bca336bf35 | ||
| 
						 | 
					6646d8acd2 | ||
| 
						 | 
					c66f0aeecc | ||
| 
						 | 
					ecb41cb150 | ||
| 
						 | 
					ed8db8b5f2 | ||
| 
						 | 
					4ba37fce95 | ||
| 
						 | 
					5b57eff9b8 | ||
| 
						 | 
					f980da560a | ||
| 
						 | 
					ffba68221b | ||
| 
						 | 
					4d45e5b9b5 | ||
| 
						 | 
					86d3f0aba7 | ||
| 
						 | 
					66a25bd4a9 | ||
| 
						 | 
					745dbedbaa | ||
| 
						 | 
					26f83e75ef | ||
| 
						 | 
					ce72827dc7 | ||
| 
						 | 
					6e8f075d42 | ||
| 
						 | 
					ae6c180be8 | ||
| 
						 | 
					54e12d03fd | ||
| 
						 | 
					469578e976 | ||
| 
						 | 
					97118668e2 | ||
| 
						 | 
					1c3813ce52 | ||
| 
						 | 
					b440e85452 | ||
| 
						 | 
					0609322489 | ||
| 
						 | 
					b215e34650 | ||
| 
						 | 
					6284a1abef | ||
| 
						 | 
					41d4167533 | ||
| 
						 | 
					75bc821afd | ||
| 
						 | 
					39551bdc1a | ||
| 
						 | 
					6412de1dd5 | ||
| 
						 | 
					8d2f7fc5ef | ||
| 
						 | 
					ffd73c39b3 | ||
| 
						 | 
					4fcee64483 | ||
| 
						 | 
					203764eb51 | ||
| 
						 | 
					747c9a1d3e | ||
| 
						 | 
					e38d0daaab | 
@@ -81,9 +81,8 @@
 | 
			
		||||
		</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>
 | 
			
		||||
		<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>
 | 
			
		||||
</html>
 | 
			
		||||
 
 | 
			
		||||
@@ -29,20 +29,24 @@
 | 
			
		||||
			and <STRONG>shared_ptr<T const></STRONG>, depending on constness, to <STRONG>this</STRONG>.</P>
 | 
			
		||||
		<h3><a name="Example">Example</a></h3>
 | 
			
		||||
		<pre>
 | 
			
		||||
class Y: public enable_shared_from_this<Y>
 | 
			
		||||
#include <boost/enable_shared_from_this.hpp>
 | 
			
		||||
#include <boost/shared_ptr.hpp>
 | 
			
		||||
#include <cassert>
 | 
			
		||||
 | 
			
		||||
class Y: public boost::enable_shared_from_this<Y>
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    shared_ptr<Y> f()
 | 
			
		||||
    boost::shared_ptr<Y> f()
 | 
			
		||||
    {
 | 
			
		||||
        return shared_from_this();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    shared_ptr<Y> p(new Y);
 | 
			
		||||
    shared_ptr<Y> q = p->f();
 | 
			
		||||
    boost::shared_ptr<Y> p(new Y);
 | 
			
		||||
    boost::shared_ptr<Y> q = p->f();
 | 
			
		||||
    assert(p == q);
 | 
			
		||||
    assert(!(p < q || q < p)); // p and q must share ownership
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -12,97 +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)
 | 
			
		||||
//
 | 
			
		||||
//  typedef <implementation-defined> boost::detail::atomic_count;
 | 
			
		||||
//
 | 
			
		||||
//  atomic_count a(n);
 | 
			
		||||
//
 | 
			
		||||
//    (n is convertible to long)
 | 
			
		||||
//
 | 
			
		||||
//    Effects: Constructs an atomic_count with an initial value of n
 | 
			
		||||
//
 | 
			
		||||
//  a;
 | 
			
		||||
//
 | 
			
		||||
//    Returns: (long) the current value of a
 | 
			
		||||
//
 | 
			
		||||
//  ++a;
 | 
			
		||||
//
 | 
			
		||||
//    Effects: Atomically increments the value of a
 | 
			
		||||
//    Returns: nothing
 | 
			
		||||
//
 | 
			
		||||
//  --a;
 | 
			
		||||
//
 | 
			
		||||
//    Effects: Atomically decrements the value of a
 | 
			
		||||
//    Returns: (long) zero if the new value of a is zero,
 | 
			
		||||
//      unspecified non-zero value otherwise (usually the new value)
 | 
			
		||||
//
 | 
			
		||||
//    Important note: when --a returns zero, it must act as a
 | 
			
		||||
//      read memory barrier (RMB); i.e. the calling thread must
 | 
			
		||||
//      have a synchronized view of the memory
 | 
			
		||||
//
 | 
			
		||||
//    On Intel IA-32 (x86) memory is always synchronized, so this
 | 
			
		||||
//      is not a problem.
 | 
			
		||||
//
 | 
			
		||||
//    On many architectures the atomic instructions already act as
 | 
			
		||||
//      a memory barrier.
 | 
			
		||||
//
 | 
			
		||||
//    This property is necessary for proper reference counting, since
 | 
			
		||||
//      a thread can update the contents of a shared object, then
 | 
			
		||||
//      release its reference, and another thread may immediately
 | 
			
		||||
//      release the last reference causing object destruction.
 | 
			
		||||
//
 | 
			
		||||
//    The destructor needs to have a synchronized view of the
 | 
			
		||||
//      object to perform proper cleanup.
 | 
			
		||||
//
 | 
			
		||||
//    Original example by Alexander Terekhov:
 | 
			
		||||
//
 | 
			
		||||
//    Given:
 | 
			
		||||
//
 | 
			
		||||
//    - a mutable shared object OBJ;
 | 
			
		||||
//    - two threads THREAD1 and THREAD2 each holding 
 | 
			
		||||
//      a private smart_ptr object pointing to that OBJ.
 | 
			
		||||
//
 | 
			
		||||
//    t1: THREAD1 updates OBJ (thread-safe via some synchronization)
 | 
			
		||||
//      and a few cycles later (after "unlock") destroys smart_ptr;
 | 
			
		||||
//
 | 
			
		||||
//    t2: THREAD2 destroys smart_ptr WITHOUT doing any synchronization 
 | 
			
		||||
//      with respect to shared mutable object OBJ; OBJ destructors
 | 
			
		||||
//      are called driven by smart_ptr interface...
 | 
			
		||||
//
 | 
			
		||||
//  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>
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_HAS_THREADS
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
typedef long atomic_count;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#elif defined(BOOST_AC_USE_PTHREADS)
 | 
			
		||||
#  include <boost/detail/atomic_count_pthreads.hpp>
 | 
			
		||||
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
 | 
			
		||||
#  include <boost/detail/atomic_count_win32.hpp>
 | 
			
		||||
#elif defined(__GLIBCPP__) || defined(__GLIBCXX__)
 | 
			
		||||
#  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
 | 
			
		||||
#error Unrecognized threading platform
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
#include <boost/smart_ptr/detail/atomic_count.hpp>
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_DETAIL_ATOMIC_COUNT_HPP_INCLUDED
 | 
			
		||||
 
 | 
			
		||||
@@ -12,31 +12,11 @@
 | 
			
		||||
//
 | 
			
		||||
//  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)
 | 
			
		||||
//
 | 
			
		||||
//  typedef <unspecified> boost::detail::lightweight_mutex;
 | 
			
		||||
//
 | 
			
		||||
//  boost::detail::lightweight_mutex is a header-only implementation of
 | 
			
		||||
//  a subset of the Mutex concept requirements:
 | 
			
		||||
//
 | 
			
		||||
//  http://www.boost.org/doc/html/threads/concepts.html#threads.concepts.Mutex
 | 
			
		||||
//
 | 
			
		||||
//  It maps to a CRITICAL_SECTION on Windows or a pthread_mutex on POSIX.
 | 
			
		||||
//  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_HAS_THREADS)
 | 
			
		||||
# include <boost/detail/lwm_nop.hpp>
 | 
			
		||||
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
 | 
			
		||||
#  include <boost/detail/lwm_win32_cs.hpp>
 | 
			
		||||
#elif defined(BOOST_HAS_PTHREADS)
 | 
			
		||||
#  include <boost/detail/lwm_pthreads.hpp>
 | 
			
		||||
#else
 | 
			
		||||
// Use #define BOOST_DISABLE_THREADS to avoid the error
 | 
			
		||||
#  error Unrecognized threading platform
 | 
			
		||||
#endif
 | 
			
		||||
#include <boost/smart_ptr/detail/lightweight_mutex.hpp>
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED
 | 
			
		||||
 
 | 
			
		||||
@@ -1,69 +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 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_PTHREADS )
 | 
			
		||||
 | 
			
		||||
# include <boost/detail/sp_counted_base_pt.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) )
 | 
			
		||||
 | 
			
		||||
# include <boost/detail/sp_counted_base_gcc_x86.hpp>
 | 
			
		||||
 | 
			
		||||
//~ #elif defined( __MWERKS__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) )
 | 
			
		||||
 | 
			
		||||
//~ # include <boost/detail/sp_counted_base_cw_x86.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( __GNUC__ ) && defined( __ia64__ ) && !defined( __INTEL_COMPILER )
 | 
			
		||||
 | 
			
		||||
# include <boost/detail/sp_counted_base_gcc_ia64.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( __MWERKS__ ) && defined( __POWERPC__ )
 | 
			
		||||
 | 
			
		||||
# include <boost/detail/sp_counted_base_cw_ppc.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( __GNUC__ ) && ( defined( __powerpc__ ) || defined( __ppc__ ) )
 | 
			
		||||
 | 
			
		||||
# include <boost/detail/sp_counted_base_gcc_ppc.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>
 | 
			
		||||
 | 
			
		||||
#elif defined( BOOST_HAS_PTHREADS )
 | 
			
		||||
 | 
			
		||||
# include <boost/detail/sp_counted_base_pt.hpp>
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
// Use #define BOOST_DISABLE_THREADS to avoid the error
 | 
			
		||||
# error Unrecognized threading platform
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED
 | 
			
		||||
							
								
								
									
										135
									
								
								include/boost/detail/sp_typeinfo.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										135
									
								
								include/boost/detail/sp_typeinfo.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,135 @@
 | 
			
		||||
#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 )
 | 
			
		||||
 | 
			
		||||
#include <boost/current_function.hpp>
 | 
			
		||||
#include <functional>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
class sp_typeinfo
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    sp_typeinfo( sp_typeinfo const& );
 | 
			
		||||
    sp_typeinfo& operator=( sp_typeinfo const& );
 | 
			
		||||
 | 
			
		||||
    char const * name_;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    explicit sp_typeinfo( char const * name ): name_( name )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool operator==( sp_typeinfo const& rhs ) const
 | 
			
		||||
    {
 | 
			
		||||
        return this == &rhs;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool operator!=( sp_typeinfo const& rhs ) const
 | 
			
		||||
    {
 | 
			
		||||
        return this != &rhs;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool before( sp_typeinfo const& rhs ) const
 | 
			
		||||
    {
 | 
			
		||||
        return std::less< sp_typeinfo const* >()( this, &rhs );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    char const* name() const
 | 
			
		||||
    {
 | 
			
		||||
        return name_;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<class T> struct sp_typeid_
 | 
			
		||||
{
 | 
			
		||||
    static sp_typeinfo ti_;
 | 
			
		||||
 | 
			
		||||
    static char const * name()
 | 
			
		||||
    {
 | 
			
		||||
        return BOOST_CURRENT_FUNCTION;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if defined(__SUNPRO_CC)
 | 
			
		||||
// see #4199, the Sun Studio compiler gets confused about static initialization 
 | 
			
		||||
// constructor arguments. But an assignment works just fine. 
 | 
			
		||||
template<class T> sp_typeinfo sp_typeid_< T >::ti_ = sp_typeid_< T >::name();
 | 
			
		||||
#else
 | 
			
		||||
template<class T> sp_typeinfo sp_typeid_< T >::ti_(sp_typeid_< T >::name());
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
template<class T> struct sp_typeid_< T & >: sp_typeid_< T >
 | 
			
		||||
{
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
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>::ti_)
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
@@ -6,68 +6,13 @@
 | 
			
		||||
//
 | 
			
		||||
//  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)
 | 
			
		||||
//  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
 | 
			
		||||
//
 | 
			
		||||
//  http://www.boost.org/libs/smart_ptr/enable_shared_from_this.html
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/weak_ptr.hpp>
 | 
			
		||||
#include <boost/shared_ptr.hpp>
 | 
			
		||||
#include <boost/assert.hpp>
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
template<class T> class enable_shared_from_this
 | 
			
		||||
{
 | 
			
		||||
protected:
 | 
			
		||||
 | 
			
		||||
    enable_shared_from_this()
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    enable_shared_from_this(enable_shared_from_this const &)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    enable_shared_from_this & operator=(enable_shared_from_this const &)
 | 
			
		||||
    {
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~enable_shared_from_this()
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    shared_ptr<T> shared_from_this()
 | 
			
		||||
    {
 | 
			
		||||
        shared_ptr<T> p(_internal_weak_this);
 | 
			
		||||
        BOOST_ASSERT(p.get() == this);
 | 
			
		||||
        return p;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    shared_ptr<T const> shared_from_this() const
 | 
			
		||||
    {
 | 
			
		||||
        shared_ptr<T const> p(_internal_weak_this);
 | 
			
		||||
        BOOST_ASSERT(p.get() == this);
 | 
			
		||||
        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;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
#include <boost/smart_ptr/enable_shared_from_this.hpp>
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,11 @@
 | 
			
		||||
#ifndef GET_POINTER_DWA20021219_HPP
 | 
			
		||||
# define GET_POINTER_DWA20021219_HPP
 | 
			
		||||
 | 
			
		||||
# include <memory>
 | 
			
		||||
// 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
 | 
			
		||||
 | 
			
		||||
namespace boost { 
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -6,272 +6,13 @@
 | 
			
		||||
//
 | 
			
		||||
//  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)
 | 
			
		||||
//  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/intrusive_ptr.html for documentation.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
 | 
			
		||||
#ifdef BOOST_MSVC  // moved here to work around VC++ compiler crash
 | 
			
		||||
# pragma warning(push)
 | 
			
		||||
# pragma warning(disable:4284) // odd return type for operator->
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <boost/assert.hpp>
 | 
			
		||||
#include <boost/detail/workaround.hpp>
 | 
			
		||||
 | 
			
		||||
#include <functional>           // for std::less
 | 
			
		||||
#include <iosfwd>               // for std::basic_ostream
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  intrusive_ptr
 | 
			
		||||
//
 | 
			
		||||
//  A smart pointer that uses intrusive reference counting.
 | 
			
		||||
//
 | 
			
		||||
//  Relies on unqualified calls to
 | 
			
		||||
//  
 | 
			
		||||
//      void intrusive_ptr_add_ref(T * p);
 | 
			
		||||
//      void intrusive_ptr_release(T * p);
 | 
			
		||||
//
 | 
			
		||||
//          (p != 0)
 | 
			
		||||
//
 | 
			
		||||
//  The object is responsible for destroying itself.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
template<class T> class intrusive_ptr
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    typedef intrusive_ptr this_type;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    typedef T element_type;
 | 
			
		||||
 | 
			
		||||
    intrusive_ptr(): p_(0)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    intrusive_ptr(T * p, bool add_ref = true): p_(p)
 | 
			
		||||
    {
 | 
			
		||||
        if(p_ != 0 && add_ref) intrusive_ptr_add_ref(p_);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES)
 | 
			
		||||
 | 
			
		||||
    template<class U> intrusive_ptr(intrusive_ptr<U> const & rhs): p_(rhs.get())
 | 
			
		||||
    {
 | 
			
		||||
        if(p_ != 0) intrusive_ptr_add_ref(p_);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    intrusive_ptr(intrusive_ptr const & rhs): p_(rhs.p_)
 | 
			
		||||
    {
 | 
			
		||||
        if(p_ != 0) intrusive_ptr_add_ref(p_);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~intrusive_ptr()
 | 
			
		||||
    {
 | 
			
		||||
        if(p_ != 0) intrusive_ptr_release(p_);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES)
 | 
			
		||||
 | 
			
		||||
    template<class U> intrusive_ptr & operator=(intrusive_ptr<U> const & rhs)
 | 
			
		||||
    {
 | 
			
		||||
        this_type(rhs).swap(*this);
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    intrusive_ptr & operator=(intrusive_ptr const & rhs)
 | 
			
		||||
    {
 | 
			
		||||
        this_type(rhs).swap(*this);
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    intrusive_ptr & operator=(T * rhs)
 | 
			
		||||
    {
 | 
			
		||||
        this_type(rhs).swap(*this);
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    T * get() const
 | 
			
		||||
    {
 | 
			
		||||
        return p_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    T & operator*() const
 | 
			
		||||
    {
 | 
			
		||||
        return *p_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    T * operator->() const
 | 
			
		||||
    {
 | 
			
		||||
        return p_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x530)
 | 
			
		||||
 | 
			
		||||
    operator bool () const
 | 
			
		||||
    {
 | 
			
		||||
        return p_ != 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#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 p_ == 0? 0: &this_type::get;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#else 
 | 
			
		||||
 | 
			
		||||
    typedef T * this_type::*unspecified_bool_type;
 | 
			
		||||
 | 
			
		||||
    operator unspecified_bool_type () const
 | 
			
		||||
    {
 | 
			
		||||
        return p_ == 0? 0: &this_type::p_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    // operator! is a Borland-specific workaround
 | 
			
		||||
    bool operator! () const
 | 
			
		||||
    {
 | 
			
		||||
        return p_ == 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void swap(intrusive_ptr & rhs)
 | 
			
		||||
    {
 | 
			
		||||
        T * tmp = p_;
 | 
			
		||||
        p_ = rhs.p_;
 | 
			
		||||
        rhs.p_ = tmp;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    T * p_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<class T, class U> inline bool operator==(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b)
 | 
			
		||||
{
 | 
			
		||||
    return a.get() == b.get();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T, class U> inline bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b)
 | 
			
		||||
{
 | 
			
		||||
    return a.get() != b.get();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T, class U> inline bool operator==(intrusive_ptr<T> const & a, U * b)
 | 
			
		||||
{
 | 
			
		||||
    return a.get() == b;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T, class U> inline bool operator!=(intrusive_ptr<T> const & a, U * b)
 | 
			
		||||
{
 | 
			
		||||
    return a.get() != b;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T, class U> inline bool operator==(T * a, intrusive_ptr<U> const & b)
 | 
			
		||||
{
 | 
			
		||||
    return a == b.get();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T, class U> inline bool operator!=(T * a, intrusive_ptr<U> const & b)
 | 
			
		||||
{
 | 
			
		||||
    return a != b.get();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if __GNUC__ == 2 && __GNUC_MINOR__ <= 96
 | 
			
		||||
 | 
			
		||||
// Resolve the ambiguity between our op!= and the one in rel_ops
 | 
			
		||||
 | 
			
		||||
template<class T> inline bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b)
 | 
			
		||||
{
 | 
			
		||||
    return a.get() != b.get();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
template<class T> inline bool operator<(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b)
 | 
			
		||||
{
 | 
			
		||||
    return std::less<T *>()(a.get(), b.get());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> void swap(intrusive_ptr<T> & lhs, intrusive_ptr<T> & rhs)
 | 
			
		||||
{
 | 
			
		||||
    lhs.swap(rhs);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// mem_fn support
 | 
			
		||||
 | 
			
		||||
template<class T> T * get_pointer(intrusive_ptr<T> const & p)
 | 
			
		||||
{
 | 
			
		||||
    return p.get();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T, class U> intrusive_ptr<T> static_pointer_cast(intrusive_ptr<U> const & p)
 | 
			
		||||
{
 | 
			
		||||
    return static_cast<T *>(p.get());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T, class U> intrusive_ptr<T> const_pointer_cast(intrusive_ptr<U> const & p)
 | 
			
		||||
{
 | 
			
		||||
    return const_cast<T *>(p.get());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T, class U> intrusive_ptr<T> dynamic_pointer_cast(intrusive_ptr<U> const & p)
 | 
			
		||||
{
 | 
			
		||||
    return dynamic_cast<T *>(p.get());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// operator<<
 | 
			
		||||
 | 
			
		||||
#if defined(__GNUC__) &&  (__GNUC__ < 3)
 | 
			
		||||
 | 
			
		||||
template<class Y> std::ostream & operator<< (std::ostream & os, intrusive_ptr<Y> const & p)
 | 
			
		||||
{
 | 
			
		||||
    os << p.get();
 | 
			
		||||
    return os;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#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)
 | 
			
		||||
// 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)
 | 
			
		||||
# else
 | 
			
		||||
template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, intrusive_ptr<Y> const & p)
 | 
			
		||||
# endif 
 | 
			
		||||
{
 | 
			
		||||
    os << p.get();
 | 
			
		||||
    return os;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // _STLP_NO_IOSTREAMS
 | 
			
		||||
 | 
			
		||||
#endif // __GNUC__ < 3
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#ifdef BOOST_MSVC
 | 
			
		||||
# pragma warning(pop)
 | 
			
		||||
#endif    
 | 
			
		||||
#include <boost/smart_ptr/intrusive_ptr.hpp>
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_INTRUSIVE_PTR_HPP_INCLUDED
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										17
									
								
								include/boost/make_shared.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								include/boost/make_shared.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
			
		||||
#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/smart_ptr/make_shared.hpp>
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_MAKE_SHARED_HPP_INCLUDED
 | 
			
		||||
							
								
								
									
										53
									
								
								include/boost/memory_order.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								include/boost/memory_order.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,53 @@
 | 
			
		||||
#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, 2009 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 values are chosen so that code that needs to insert
 | 
			
		||||
// a trailing fence for acquire semantics can use a single
 | 
			
		||||
// test such as:
 | 
			
		||||
//
 | 
			
		||||
// if( mo & memory_order_acquire ) { ...fence... }
 | 
			
		||||
//
 | 
			
		||||
// For leading fences one can use:
 | 
			
		||||
//
 | 
			
		||||
// if( mo & memory_order_release ) { ...fence... }
 | 
			
		||||
//
 | 
			
		||||
// Architectures such as Alpha that need a fence on consume
 | 
			
		||||
// can use:
 | 
			
		||||
//
 | 
			
		||||
// if( mo & ( memory_order_acquire | memory_order_consume ) ) { ...fence... }
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
    memory_order_consume = 8
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_MEMORY_ORDER_HPP_INCLUDED
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
//////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
//
 | 
			
		||||
// (C) Copyright Ion Gazta<EFBFBD>aga 2005. 
 | 
			
		||||
// (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)
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@
 | 
			
		||||
//
 | 
			
		||||
//  pointer_to_other.hpp
 | 
			
		||||
//
 | 
			
		||||
//  (C) Copyright Ion Gazta<EFBFBD>aga 2005.
 | 
			
		||||
//  (C) Copyright Ion Gaztanaga 2005.
 | 
			
		||||
//  Copyright (c) 2005 Peter Dimov.
 | 
			
		||||
//
 | 
			
		||||
//  Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
 
 | 
			
		||||
@@ -11,125 +11,6 @@
 | 
			
		||||
//  http://www.boost.org/libs/smart_ptr/scoped_array.htm
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/assert.hpp>
 | 
			
		||||
#include <boost/checked_delete.hpp>
 | 
			
		||||
#include <boost/config.hpp>   // in case ptrdiff_t not in std
 | 
			
		||||
 | 
			
		||||
#include <boost/detail/workaround.hpp>
 | 
			
		||||
 | 
			
		||||
#include <cstddef>            // for std::ptrdiff_t
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
// Debug hooks
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
 | 
			
		||||
void sp_array_constructor_hook(void * p);
 | 
			
		||||
void sp_array_destructor_hook(void * p);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//  scoped_array extends scoped_ptr to arrays. Deletion of the array pointed to
 | 
			
		||||
//  is guaranteed, either on destruction of the scoped_array or via an explicit
 | 
			
		||||
//  reset(). Use shared_array or std::vector if your needs are more complex.
 | 
			
		||||
 | 
			
		||||
template<class T> class scoped_array // noncopyable
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    T * ptr;
 | 
			
		||||
 | 
			
		||||
    scoped_array(scoped_array const &);
 | 
			
		||||
    scoped_array & operator=(scoped_array const &);
 | 
			
		||||
 | 
			
		||||
    typedef scoped_array<T> this_type;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    typedef T element_type;
 | 
			
		||||
 | 
			
		||||
    explicit scoped_array(T * p = 0) : ptr(p) // never throws
 | 
			
		||||
    {
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
        boost::sp_array_constructor_hook(ptr);
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~scoped_array() // never throws
 | 
			
		||||
    {
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
        boost::sp_array_destructor_hook(ptr);
 | 
			
		||||
#endif
 | 
			
		||||
        boost::checked_array_delete(ptr);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void reset(T * p = 0) // never throws
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ASSERT(p == 0 || p != ptr); // catch self-reset errors
 | 
			
		||||
        this_type(p).swap(*this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    T & operator[](std::ptrdiff_t i) const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ASSERT(ptr != 0);
 | 
			
		||||
        BOOST_ASSERT(i >= 0);
 | 
			
		||||
        return ptr[i];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    T * get() const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return ptr;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // implicit conversion to "bool"
 | 
			
		||||
 | 
			
		||||
#if defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x530)
 | 
			
		||||
 | 
			
		||||
    operator bool () const
 | 
			
		||||
    {
 | 
			
		||||
        return ptr != 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#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 ptr == 0? 0: &this_type::get;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#else 
 | 
			
		||||
 | 
			
		||||
    typedef T * this_type::*unspecified_bool_type;
 | 
			
		||||
 | 
			
		||||
    operator unspecified_bool_type() const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return ptr == 0? 0: &this_type::ptr;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    bool operator! () const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return ptr == 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void swap(scoped_array & b) // never throws
 | 
			
		||||
    {
 | 
			
		||||
        T * tmp = b.ptr;
 | 
			
		||||
        b.ptr = ptr;
 | 
			
		||||
        ptr = tmp;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<class T> inline void swap(scoped_array<T> & a, scoped_array<T> & b) // never throws
 | 
			
		||||
{
 | 
			
		||||
    a.swap(b);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
#include <boost/smart_ptr/scoped_array.hpp>
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SCOPED_ARRAY_HPP_INCLUDED
 | 
			
		||||
 
 | 
			
		||||
@@ -11,147 +11,6 @@
 | 
			
		||||
//  http://www.boost.org/libs/smart_ptr/scoped_ptr.htm
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/assert.hpp>
 | 
			
		||||
#include <boost/checked_delete.hpp>
 | 
			
		||||
#include <boost/detail/workaround.hpp>
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_NO_AUTO_PTR
 | 
			
		||||
# include <memory>          // for std::auto_ptr
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
// Debug hooks
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
 | 
			
		||||
void sp_scalar_constructor_hook(void * p);
 | 
			
		||||
void sp_scalar_destructor_hook(void * p);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//  scoped_ptr mimics a built-in pointer except that it guarantees deletion
 | 
			
		||||
//  of the object pointed to, either on destruction of the scoped_ptr or via
 | 
			
		||||
//  an explicit reset(). scoped_ptr is a simple solution for simple needs;
 | 
			
		||||
//  use shared_ptr or std::auto_ptr if your needs are more complex.
 | 
			
		||||
 | 
			
		||||
template<class T> class scoped_ptr // noncopyable
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    T * ptr;
 | 
			
		||||
 | 
			
		||||
    scoped_ptr(scoped_ptr const &);
 | 
			
		||||
    scoped_ptr & operator=(scoped_ptr const &);
 | 
			
		||||
 | 
			
		||||
    typedef scoped_ptr<T> this_type;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    typedef T element_type;
 | 
			
		||||
 | 
			
		||||
    explicit scoped_ptr(T * p = 0): ptr(p) // never throws
 | 
			
		||||
    {
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
        boost::sp_scalar_constructor_hook(ptr);
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_NO_AUTO_PTR
 | 
			
		||||
 | 
			
		||||
    explicit scoped_ptr(std::auto_ptr<T> p): ptr(p.release()) // never throws
 | 
			
		||||
    {
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
        boost::sp_scalar_constructor_hook(ptr);
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    ~scoped_ptr() // never throws
 | 
			
		||||
    {
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
        boost::sp_scalar_destructor_hook(ptr);
 | 
			
		||||
#endif
 | 
			
		||||
        boost::checked_delete(ptr);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void reset(T * p = 0) // never throws
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ASSERT(p == 0 || p != ptr); // catch self-reset errors
 | 
			
		||||
        this_type(p).swap(*this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    T & operator*() const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ASSERT(ptr != 0);
 | 
			
		||||
        return *ptr;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    T * operator->() const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ASSERT(ptr != 0);
 | 
			
		||||
        return ptr;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    T * get() const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return ptr;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // implicit conversion to "bool"
 | 
			
		||||
 | 
			
		||||
#if defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x530)
 | 
			
		||||
 | 
			
		||||
    operator bool () const
 | 
			
		||||
    {
 | 
			
		||||
        return ptr != 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#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 ptr == 0? 0: &this_type::get;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#else 
 | 
			
		||||
    typedef T * this_type::*unspecified_bool_type;
 | 
			
		||||
 | 
			
		||||
    operator unspecified_bool_type() const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return ptr == 0? 0: &this_type::ptr;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    bool operator! () const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return ptr == 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void swap(scoped_ptr & b) // never throws
 | 
			
		||||
    {
 | 
			
		||||
        T * tmp = b.ptr;
 | 
			
		||||
        b.ptr = ptr;
 | 
			
		||||
        ptr = tmp;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<class T> inline void swap(scoped_ptr<T> & a, scoped_ptr<T> & b) // never throws
 | 
			
		||||
{
 | 
			
		||||
    a.swap(b);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// get_pointer(p) is a generic way to say p.get()
 | 
			
		||||
 | 
			
		||||
template<class T> inline T * get_pointer(scoped_ptr<T> const & p)
 | 
			
		||||
{
 | 
			
		||||
    return p.get();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
#include <boost/smart_ptr/scoped_ptr.hpp>
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_SCOPED_PTR_HPP_INCLUDED
 | 
			
		||||
 
 | 
			
		||||
@@ -14,164 +14,6 @@
 | 
			
		||||
//  See http://www.boost.org/libs/smart_ptr/shared_array.htm for documentation.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>   // for broken compiler workarounds
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
 | 
			
		||||
#include <boost/detail/shared_array_nmt.hpp>
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
#include <memory>             // TR1 cyclic inclusion fix
 | 
			
		||||
 | 
			
		||||
#include <boost/assert.hpp>
 | 
			
		||||
#include <boost/checked_delete.hpp>
 | 
			
		||||
 | 
			
		||||
#include <boost/detail/shared_count.hpp>
 | 
			
		||||
#include <boost/detail/workaround.hpp>
 | 
			
		||||
 | 
			
		||||
#include <cstddef>            // for std::ptrdiff_t
 | 
			
		||||
#include <algorithm>          // for std::swap
 | 
			
		||||
#include <functional>         // for std::less
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  shared_array
 | 
			
		||||
//
 | 
			
		||||
//  shared_array extends shared_ptr to arrays.
 | 
			
		||||
//  The array pointed to is deleted when the last shared_array pointing to it
 | 
			
		||||
//  is destroyed or reset.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
template<class T> class shared_array
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    // Borland 5.5.1 specific workarounds
 | 
			
		||||
    typedef checked_array_deleter<T> deleter;
 | 
			
		||||
    typedef shared_array<T> this_type;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    typedef T element_type;
 | 
			
		||||
 | 
			
		||||
    explicit shared_array(T * p = 0): px(p), pn(p, deleter())
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //
 | 
			
		||||
    // Requirements: D's copy constructor must not throw
 | 
			
		||||
    //
 | 
			
		||||
    // shared_array will release p by calling d(p)
 | 
			
		||||
    //
 | 
			
		||||
 | 
			
		||||
    template<class D> shared_array(T * p, D d): px(p), pn(p, d)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
//  generated copy constructor, assignment, destructor are fine
 | 
			
		||||
 | 
			
		||||
    void reset(T * p = 0)
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ASSERT(p == 0 || p != px);
 | 
			
		||||
        this_type(p).swap(*this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template <class D> void reset(T * p, D d)
 | 
			
		||||
    {
 | 
			
		||||
        this_type(p, d).swap(*this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    T & operator[] (std::ptrdiff_t i) const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ASSERT(px != 0);
 | 
			
		||||
        BOOST_ASSERT(i >= 0);
 | 
			
		||||
        return px[i];
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    T * get() const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // implicit conversion to "bool"
 | 
			
		||||
 | 
			
		||||
#if defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x530)
 | 
			
		||||
 | 
			
		||||
    operator bool () const
 | 
			
		||||
    {
 | 
			
		||||
        return px != 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#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 
 | 
			
		||||
 | 
			
		||||
    typedef T * this_type::*unspecified_bool_type;
 | 
			
		||||
 | 
			
		||||
    operator unspecified_bool_type() const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return px == 0? 0: &this_type::px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    bool operator! () const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return px == 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool unique() const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return pn.unique();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long use_count() const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return pn.use_count();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void swap(shared_array<T> & other) // never throws
 | 
			
		||||
    {
 | 
			
		||||
        std::swap(px, other.px);
 | 
			
		||||
        pn.swap(other.pn);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    T * px;                     // contained pointer
 | 
			
		||||
    detail::shared_count pn;    // reference counter
 | 
			
		||||
 | 
			
		||||
};  // shared_array
 | 
			
		||||
 | 
			
		||||
template<class T> inline bool operator==(shared_array<T> const & a, shared_array<T> const & b) // never throws
 | 
			
		||||
{
 | 
			
		||||
    return a.get() == b.get();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> inline bool operator!=(shared_array<T> const & a, shared_array<T> const & b) // never throws
 | 
			
		||||
{
 | 
			
		||||
    return a.get() != b.get();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> inline bool operator<(shared_array<T> const & a, shared_array<T> const & b) // never throws
 | 
			
		||||
{
 | 
			
		||||
    return std::less<T*>()(a.get(), b.get());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> void swap(shared_array<T> & a, shared_array<T> & b) // never throws
 | 
			
		||||
{
 | 
			
		||||
    a.swap(b);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
 | 
			
		||||
#include <boost/smart_ptr/shared_array.hpp>
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SHARED_ARRAY_HPP_INCLUDED
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,7 @@
 | 
			
		||||
//  shared_ptr.hpp
 | 
			
		||||
//
 | 
			
		||||
//  (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
 | 
			
		||||
//  Copyright (c) 2001-2006 Peter Dimov
 | 
			
		||||
//  Copyright (c) 2001-2008 Peter Dimov
 | 
			
		||||
//
 | 
			
		||||
//  Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
//  accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
@@ -14,545 +14,6 @@
 | 
			
		||||
//  See http://www.boost.org/libs/smart_ptr/shared_ptr.htm for documentation.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>   // for broken compiler workarounds
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
 | 
			
		||||
#include <boost/detail/shared_ptr_nmt.hpp>
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
#include <memory>               // for 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 <algorithm>            // for std::swap
 | 
			
		||||
#include <functional>           // for std::less
 | 
			
		||||
#include <typeinfo>             // for std::bad_cast
 | 
			
		||||
#include <iosfwd>               // for std::basic_ostream
 | 
			
		||||
 | 
			
		||||
#ifdef BOOST_MSVC  // moved here to work around VC++ compiler crash
 | 
			
		||||
# pragma warning(push)
 | 
			
		||||
# pragma warning(disable:4284) // odd return type for operator->
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
template<class T> class weak_ptr;
 | 
			
		||||
template<class T> class enable_shared_from_this;
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
struct static_cast_tag {};
 | 
			
		||||
struct const_cast_tag {};
 | 
			
		||||
struct dynamic_cast_tag {};
 | 
			
		||||
struct polymorphic_cast_tag {};
 | 
			
		||||
 | 
			
		||||
template<class T> struct shared_ptr_traits
 | 
			
		||||
{
 | 
			
		||||
    typedef T & reference;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<> struct shared_ptr_traits<void>
 | 
			
		||||
{
 | 
			
		||||
    typedef void reference;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if !defined(BOOST_NO_CV_VOID_SPECIALIZATIONS)
 | 
			
		||||
 | 
			
		||||
template<> struct shared_ptr_traits<void const>
 | 
			
		||||
{
 | 
			
		||||
    typedef void reference;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<> struct shared_ptr_traits<void volatile>
 | 
			
		||||
{
 | 
			
		||||
    typedef void reference;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<> struct shared_ptr_traits<void const volatile>
 | 
			
		||||
{
 | 
			
		||||
    typedef void reference;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// 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 )
 | 
			
		||||
{
 | 
			
		||||
    if(pe != 0) pe->_internal_weak_this._internal_assign(const_cast<Y*>(px), pn);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  shared_ptr
 | 
			
		||||
//
 | 
			
		||||
//  An enhanced relative of scoped_ptr with reference counted copy semantics.
 | 
			
		||||
//  The object pointed to is deleted when the last shared_ptr pointing to it
 | 
			
		||||
//  is destroyed or reset.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
template<class T> class shared_ptr
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    // Borland 5.5.1 specific workaround
 | 
			
		||||
    typedef shared_ptr<T> this_type;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    typedef T element_type;
 | 
			
		||||
    typedef T value_type;
 | 
			
		||||
    typedef T * pointer;
 | 
			
		||||
    typedef typename boost::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
 | 
			
		||||
    {
 | 
			
		||||
        boost::detail::sp_enable_shared_from_this( pn, p, p );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //
 | 
			
		||||
    // Requirements: D's copy constructor must not throw
 | 
			
		||||
    //
 | 
			
		||||
    // shared_ptr will release p by calling d(p)
 | 
			
		||||
    //
 | 
			
		||||
 | 
			
		||||
    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 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
//  generated copy constructor, assignment, destructor are fine...
 | 
			
		||||
 | 
			
		||||
//  except that Borland C++ has a bug, and g++ with -Wsynth warns
 | 
			
		||||
#if defined(__BORLANDC__) || defined(__GNUC__)
 | 
			
		||||
 | 
			
		||||
    shared_ptr & operator=(shared_ptr const & r) // never throws
 | 
			
		||||
    {
 | 
			
		||||
        px = r.px;
 | 
			
		||||
        pn = r.pn; // shared_count::op= doesn't throw
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
    explicit shared_ptr(weak_ptr<Y> const & r): pn(r.pn) // may throw
 | 
			
		||||
    {
 | 
			
		||||
        // it is now safe to copy r.px, as pn(r.pn) did not throw
 | 
			
		||||
        px = r.px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
    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)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
    shared_ptr(shared_ptr<Y> const & r, boost::detail::dynamic_cast_tag): px(dynamic_cast<element_type *>(r.px)), pn(r.pn)
 | 
			
		||||
    {
 | 
			
		||||
        if(px == 0) // need to allocate new counter -- the cast failed
 | 
			
		||||
        {
 | 
			
		||||
            pn = boost::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)
 | 
			
		||||
    {
 | 
			
		||||
        if(px == 0)
 | 
			
		||||
        {
 | 
			
		||||
            boost::throw_exception(std::bad_cast());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_NO_AUTO_PTR
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
    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 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
 | 
			
		||||
 | 
			
		||||
    template<class Ap>
 | 
			
		||||
    explicit shared_ptr( Ap r, typename boost::detail::sp_enable_if_auto_ptr<Ap, int>::type = 0 ): px( r.get() ), pn()
 | 
			
		||||
    {
 | 
			
		||||
        typename Ap::element_type * tmp = r.get();
 | 
			
		||||
        pn = boost::detail::shared_count( r );
 | 
			
		||||
        boost::detail::sp_enable_shared_from_this( pn, tmp, tmp );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif // BOOST_NO_SFINAE, BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 | 
			
		||||
 | 
			
		||||
#endif // BOOST_NO_AUTO_PTR
 | 
			
		||||
 | 
			
		||||
#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300)
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
    shared_ptr & operator=(shared_ptr<Y> const & r) // never throws
 | 
			
		||||
    {
 | 
			
		||||
        px = r.px;
 | 
			
		||||
        pn = r.pn; // shared_count::op= doesn't throw
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_NO_AUTO_PTR
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
    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
 | 
			
		||||
 | 
			
		||||
    void reset() // never throws in 1.30+
 | 
			
		||||
    {
 | 
			
		||||
        this_type().swap(*this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class Y> void reset(Y * p) // Y must be complete
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ASSERT(p == 0 || p != px); // catch self-reset errors
 | 
			
		||||
        this_type(p).swap(*this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    reference operator* () const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ASSERT(px != 0);
 | 
			
		||||
        return *px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    T * operator-> () const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ASSERT(px != 0);
 | 
			
		||||
        return px;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    T * get() const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // implicit conversion to "bool"
 | 
			
		||||
 | 
			
		||||
#if defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x580)
 | 
			
		||||
 | 
			
		||||
    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) )
 | 
			
		||||
 | 
			
		||||
    typedef T * (this_type::*unspecified_bool_type)() const;
 | 
			
		||||
    
 | 
			
		||||
    operator unspecified_bool_type() const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return px == 0? 0: &this_type::get;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#else 
 | 
			
		||||
 | 
			
		||||
    typedef T * this_type::*unspecified_bool_type;
 | 
			
		||||
 | 
			
		||||
    operator unspecified_bool_type() const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return px == 0? 0: &this_type::px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    // operator! is redundant, but some compilers need it
 | 
			
		||||
 | 
			
		||||
    bool operator! () const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return px == 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool unique() const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return pn.unique();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long use_count() const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return pn.use_count();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void swap(shared_ptr<T> & other) // never throws
 | 
			
		||||
    {
 | 
			
		||||
        std::swap(px, other.px);
 | 
			
		||||
        pn.swap(other.pn);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class Y> bool _internal_less(shared_ptr<Y> const & rhs) const
 | 
			
		||||
    {
 | 
			
		||||
        return pn < rhs.pn;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void * _internal_get_deleter(std::type_info const & ti) const
 | 
			
		||||
    {
 | 
			
		||||
        return pn.get_deleter(ti);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
// Tasteless as this may seem, making all members public allows member templates
 | 
			
		||||
// to work in the absence of member template friends. (Matthew Langston)
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    template<class Y> friend class shared_ptr;
 | 
			
		||||
    template<class Y> friend class weak_ptr;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    T * px;                     // contained pointer
 | 
			
		||||
    boost::detail::shared_count pn;    // reference counter
 | 
			
		||||
 | 
			
		||||
};  // shared_ptr
 | 
			
		||||
 | 
			
		||||
template<class T, class U> inline bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b)
 | 
			
		||||
{
 | 
			
		||||
    return a.get() == b.get();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T, class U> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b)
 | 
			
		||||
{
 | 
			
		||||
    return a.get() != b.get();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if __GNUC__ == 2 && __GNUC_MINOR__ <= 96
 | 
			
		||||
 | 
			
		||||
// Resolve the ambiguity between our op!= and the one in rel_ops
 | 
			
		||||
 | 
			
		||||
template<class T> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<T> const & b)
 | 
			
		||||
{
 | 
			
		||||
    return a.get() != b.get();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
template<class T, class U> inline bool operator<(shared_ptr<T> const & a, shared_ptr<U> const & b)
 | 
			
		||||
{
 | 
			
		||||
    return a._internal_less(b);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> inline void swap(shared_ptr<T> & a, shared_ptr<T> & b)
 | 
			
		||||
{
 | 
			
		||||
    a.swap(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());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T, class U> shared_ptr<T> shared_polymorphic_downcast(shared_ptr<U> const & r)
 | 
			
		||||
{
 | 
			
		||||
    BOOST_ASSERT(dynamic_cast<T *>(r.get()) == r.get());
 | 
			
		||||
    return shared_static_cast<T>(r);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// get_pointer() enables boost::mem_fn to recognize shared_ptr
 | 
			
		||||
 | 
			
		||||
template<class T> inline T * get_pointer(shared_ptr<T> const & p)
 | 
			
		||||
{
 | 
			
		||||
    return p.get();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// operator<<
 | 
			
		||||
 | 
			
		||||
#if defined(__GNUC__) &&  (__GNUC__ < 3)
 | 
			
		||||
 | 
			
		||||
template<class Y> std::ostream & operator<< (std::ostream & os, shared_ptr<Y> const & p)
 | 
			
		||||
{
 | 
			
		||||
    os << p.get();
 | 
			
		||||
    return os;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#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)
 | 
			
		||||
// 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 
 | 
			
		||||
{
 | 
			
		||||
    os << p.get();
 | 
			
		||||
    return os;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // _STLP_NO_IOSTREAMS
 | 
			
		||||
 | 
			
		||||
#endif // __GNUC__ < 3
 | 
			
		||||
 | 
			
		||||
// get_deleter (experimental)
 | 
			
		||||
 | 
			
		||||
#if ( defined(__GNUC__) && BOOST_WORKAROUND(__GNUC__, < 3) ) || \
 | 
			
		||||
    ( defined(__EDG_VERSION__) && BOOST_WORKAROUND(__EDG_VERSION__, <= 238) ) || \
 | 
			
		||||
    ( defined(__HP_aCC) && BOOST_WORKAROUND(__HP_aCC, <= 33500) )
 | 
			
		||||
 | 
			
		||||
// 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
 | 
			
		||||
 | 
			
		||||
template<class D, class T> D * get_deleter(shared_ptr<T> const & p)
 | 
			
		||||
{
 | 
			
		||||
    void const * q = p._internal_get_deleter(typeid(D));
 | 
			
		||||
    return const_cast<D *>(static_cast<D const *>(q));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
template<class D, class T> D * get_deleter(shared_ptr<T> const & p)
 | 
			
		||||
{
 | 
			
		||||
    return static_cast<D *>(p._internal_get_deleter(typeid(D)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#ifdef BOOST_MSVC
 | 
			
		||||
# pragma warning(pop)
 | 
			
		||||
#endif    
 | 
			
		||||
 | 
			
		||||
#endif  // #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
 | 
			
		||||
#include <boost/smart_ptr/shared_ptr.hpp>
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SHARED_PTR_HPP_INCLUDED
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,6 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  smart_ptr.hpp
 | 
			
		||||
//
 | 
			
		||||
@@ -22,4 +25,7 @@
 | 
			
		||||
# include <boost/weak_ptr.hpp>
 | 
			
		||||
# include <boost/intrusive_ptr.hpp>
 | 
			
		||||
# include <boost/enable_shared_from_this.hpp>
 | 
			
		||||
# include <boost/make_shared.hpp>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_SMART_PTR_HPP_INCLUDED
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
#ifndef BOOST_BAD_WEAK_PTR_HPP_INCLUDED
 | 
			
		||||
#define BOOST_BAD_WEAK_PTR_HPP_INCLUDED
 | 
			
		||||
#ifndef BOOST_SMART_PTR_BAD_WEAK_PTR_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_BAD_WEAK_PTR_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
@@ -8,7 +8,7 @@
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  detail/bad_weak_ptr.hpp
 | 
			
		||||
//  boost/smart_ptr/bad_weak_ptr.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
 | 
			
		||||
//
 | 
			
		||||
@@ -56,4 +56,4 @@ public:
 | 
			
		||||
# pragma warn .8026     // Functions with excep. spec. are not expanded inline
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_BAD_WEAK_PTR_HPP_INCLUDED
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_BAD_WEAK_PTR_HPP_INCLUDED
 | 
			
		||||
							
								
								
									
										119
									
								
								include/boost/smart_ptr/detail/atomic_count.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								include/boost/smart_ptr/detail/atomic_count.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,119 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  boost/detail/atomic_count.hpp - thread/SMP safe reference counter
 | 
			
		||||
//
 | 
			
		||||
//  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)
 | 
			
		||||
//
 | 
			
		||||
//  typedef <implementation-defined> boost::detail::atomic_count;
 | 
			
		||||
//
 | 
			
		||||
//  atomic_count a(n);
 | 
			
		||||
//
 | 
			
		||||
//    (n is convertible to long)
 | 
			
		||||
//
 | 
			
		||||
//    Effects: Constructs an atomic_count with an initial value of n
 | 
			
		||||
//
 | 
			
		||||
//  a;
 | 
			
		||||
//
 | 
			
		||||
//    Returns: (long) the current value of a
 | 
			
		||||
//
 | 
			
		||||
//  ++a;
 | 
			
		||||
//
 | 
			
		||||
//    Effects: Atomically increments the value of a
 | 
			
		||||
//    Returns: (long) the new value of a
 | 
			
		||||
//
 | 
			
		||||
//  --a;
 | 
			
		||||
//
 | 
			
		||||
//    Effects: Atomically decrements the value of a
 | 
			
		||||
//    Returns: (long) the new value of a
 | 
			
		||||
//
 | 
			
		||||
//    Important note: when --a returns zero, it must act as a
 | 
			
		||||
//      read memory barrier (RMB); i.e. the calling thread must
 | 
			
		||||
//      have a synchronized view of the memory
 | 
			
		||||
//
 | 
			
		||||
//    On Intel IA-32 (x86) memory is always synchronized, so this
 | 
			
		||||
//      is not a problem.
 | 
			
		||||
//
 | 
			
		||||
//    On many architectures the atomic instructions already act as
 | 
			
		||||
//      a memory barrier.
 | 
			
		||||
//
 | 
			
		||||
//    This property is necessary for proper reference counting, since
 | 
			
		||||
//      a thread can update the contents of a shared object, then
 | 
			
		||||
//      release its reference, and another thread may immediately
 | 
			
		||||
//      release the last reference causing object destruction.
 | 
			
		||||
//
 | 
			
		||||
//    The destructor needs to have a synchronized view of the
 | 
			
		||||
//      object to perform proper cleanup.
 | 
			
		||||
//
 | 
			
		||||
//    Original example by Alexander Terekhov:
 | 
			
		||||
//
 | 
			
		||||
//    Given:
 | 
			
		||||
//
 | 
			
		||||
//    - a mutable shared object OBJ;
 | 
			
		||||
//    - two threads THREAD1 and THREAD2 each holding 
 | 
			
		||||
//      a private smart_ptr object pointing to that OBJ.
 | 
			
		||||
//
 | 
			
		||||
//    t1: THREAD1 updates OBJ (thread-safe via some synchronization)
 | 
			
		||||
//      and a few cycles later (after "unlock") destroys smart_ptr;
 | 
			
		||||
//
 | 
			
		||||
//    t2: THREAD2 destroys smart_ptr WITHOUT doing any synchronization 
 | 
			
		||||
//      with respect to shared mutable object OBJ; OBJ destructors
 | 
			
		||||
//      are called driven by smart_ptr interface...
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#include <boost/smart_ptr/detail/sp_has_sync.hpp>
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_HAS_THREADS
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
typedef long atomic_count;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#elif defined(BOOST_AC_USE_PTHREADS)
 | 
			
		||||
#  include <boost/smart_ptr/detail/atomic_count_pthreads.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) )
 | 
			
		||||
#  include <boost/smart_ptr/detail/atomic_count_gcc_x86.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
 | 
			
		||||
#  include <boost/smart_ptr/detail/atomic_count_win32.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( BOOST_SP_HAS_SYNC )
 | 
			
		||||
#  include <boost/smart_ptr/detail/atomic_count_sync.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined(__GLIBCPP__) || defined(__GLIBCXX__)
 | 
			
		||||
#  include <boost/smart_ptr/detail/atomic_count_gcc.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined(BOOST_HAS_PTHREADS)
 | 
			
		||||
 | 
			
		||||
#  define BOOST_AC_USE_PTHREADS
 | 
			
		||||
#  include <boost/smart_ptr/detail/atomic_count_pthreads.hpp>
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
// Use #define BOOST_DISABLE_THREADS to avoid the error
 | 
			
		||||
#error Unrecognized threading platform
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_HPP_INCLUDED
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_ATOMIC_COUNT_GCC_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_ATOMIC_COUNT_GCC_HPP_INCLUDED
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  boost/detail/atomic_count_gcc.hpp
 | 
			
		||||
@@ -17,9 +17,9 @@
 | 
			
		||||
//  http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 2))
 | 
			
		||||
# include <ext/atomicity.h>
 | 
			
		||||
#else
 | 
			
		||||
#if __GNUC__ * 100 + __GNUC_MINOR__ >= 402
 | 
			
		||||
# include <ext/atomicity.h> 
 | 
			
		||||
#else 
 | 
			
		||||
# include <bits/atomicity.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@@ -40,21 +40,21 @@ class atomic_count
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    explicit atomic_count(long v) : value_(v) {}
 | 
			
		||||
    explicit atomic_count( long v ) : value_( v ) {}
 | 
			
		||||
 | 
			
		||||
    void operator++()
 | 
			
		||||
    long operator++()
 | 
			
		||||
    {
 | 
			
		||||
        __atomic_add(&value_, 1);
 | 
			
		||||
        return __exchange_and_add( &value_, +1 ) + 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long operator--()
 | 
			
		||||
    {
 | 
			
		||||
        return __exchange_and_add(&value_, -1) - 1;
 | 
			
		||||
        return __exchange_and_add( &value_, -1 ) - 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    operator long() const
 | 
			
		||||
    {
 | 
			
		||||
        return __exchange_and_add(&value_, 0);
 | 
			
		||||
        return __exchange_and_add( &value_, 0 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
@@ -69,4 +69,4 @@ private:
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_DETAIL_ATOMIC_COUNT_GCC_HPP_INCLUDED
 | 
			
		||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_HPP_INCLUDED
 | 
			
		||||
							
								
								
									
										77
									
								
								include/boost/smart_ptr/detail/atomic_count_gcc_x86.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								include/boost/smart_ptr/detail/atomic_count_gcc_x86.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,77 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_X86_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_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 ) ) {}
 | 
			
		||||
 | 
			
		||||
    long operator++()
 | 
			
		||||
    {
 | 
			
		||||
        return atomic_exchange_and_add( &value_, +1 ) + 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_X86_HPP_INCLUDED
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_ATOMIC_COUNT_PTHREADS_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_ATOMIC_COUNT_PTHREADS_HPP_INCLUDED
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_PTHREADS_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_PTHREADS_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  boost/detail/atomic_count_pthreads.hpp
 | 
			
		||||
@@ -62,10 +62,10 @@ public:
 | 
			
		||||
        pthread_mutex_destroy(&mutex_);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void operator++()
 | 
			
		||||
    long operator++()
 | 
			
		||||
    {
 | 
			
		||||
        scoped_lock lock(mutex_);
 | 
			
		||||
        ++value_;
 | 
			
		||||
        return ++value_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long operator--()
 | 
			
		||||
@@ -93,4 +93,4 @@ private:
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_DETAIL_ATOMIC_COUNT_PTHREADS_HPP_INCLUDED
 | 
			
		||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_PTHREADS_HPP_INCLUDED
 | 
			
		||||
							
								
								
									
										59
									
								
								include/boost/smart_ptr/detail/atomic_count_solaris.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								include/boost/smart_ptr/detail/atomic_count_solaris.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,59 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SOLARIS_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_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_SMART_PTR_DETAIL_ATOMIC_COUNT_SOLARIS_HPP_INCLUDED
 | 
			
		||||
							
								
								
									
										61
									
								
								include/boost/smart_ptr/detail/atomic_count_sync.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								include/boost/smart_ptr/detail/atomic_count_sync.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,61 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SYNC_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_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)
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#if defined( __ia64__ ) && defined( __INTEL_COMPILER )
 | 
			
		||||
# include <ia64intrin.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
class atomic_count
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    explicit atomic_count( long v ) : value_( v ) {}
 | 
			
		||||
 | 
			
		||||
    long operator++()
 | 
			
		||||
    {
 | 
			
		||||
        return __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_SMART_PTR_DETAIL_ATOMIC_COUNT_SYNC_HPP_INCLUDED
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_ATOMIC_COUNT_WIN32_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_ATOMIC_COUNT_WIN32_HPP_INCLUDED
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_WIN32_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_WIN32_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
@@ -60,4 +60,4 @@ private:
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_DETAIL_ATOMIC_COUNT_WIN32_HPP_INCLUDED
 | 
			
		||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_WIN32_HPP_INCLUDED
 | 
			
		||||
							
								
								
									
										42
									
								
								include/boost/smart_ptr/detail/lightweight_mutex.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								include/boost/smart_ptr/detail/lightweight_mutex.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,42 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  boost/detail/lightweight_mutex.hpp - lightweight mutex
 | 
			
		||||
//
 | 
			
		||||
//  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)
 | 
			
		||||
//
 | 
			
		||||
//  typedef <unspecified> boost::detail::lightweight_mutex;
 | 
			
		||||
//
 | 
			
		||||
//  boost::detail::lightweight_mutex is a header-only implementation of
 | 
			
		||||
//  a subset of the Mutex concept requirements:
 | 
			
		||||
//
 | 
			
		||||
//  http://www.boost.org/doc/html/threads/concepts.html#threads.concepts.Mutex
 | 
			
		||||
//
 | 
			
		||||
//  It maps to a CRITICAL_SECTION on Windows or a pthread_mutex on POSIX.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
 | 
			
		||||
#if !defined(BOOST_HAS_THREADS)
 | 
			
		||||
#  include <boost/smart_ptr/detail/lwm_nop.hpp>
 | 
			
		||||
#elif defined(BOOST_HAS_PTHREADS)
 | 
			
		||||
#  include <boost/smart_ptr/detail/lwm_pthreads.hpp>
 | 
			
		||||
#elif defined(BOOST_HAS_WINTHREADS) || defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
 | 
			
		||||
#  include <boost/smart_ptr/detail/lwm_win32_cs.hpp>
 | 
			
		||||
#else
 | 
			
		||||
// Use #define BOOST_DISABLE_THREADS to avoid the error
 | 
			
		||||
#  error Unrecognized threading platform
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_LWM_NOP_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_LWM_NOP_HPP_INCLUDED
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_LWM_NOP_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_LWM_NOP_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
@@ -34,4 +34,4 @@ public:
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_DETAIL_LWM_NOP_HPP_INCLUDED
 | 
			
		||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_LWM_NOP_HPP_INCLUDED
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_LWM_PTHREADS_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_LWM_PTHREADS_HPP_INCLUDED
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_LWM_PTHREADS_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_LWM_PTHREADS_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
@@ -17,6 +17,7 @@
 | 
			
		||||
// http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/assert.hpp>
 | 
			
		||||
#include <pthread.h>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
@@ -42,15 +43,15 @@ public:
 | 
			
		||||
// HPUX 10.20 / DCE has a nonstandard pthread_mutex_init
 | 
			
		||||
 | 
			
		||||
#if defined(__hpux) && defined(_DECTHREADS_)
 | 
			
		||||
        pthread_mutex_init(&m_, pthread_mutexattr_default);
 | 
			
		||||
        BOOST_VERIFY( pthread_mutex_init( &m_, pthread_mutexattr_default ) == 0 );
 | 
			
		||||
#else
 | 
			
		||||
        pthread_mutex_init(&m_, 0);
 | 
			
		||||
        BOOST_VERIFY( pthread_mutex_init( &m_, 0 ) == 0 );
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~lightweight_mutex()
 | 
			
		||||
    {
 | 
			
		||||
        pthread_mutex_destroy(&m_);
 | 
			
		||||
        BOOST_VERIFY( pthread_mutex_destroy( &m_ ) == 0 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    class scoped_lock;
 | 
			
		||||
@@ -69,12 +70,12 @@ public:
 | 
			
		||||
 | 
			
		||||
        scoped_lock(lightweight_mutex & m): m_(m.m_)
 | 
			
		||||
        {
 | 
			
		||||
            pthread_mutex_lock(&m_);
 | 
			
		||||
            BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ~scoped_lock()
 | 
			
		||||
        {
 | 
			
		||||
            pthread_mutex_unlock(&m_);
 | 
			
		||||
            BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
@@ -83,4 +84,4 @@ public:
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_DETAIL_LWM_PTHREADS_HPP_INCLUDED
 | 
			
		||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_LWM_PTHREADS_HPP_INCLUDED
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_LWM_WIN32_CS_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_LWM_WIN32_CS_HPP_INCLUDED
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_LWM_WIN32_CS_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_LWM_WIN32_CS_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
@@ -29,7 +29,7 @@ namespace detail
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_USE_WINDOWS_H
 | 
			
		||||
 | 
			
		||||
struct CRITICAL_SECTION
 | 
			
		||||
struct critical_section
 | 
			
		||||
{
 | 
			
		||||
    struct critical_section_debug * DebugInfo;
 | 
			
		||||
    long LockCount;
 | 
			
		||||
@@ -43,10 +43,14 @@ 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 *);
 | 
			
		||||
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;
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_USE_WINDOWS_H
 | 
			
		||||
 | 
			
		||||
@@ -54,7 +58,7 @@ class lightweight_mutex
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    CRITICAL_SECTION cs_;
 | 
			
		||||
    critical_section cs_;
 | 
			
		||||
 | 
			
		||||
    lightweight_mutex(lightweight_mutex const &);
 | 
			
		||||
    lightweight_mutex & operator=(lightweight_mutex const &);
 | 
			
		||||
@@ -101,4 +105,4 @@ public:
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_DETAIL_LWM_WIN32_CS_HPP_INCLUDED
 | 
			
		||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_LWM_WIN32_CS_HPP_INCLUDED
 | 
			
		||||
							
								
								
									
										56
									
								
								include/boost/smart_ptr/detail/operator_bool.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								include/boost/smart_ptr/detail/operator_bool.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,56 @@
 | 
			
		||||
//  This header intentionally has no include guards.
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2001-2009 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
 | 
			
		||||
 | 
			
		||||
#if ( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, < 0x570) ) || defined(__CINT__)
 | 
			
		||||
 | 
			
		||||
    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) )
 | 
			
		||||
 | 
			
		||||
    typedef T * (this_type::*unspecified_bool_type)() const;
 | 
			
		||||
 | 
			
		||||
    operator unspecified_bool_type() const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return px == 0? 0: &this_type::get;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
    typedef T * this_type::*unspecified_bool_type;
 | 
			
		||||
 | 
			
		||||
    operator unspecified_bool_type() const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return px == 0? 0: &this_type::px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    // operator! is redundant, but some compilers need it
 | 
			
		||||
    bool operator! () const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return px == 0;
 | 
			
		||||
    }
 | 
			
		||||
							
								
								
									
										199
									
								
								include/boost/smart_ptr/detail/quick_allocator.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										199
									
								
								include/boost/smart_ptr/detail/quick_allocator.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,199 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  detail/quick_allocator.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2003 David Abrahams
 | 
			
		||||
//  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)
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
 | 
			
		||||
#include <boost/smart_ptr/detail/lightweight_mutex.hpp>
 | 
			
		||||
#include <boost/type_traits/type_with_alignment.hpp>
 | 
			
		||||
#include <boost/type_traits/alignment_of.hpp>
 | 
			
		||||
 | 
			
		||||
#include <new>              // ::operator new, ::operator delete
 | 
			
		||||
#include <cstddef>          // std::size_t
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
template<unsigned size, unsigned align_> union freeblock
 | 
			
		||||
{
 | 
			
		||||
    typedef typename boost::type_with_alignment<align_>::type aligner_type;
 | 
			
		||||
    aligner_type aligner;
 | 
			
		||||
    char bytes[size];
 | 
			
		||||
    freeblock * next;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<unsigned size, unsigned align_> struct allocator_impl
 | 
			
		||||
{
 | 
			
		||||
    typedef freeblock<size, align_> block;
 | 
			
		||||
 | 
			
		||||
    // It may seem odd to use such small pages.
 | 
			
		||||
    //
 | 
			
		||||
    // However, on a typical Windows implementation that uses
 | 
			
		||||
    // the OS allocator, "normal size" pages interact with the
 | 
			
		||||
    // "ordinary" operator new, slowing it down dramatically.
 | 
			
		||||
    //
 | 
			
		||||
    // 512 byte pages are handled by the small object allocator,
 | 
			
		||||
    // and don't interfere with ::new.
 | 
			
		||||
    //
 | 
			
		||||
    // The other alternative is to use much bigger pages (1M.)
 | 
			
		||||
    //
 | 
			
		||||
    // It is surprisingly easy to hit pathological behavior by
 | 
			
		||||
    // varying the page size. g++ 2.96 on Red Hat Linux 7.2,
 | 
			
		||||
    // for example, passionately dislikes 496. 512 seems OK.
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_QA_PAGE_SIZE)
 | 
			
		||||
 | 
			
		||||
    enum { items_per_page = BOOST_QA_PAGE_SIZE / size };
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
    enum { items_per_page = 512 / size }; // 1048560 / size
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef BOOST_HAS_THREADS
 | 
			
		||||
 | 
			
		||||
    static lightweight_mutex & mutex()
 | 
			
		||||
    {
 | 
			
		||||
        static freeblock< sizeof( lightweight_mutex ), boost::alignment_of< lightweight_mutex >::value > fbm;
 | 
			
		||||
        static lightweight_mutex * pm = new( &fbm ) lightweight_mutex;
 | 
			
		||||
        return *pm;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static lightweight_mutex * mutex_init;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    static block * free;
 | 
			
		||||
    static block * page;
 | 
			
		||||
    static unsigned last;
 | 
			
		||||
 | 
			
		||||
    static inline void * alloc()
 | 
			
		||||
    {
 | 
			
		||||
#ifdef BOOST_HAS_THREADS
 | 
			
		||||
        lightweight_mutex::scoped_lock lock( mutex() );
 | 
			
		||||
#endif
 | 
			
		||||
        if(block * x = free)
 | 
			
		||||
        {
 | 
			
		||||
            free = x->next;
 | 
			
		||||
            return x;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            if(last == items_per_page)
 | 
			
		||||
            {
 | 
			
		||||
                // "Listen to me carefully: there is no memory leak"
 | 
			
		||||
                // -- Scott Meyers, Eff C++ 2nd Ed Item 10
 | 
			
		||||
                page = ::new block[items_per_page];
 | 
			
		||||
                last = 0;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return &page[last++];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static inline void * alloc(std::size_t n)
 | 
			
		||||
    {
 | 
			
		||||
        if(n != size) // class-specific new called for a derived object
 | 
			
		||||
        {
 | 
			
		||||
            return ::operator new(n);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
#ifdef BOOST_HAS_THREADS
 | 
			
		||||
            lightweight_mutex::scoped_lock lock( mutex() );
 | 
			
		||||
#endif
 | 
			
		||||
            if(block * x = free)
 | 
			
		||||
            {
 | 
			
		||||
                free = x->next;
 | 
			
		||||
                return x;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                if(last == items_per_page)
 | 
			
		||||
                {
 | 
			
		||||
                    page = ::new block[items_per_page];
 | 
			
		||||
                    last = 0;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                return &page[last++];
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static inline void dealloc(void * pv)
 | 
			
		||||
    {
 | 
			
		||||
        if(pv != 0) // 18.4.1.1/13
 | 
			
		||||
        {
 | 
			
		||||
#ifdef BOOST_HAS_THREADS
 | 
			
		||||
            lightweight_mutex::scoped_lock lock( mutex() );
 | 
			
		||||
#endif
 | 
			
		||||
            block * pb = static_cast<block *>(pv);
 | 
			
		||||
            pb->next = free;
 | 
			
		||||
            free = pb;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static inline void dealloc(void * pv, std::size_t n)
 | 
			
		||||
    {
 | 
			
		||||
        if(n != size) // class-specific delete called for a derived object
 | 
			
		||||
        {
 | 
			
		||||
            ::operator delete(pv);
 | 
			
		||||
        }
 | 
			
		||||
        else if(pv != 0) // 18.4.1.1/13
 | 
			
		||||
        {
 | 
			
		||||
#ifdef BOOST_HAS_THREADS
 | 
			
		||||
            lightweight_mutex::scoped_lock lock( mutex() );
 | 
			
		||||
#endif
 | 
			
		||||
            block * pb = static_cast<block *>(pv);
 | 
			
		||||
            pb->next = free;
 | 
			
		||||
            free = pb;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#ifdef BOOST_HAS_THREADS
 | 
			
		||||
 | 
			
		||||
template<unsigned size, unsigned align_>
 | 
			
		||||
  lightweight_mutex * allocator_impl<size, align_>::mutex_init = &allocator_impl<size, align_>::mutex();
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
template<unsigned size, unsigned align_>
 | 
			
		||||
  freeblock<size, align_> * allocator_impl<size, align_>::free = 0;
 | 
			
		||||
 | 
			
		||||
template<unsigned size, unsigned align_>
 | 
			
		||||
  freeblock<size, align_> * allocator_impl<size, align_>::page = 0;
 | 
			
		||||
 | 
			
		||||
template<unsigned size, unsigned align_>
 | 
			
		||||
  unsigned allocator_impl<size, align_>::last = allocator_impl<size, align_>::items_per_page;
 | 
			
		||||
 | 
			
		||||
template<class T>
 | 
			
		||||
struct quick_allocator: public allocator_impl< sizeof(T), boost::alignment_of<T>::value >
 | 
			
		||||
{
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_SHARED_ARRAY_NMT_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_SHARED_ARRAY_NMT_HPP_INCLUDED
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SHARED_ARRAY_NMT_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_SHARED_ARRAY_NMT_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  detail/shared_array_nmt.hpp - shared_array.hpp without member templates
 | 
			
		||||
@@ -17,7 +17,7 @@
 | 
			
		||||
#include <boost/assert.hpp>
 | 
			
		||||
#include <boost/checked_delete.hpp>
 | 
			
		||||
#include <boost/throw_exception.hpp>
 | 
			
		||||
#include <boost/detail/atomic_count.hpp>
 | 
			
		||||
#include <boost/smart_ptr/detail/atomic_count.hpp>
 | 
			
		||||
 | 
			
		||||
#include <cstddef>          // for std::ptrdiff_t
 | 
			
		||||
#include <algorithm>        // for std::swap
 | 
			
		||||
@@ -148,4 +148,4 @@ template<class T> void swap(shared_array<T> & a, shared_array<T> & b)
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_DETAIL_SHARED_ARRAY_NMT_HPP_INCLUDED
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SHARED_ARRAY_NMT_HPP_INCLUDED
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_SHARED_COUNT_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_SHARED_COUNT_HPP_INCLUDED
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
@@ -25,14 +25,17 @@
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#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>
 | 
			
		||||
 | 
			
		||||
#include <memory>           // std::auto_ptr
 | 
			
		||||
#include <boost/smart_ptr/bad_weak_ptr.hpp>
 | 
			
		||||
#include <boost/smart_ptr/detail/sp_counted_base.hpp>
 | 
			
		||||
#include <boost/smart_ptr/detail/sp_counted_impl.hpp>
 | 
			
		||||
#include <boost/detail/workaround.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 <functional>       // std::less
 | 
			
		||||
#include <new>              // std::bad_alloc
 | 
			
		||||
#include <typeinfo>         // std::type_info in get_deleter
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
@@ -47,6 +50,12 @@ int const   weak_count_id = 0x298C38A4;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
struct sp_nothrow_tag {};
 | 
			
		||||
 | 
			
		||||
template< class D > struct sp_inplace_tag
 | 
			
		||||
{
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class weak_count;
 | 
			
		||||
 | 
			
		||||
class shared_count
 | 
			
		||||
@@ -100,11 +109,18 @@ public:
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class P, class D> shared_count(P p, D d): pi_(0)
 | 
			
		||||
#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
 | 
			
		||||
@@ -130,6 +146,40 @@ public:
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
 | 
			
		||||
 | 
			
		||||
    template< class P, class D > shared_count( P p, sp_inplace_tag<D> ): pi_( 0 )
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
        , id_(shared_count_id)
 | 
			
		||||
#endif
 | 
			
		||||
    {
 | 
			
		||||
#ifndef BOOST_NO_EXCEPTIONS
 | 
			
		||||
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            pi_ = new sp_counted_impl_pd< P, D >( p );
 | 
			
		||||
        }
 | 
			
		||||
        catch( ... )
 | 
			
		||||
        {
 | 
			
		||||
            D()( p ); // delete p
 | 
			
		||||
            throw;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
        pi_ = new sp_counted_impl_pd< P, D >( p );
 | 
			
		||||
 | 
			
		||||
        if( pi_ == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            D()( p ); // delete p
 | 
			
		||||
            boost::throw_exception( std::bad_alloc() );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_NO_EXCEPTIONS
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif // !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
 | 
			
		||||
 | 
			
		||||
    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)
 | 
			
		||||
@@ -176,6 +226,56 @@ public:
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
 | 
			
		||||
 | 
			
		||||
    template< class P, class D, class A > shared_count( P p, sp_inplace_tag< 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, 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, a );
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            D()( p );
 | 
			
		||||
            boost::throw_exception( std::bad_alloc() );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_NO_EXCEPTIONS
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif // !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_NO_AUTO_PTR
 | 
			
		||||
 | 
			
		||||
    // auto_ptr<Y> is special cased to provide the strong guarantee
 | 
			
		||||
@@ -216,7 +316,20 @@ public:
 | 
			
		||||
        if( pi_ != 0 ) pi_->add_ref_copy();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if defined( BOOST_HAS_RVALUE_REFS )
 | 
			
		||||
 | 
			
		||||
    shared_count(shared_count && r): pi_(r.pi_) // nothrow
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
        , id_(shared_count_id)
 | 
			
		||||
#endif
 | 
			
		||||
    {
 | 
			
		||||
        r.pi_ = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    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
 | 
			
		||||
    {
 | 
			
		||||
@@ -249,6 +362,11 @@ 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_;
 | 
			
		||||
@@ -259,7 +377,7 @@ public:
 | 
			
		||||
        return std::less<sp_counted_base *>()( a.pi_, b.pi_ );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void * get_deleter(std::type_info const & ti) const
 | 
			
		||||
    void * get_deleter( sp_typeinfo const & ti ) const
 | 
			
		||||
    {
 | 
			
		||||
        return pi_? pi_->get_deleter( ti ): 0;
 | 
			
		||||
    }
 | 
			
		||||
@@ -289,7 +407,7 @@ public:
 | 
			
		||||
 | 
			
		||||
    weak_count(shared_count const & r): pi_(r.pi_) // nothrow
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
        , id_(shared_count_id)
 | 
			
		||||
        , id_(weak_count_id)
 | 
			
		||||
#endif
 | 
			
		||||
    {
 | 
			
		||||
        if(pi_ != 0) pi_->weak_add_ref();
 | 
			
		||||
@@ -297,12 +415,26 @@ public:
 | 
			
		||||
 | 
			
		||||
    weak_count(weak_count const & r): pi_(r.pi_) // nothrow
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
        , id_(shared_count_id)
 | 
			
		||||
        , id_(weak_count_id)
 | 
			
		||||
#endif
 | 
			
		||||
    {
 | 
			
		||||
        if(pi_ != 0) pi_->weak_add_ref();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
// Move support
 | 
			
		||||
 | 
			
		||||
#if defined( BOOST_HAS_RVALUE_REFS )
 | 
			
		||||
 | 
			
		||||
    weak_count(weak_count && r): pi_(r.pi_) // nothrow
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
        , id_(weak_count_id)
 | 
			
		||||
#endif
 | 
			
		||||
    {
 | 
			
		||||
        r.pi_ = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    ~weak_count() // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        if(pi_ != 0) pi_->weak_release();
 | 
			
		||||
@@ -314,9 +446,13 @@ public:
 | 
			
		||||
    weak_count & operator= (shared_count const & r) // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        sp_counted_base * tmp = r.pi_;
 | 
			
		||||
        if(tmp != 0) tmp->weak_add_ref();
 | 
			
		||||
        if(pi_ != 0) pi_->weak_release();
 | 
			
		||||
        pi_ = tmp;
 | 
			
		||||
 | 
			
		||||
        if( tmp != pi_ )
 | 
			
		||||
        {
 | 
			
		||||
            if(tmp != 0) tmp->weak_add_ref();
 | 
			
		||||
            if(pi_ != 0) pi_->weak_release();
 | 
			
		||||
            pi_ = tmp;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
@@ -324,9 +460,13 @@ public:
 | 
			
		||||
    weak_count & operator= (weak_count const & r) // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        sp_counted_base * tmp = r.pi_;
 | 
			
		||||
        if(tmp != 0) tmp->weak_add_ref();
 | 
			
		||||
        if(pi_ != 0) pi_->weak_release();
 | 
			
		||||
        pi_ = tmp;
 | 
			
		||||
 | 
			
		||||
        if( tmp != pi_ )
 | 
			
		||||
        {
 | 
			
		||||
            if(tmp != 0) tmp->weak_add_ref();
 | 
			
		||||
            if(pi_ != 0) pi_->weak_release();
 | 
			
		||||
            pi_ = tmp;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
@@ -343,6 +483,11 @@ public:
 | 
			
		||||
        return pi_ != 0? pi_->use_count(): 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool empty() const // nothrow
 | 
			
		||||
    {
 | 
			
		||||
        return pi_ == 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    friend inline bool operator==(weak_count const & a, weak_count const & b)
 | 
			
		||||
    {
 | 
			
		||||
        return a.pi_ == b.pi_;
 | 
			
		||||
@@ -365,6 +510,17 @@ inline shared_count::shared_count( weak_count const & r ): pi_( r.pi_ )
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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() )
 | 
			
		||||
    {
 | 
			
		||||
        pi_ = 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
@@ -373,4 +529,4 @@ inline shared_count::shared_count( weak_count const & r ): pi_( r.pi_ )
 | 
			
		||||
# pragma warn .8027     // Functions containing try are not expanded inline
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_DETAIL_SHARED_COUNT_HPP_INCLUDED
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_SHARED_PTR_NMT_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_SHARED_PTR_NMT_HPP_INCLUDED
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SHARED_PTR_NMT_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_SHARED_PTR_NMT_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  detail/shared_ptr_nmt.hpp - shared_ptr.hpp without member templates
 | 
			
		||||
@@ -17,7 +17,7 @@
 | 
			
		||||
#include <boost/assert.hpp>
 | 
			
		||||
#include <boost/checked_delete.hpp>
 | 
			
		||||
#include <boost/throw_exception.hpp>
 | 
			
		||||
#include <boost/detail/atomic_count.hpp>
 | 
			
		||||
#include <boost/smart_ptr/detail/atomic_count.hpp>
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_NO_AUTO_PTR
 | 
			
		||||
# include <memory>          // for std::auto_ptr
 | 
			
		||||
@@ -179,4 +179,4 @@ template<class T> inline T * get_pointer(shared_ptr<T> const & p)
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_DETAIL_SHARED_PTR_NMT_HPP_INCLUDED
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SHARED_PTR_NMT_HPP_INCLUDED
 | 
			
		||||
							
								
								
									
										76
									
								
								include/boost/smart_ptr/detail/sp_convertible.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								include/boost/smart_ptr/detail/sp_convertible.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,76 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_CONVERTIBLE_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_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__ < 0x630 )
 | 
			
		||||
# 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)( static_cast<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_SMART_PTR_DETAIL_SP_CONVERTIBLE_HPP_INCLUDED
 | 
			
		||||
							
								
								
									
										73
									
								
								include/boost/smart_ptr/detail/sp_counted_base.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								include/boost/smart_ptr/detail/sp_counted_base.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,73 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_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>
 | 
			
		||||
#include <boost/smart_ptr/detail/sp_has_sync.hpp>
 | 
			
		||||
 | 
			
		||||
#if defined( BOOST_SP_DISABLE_THREADS )
 | 
			
		||||
# include <boost/smart_ptr/detail/sp_counted_base_nt.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( BOOST_SP_USE_SPINLOCK )
 | 
			
		||||
# include <boost/smart_ptr/detail/sp_counted_base_spin.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( BOOST_SP_USE_PTHREADS )
 | 
			
		||||
# include <boost/smart_ptr/detail/sp_counted_base_pt.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( BOOST_DISABLE_THREADS ) && !defined( BOOST_SP_ENABLE_THREADS ) && !defined( BOOST_DISABLE_WIN32 )
 | 
			
		||||
# include <boost/smart_ptr/detail/sp_counted_base_nt.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) )
 | 
			
		||||
# include <boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( __GNUC__ ) && defined( __ia64__ ) && !defined( __INTEL_COMPILER )
 | 
			
		||||
# include <boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined(__HP_aCC) && defined(__ia64)
 | 
			
		||||
# include <boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( __MWERKS__ ) && defined( __POWERPC__ )
 | 
			
		||||
# include <boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( __GNUC__ ) && ( defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc ) )
 | 
			
		||||
# include <boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( __GNUC__ ) && ( defined( __mips__ ) || defined( _mips ) )
 | 
			
		||||
# include <boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( BOOST_SP_HAS_SYNC )
 | 
			
		||||
# include <boost/smart_ptr/detail/sp_counted_base_sync.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined(__GNUC__) && ( defined( __sparcv9 ) || ( defined( __sparcv8 ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 402 ) ) )
 | 
			
		||||
# include <boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined(__CYGWIN__)
 | 
			
		||||
# include <boost/smart_ptr/detail/sp_counted_base_w32.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( _AIX )
 | 
			
		||||
# include <boost/smart_ptr/detail/sp_counted_base_aix.hpp>
 | 
			
		||||
 | 
			
		||||
#elif !defined( BOOST_HAS_THREADS )
 | 
			
		||||
# include <boost/smart_ptr/detail/sp_counted_base_nt.hpp>
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
# include <boost/smart_ptr/detail/sp_counted_base_spin.hpp>
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED
 | 
			
		||||
							
								
								
									
										150
									
								
								include/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										150
									
								
								include/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,150 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_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_SMART_PTR_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED
 | 
			
		||||
							
								
								
									
										142
									
								
								include/boost/smart_ptr/detail/sp_counted_base_aix.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										142
									
								
								include/boost/smart_ptr/detail/sp_counted_base_aix.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,142 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_AIX_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_AIX_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  detail/sp_counted_base_aix.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 <builtins.h>
 | 
			
		||||
#include <sys/atomic_op.h>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
inline void atomic_increment( int32_t* pw )
 | 
			
		||||
{
 | 
			
		||||
    // ++*pw;
 | 
			
		||||
 | 
			
		||||
    fetch_and_add( pw, 1 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline int32_t atomic_decrement( int32_t * pw )
 | 
			
		||||
{
 | 
			
		||||
    // return --*pw;
 | 
			
		||||
 | 
			
		||||
    int32_t originalValue;
 | 
			
		||||
 | 
			
		||||
    __lwsync();
 | 
			
		||||
    originalValue = fetch_and_add( pw, -1 );
 | 
			
		||||
    __isync();
 | 
			
		||||
 | 
			
		||||
    return (originalValue - 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline int32_t atomic_conditional_increment( int32_t * pw )
 | 
			
		||||
{
 | 
			
		||||
    // if( *pw != 0 ) ++*pw;
 | 
			
		||||
    // return *pw;
 | 
			
		||||
 | 
			
		||||
    int32_t tmp = fetch_and_add( pw, 0 );
 | 
			
		||||
    for( ;; )
 | 
			
		||||
    {
 | 
			
		||||
        if( tmp == 0 ) return 0;
 | 
			
		||||
        if( compare_and_swap( pw, &tmp, tmp + 1 ) ) return (tmp + 1);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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_ ) == 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 fetch_and_add( const_cast<int32_t*>(&use_count_), 0 );
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_AIX_HPP_INCLUDED
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
@@ -24,7 +24,7 @@
 | 
			
		||||
//  formulation
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <typeinfo>
 | 
			
		||||
#include <boost/detail/sp_typeinfo.hpp>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
@@ -123,7 +123,7 @@ public:
 | 
			
		||||
        delete this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void * get_deleter( std::type_info const & ti ) = 0;
 | 
			
		||||
    virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
 | 
			
		||||
 | 
			
		||||
    void add_ref_copy()
 | 
			
		||||
    {
 | 
			
		||||
@@ -167,4 +167,4 @@ public:
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_CW_X86_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_SP_COUNTED_BASE_CW_X86_HPP_INCLUDED
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_X86_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_X86_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
@@ -25,7 +25,7 @@
 | 
			
		||||
//  formulation
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <typeinfo>
 | 
			
		||||
#include <boost/detail/sp_typeinfo.hpp>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
@@ -111,7 +111,7 @@ public:
 | 
			
		||||
        delete this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void * get_deleter( std::type_info const & ti ) = 0;
 | 
			
		||||
    virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
 | 
			
		||||
 | 
			
		||||
    void add_ref_copy()
 | 
			
		||||
    {
 | 
			
		||||
@@ -155,4 +155,4 @@ public:
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_X86_HPP_INCLUDED
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  detail/sp_counted_base_gcc_ia64.hpp - g++ on IA64
 | 
			
		||||
@@ -16,7 +16,7 @@
 | 
			
		||||
//  Lock-free algorithm by Alexander Terekhov
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <typeinfo>
 | 
			
		||||
#include <boost/detail/sp_typeinfo.hpp>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
@@ -110,7 +110,7 @@ public:
 | 
			
		||||
        delete this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void * get_deleter( std::type_info const & ti ) = 0;
 | 
			
		||||
    virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
 | 
			
		||||
 | 
			
		||||
    void add_ref_copy()
 | 
			
		||||
    {
 | 
			
		||||
@@ -154,4 +154,4 @@ public:
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED
 | 
			
		||||
							
								
								
									
										181
									
								
								include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										181
									
								
								include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,181 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_MIPS_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_SP_COUNTED_BASE_GCC_MIPS_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  detail/sp_counted_base_gcc_mips.hpp - g++ on MIPS
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2009, Spirent Communications, Inc.
 | 
			
		||||
//
 | 
			
		||||
//  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;
 | 
			
		||||
 | 
			
		||||
    __asm__ __volatile__
 | 
			
		||||
    (
 | 
			
		||||
        "0:\n\t"
 | 
			
		||||
        ".set push\n\t"
 | 
			
		||||
        ".set mips2\n\t"
 | 
			
		||||
        "ll %0, %1\n\t"
 | 
			
		||||
        "addiu %0, 1\n\t"
 | 
			
		||||
        "sc %0, %1\n\t"
 | 
			
		||||
        ".set pop\n\t"
 | 
			
		||||
        "beqz %0, 0b":
 | 
			
		||||
        "=&r"( tmp ), "=m"( *pw ):
 | 
			
		||||
        "m"( *pw )
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline int atomic_decrement( int * pw )
 | 
			
		||||
{
 | 
			
		||||
    // return --*pw;
 | 
			
		||||
 | 
			
		||||
    int rv, tmp;
 | 
			
		||||
 | 
			
		||||
    __asm__ __volatile__
 | 
			
		||||
    (
 | 
			
		||||
        "0:\n\t"
 | 
			
		||||
        ".set push\n\t"
 | 
			
		||||
        ".set mips2\n\t"
 | 
			
		||||
        "ll %1, %2\n\t"
 | 
			
		||||
        "addiu %0, %1, -1\n\t"
 | 
			
		||||
        "sc %0, %2\n\t"
 | 
			
		||||
        ".set pop\n\t"
 | 
			
		||||
        "beqz %0, 0b\n\t"
 | 
			
		||||
        "addiu %0, %1, -1":
 | 
			
		||||
        "=&r"( rv ), "=&r"( tmp ), "=m"( *pw ):
 | 
			
		||||
        "m"( *pw ):
 | 
			
		||||
        "memory"
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    return rv;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline int atomic_conditional_increment( int * pw )
 | 
			
		||||
{
 | 
			
		||||
    // if( *pw != 0 ) ++*pw;
 | 
			
		||||
    // return *pw;
 | 
			
		||||
 | 
			
		||||
    int rv, tmp;
 | 
			
		||||
 | 
			
		||||
    __asm__ __volatile__
 | 
			
		||||
    (
 | 
			
		||||
        "0:\n\t"
 | 
			
		||||
        ".set push\n\t"
 | 
			
		||||
        ".set mips2\n\t"
 | 
			
		||||
        "ll %0, %2\n\t"
 | 
			
		||||
        "beqz %0, 1f\n\t"
 | 
			
		||||
        "addiu %1, %0, 1\n\t"
 | 
			
		||||
        "sc %1, %2\n\t"
 | 
			
		||||
        ".set pop\n\t"
 | 
			
		||||
        "beqz %1, 0b\n\t"
 | 
			
		||||
        "addiu %0, %0, 1\n\t"
 | 
			
		||||
        "1:":
 | 
			
		||||
        "=&r"( rv ), "=&r"( tmp ), "=m"( *pw ):
 | 
			
		||||
        "m"( *pw ):
 | 
			
		||||
        "memory"
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    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_MIPS_HPP_INCLUDED
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
@@ -24,7 +24,7 @@
 | 
			
		||||
//  formulation
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <typeinfo>
 | 
			
		||||
#include <boost/detail/sp_typeinfo.hpp>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
@@ -134,7 +134,7 @@ public:
 | 
			
		||||
        delete this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void * get_deleter( std::type_info const & ti ) = 0;
 | 
			
		||||
    virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
 | 
			
		||||
 | 
			
		||||
    void add_ref_copy()
 | 
			
		||||
    {
 | 
			
		||||
@@ -178,4 +178,4 @@ public:
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED
 | 
			
		||||
							
								
								
									
										166
									
								
								include/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										166
									
								
								include/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,166 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_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 [%1], %2, %0"
 | 
			
		||||
                        : "+r" (swap_)
 | 
			
		||||
                        : "r" (dest_), "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_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
@@ -24,7 +24,7 @@
 | 
			
		||||
//  formulation
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <typeinfo>
 | 
			
		||||
#include <boost/detail/sp_typeinfo.hpp>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
@@ -126,7 +126,7 @@ public:
 | 
			
		||||
        delete this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void * get_deleter( std::type_info const & ti ) = 0;
 | 
			
		||||
    virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
 | 
			
		||||
 | 
			
		||||
    void add_ref_copy()
 | 
			
		||||
    {
 | 
			
		||||
@@ -170,4 +170,4 @@ public:
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_NT_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_SP_COUNTED_BASE_NT_HPP_INCLUDED
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_NT_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_NT_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
@@ -18,7 +18,7 @@
 | 
			
		||||
// http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <typeinfo>
 | 
			
		||||
#include <boost/detail/sp_typeinfo.hpp>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
@@ -58,7 +58,7 @@ public:
 | 
			
		||||
        delete this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void * get_deleter( std::type_info const & ti ) = 0;
 | 
			
		||||
    virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
 | 
			
		||||
 | 
			
		||||
    void add_ref_copy()
 | 
			
		||||
    {
 | 
			
		||||
@@ -104,4 +104,4 @@ public:
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_NT_HPP_INCLUDED
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_NT_HPP_INCLUDED
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
@@ -18,7 +18,7 @@
 | 
			
		||||
// http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <typeinfo>
 | 
			
		||||
#include <boost/detail/sp_typeinfo.hpp>
 | 
			
		||||
#include <pthread.h>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
@@ -69,7 +69,7 @@ public:
 | 
			
		||||
        delete this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void * get_deleter( std::type_info const & ti ) = 0;
 | 
			
		||||
    virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
 | 
			
		||||
 | 
			
		||||
    void add_ref_copy()
 | 
			
		||||
    {
 | 
			
		||||
@@ -132,4 +132,4 @@ public:
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED
 | 
			
		||||
							
								
								
									
										113
									
								
								include/boost/smart_ptr/detail/sp_counted_base_solaris.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								include/boost/smart_ptr/detail/sp_counted_base_solaris.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,113 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_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_SMART_PTR_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED
 | 
			
		||||
							
								
								
									
										131
									
								
								include/boost/smart_ptr/detail/sp_counted_base_spin.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										131
									
								
								include/boost/smart_ptr/detail/sp_counted_base_spin.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,131 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_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/smart_ptr/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_SMART_PTR_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED
 | 
			
		||||
							
								
								
									
										155
									
								
								include/boost/smart_ptr/detail/sp_counted_base_sync.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										155
									
								
								include/boost/smart_ptr/detail/sp_counted_base_sync.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,155 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_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_SMART_PTR_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
@@ -26,7 +26,7 @@
 | 
			
		||||
 | 
			
		||||
#include <boost/detail/interlocked.hpp>
 | 
			
		||||
#include <boost/detail/workaround.hpp>
 | 
			
		||||
#include <typeinfo>
 | 
			
		||||
#include <boost/detail/sp_typeinfo.hpp>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
@@ -66,7 +66,7 @@ public:
 | 
			
		||||
        delete this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void * get_deleter( std::type_info const & ti ) = 0;
 | 
			
		||||
    virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
 | 
			
		||||
 | 
			
		||||
    void add_ref_copy()
 | 
			
		||||
    {
 | 
			
		||||
@@ -127,4 +127,4 @@ public:
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
#ifndef BOOST_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
 | 
			
		||||
#define BOOST_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
@@ -25,17 +25,16 @@
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <boost/checked_delete.hpp>
 | 
			
		||||
#include <boost/detail/sp_counted_base.hpp>
 | 
			
		||||
#include <boost/smart_ptr/detail/sp_counted_base.hpp>
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
 | 
			
		||||
#include <boost/detail/quick_allocator.hpp>
 | 
			
		||||
#include <boost/smart_ptr/detail/quick_allocator.hpp>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_SP_USE_STD_ALLOCATOR)
 | 
			
		||||
#include <memory>           // std::allocator
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <typeinfo>         // std::type_info in get_deleter
 | 
			
		||||
#include <cstddef>          // std::size_t
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
@@ -79,7 +78,7 @@ public:
 | 
			
		||||
        boost::checked_delete( px_ );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void * get_deleter( std::type_info const & )
 | 
			
		||||
    virtual void * get_deleter( detail::sp_typeinfo const & )
 | 
			
		||||
    {
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
@@ -136,7 +135,11 @@ public:
 | 
			
		||||
 | 
			
		||||
    // pre: d(p) must not throw
 | 
			
		||||
 | 
			
		||||
    sp_counted_impl_pd( P p, D d ): ptr(p), del(d)
 | 
			
		||||
    sp_counted_impl_pd( P p, D & d ): ptr( p ), del( d )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    sp_counted_impl_pd( P p ): ptr( p ), del()
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -145,9 +148,9 @@ public:
 | 
			
		||||
        del( ptr );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void * get_deleter( std::type_info const & ti )
 | 
			
		||||
    virtual void * get_deleter( detail::sp_typeinfo const & ti )
 | 
			
		||||
    {
 | 
			
		||||
        return ti == typeid(D)? &del: 0;
 | 
			
		||||
        return ti == BOOST_SP_TYPEID(D)? &reinterpret_cast<char&>( del ): 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_SP_USE_STD_ALLOCATOR)
 | 
			
		||||
@@ -196,7 +199,11 @@ public:
 | 
			
		||||
 | 
			
		||||
    // pre: d( p ) must not throw
 | 
			
		||||
 | 
			
		||||
    sp_counted_impl_pda( P p, D d, A a ): p_( p ), d_( d ), a_( a )
 | 
			
		||||
    sp_counted_impl_pda( P p, D & d, A a ): p_( p ), d_( d ), a_( a )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    sp_counted_impl_pda( P p, A a ): p_( p ), d_(), a_( a )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -215,9 +222,9 @@ public:
 | 
			
		||||
        a2.deallocate( this, 1 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void * get_deleter( std::type_info const & ti )
 | 
			
		||||
    virtual void * get_deleter( detail::sp_typeinfo const & ti )
 | 
			
		||||
    {
 | 
			
		||||
        return ti == typeid( D )? &d_: 0;
 | 
			
		||||
        return ti == BOOST_SP_TYPEID( D )? &reinterpret_cast<char&>( d_ ): 0;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -229,4 +236,4 @@ public:
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
 | 
			
		||||
							
								
								
									
										53
									
								
								include/boost/smart_ptr/detail/sp_has_sync.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								include/boost/smart_ptr/detail/sp_has_sync.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,53 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  boost/smart_ptr/detail/sp_has_sync.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2008, 2009 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)
 | 
			
		||||
//
 | 
			
		||||
//  Defines the BOOST_SP_HAS_SYNC macro if the __sync_* intrinsics
 | 
			
		||||
//  are available.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#if defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 ) && !defined( BOOST_SP_NO_SYNC )
 | 
			
		||||
 | 
			
		||||
#define BOOST_SP_HAS_SYNC
 | 
			
		||||
 | 
			
		||||
#if defined( __arm__ )  || defined( __armel__ )
 | 
			
		||||
#undef BOOST_SP_HAS_SYNC
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined( __hppa ) || defined( __hppa__ )
 | 
			
		||||
#undef BOOST_SP_HAS_SYNC
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined( __m68k__ )
 | 
			
		||||
#undef BOOST_SP_HAS_SYNC
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined( __sh__ )
 | 
			
		||||
#undef BOOST_SP_HAS_SYNC
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined( __sparc__ )
 | 
			
		||||
#undef BOOST_SP_HAS_SYNC
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined( __INTEL_COMPILER ) && !defined( __ia64__ ) && ( __INTEL_COMPILER < 1100 )
 | 
			
		||||
#undef BOOST_SP_HAS_SYNC
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // __GNUC__ * 100 + __GNUC_MINOR__ >= 401
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_HPP_INCLUDED
 | 
			
		||||
							
								
								
									
										56
									
								
								include/boost/smart_ptr/detail/spinlock.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								include/boost/smart_ptr/detail/spinlock.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,56 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_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>
 | 
			
		||||
#include <boost/smart_ptr/detail/sp_has_sync.hpp>
 | 
			
		||||
 | 
			
		||||
#if defined( BOOST_SP_USE_PTHREADS )
 | 
			
		||||
#  include <boost/smart_ptr/detail/spinlock_pt.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined(__GNUC__) && defined( __arm__ ) && !defined( __thumb__ )
 | 
			
		||||
#  include <boost/smart_ptr/detail/spinlock_gcc_arm.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined( BOOST_SP_HAS_SYNC )
 | 
			
		||||
#  include <boost/smart_ptr/detail/spinlock_sync.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
 | 
			
		||||
#  include <boost/smart_ptr/detail/spinlock_w32.hpp>
 | 
			
		||||
 | 
			
		||||
#elif defined(BOOST_HAS_PTHREADS)
 | 
			
		||||
#  include <boost/smart_ptr/detail/spinlock_pt.hpp>
 | 
			
		||||
 | 
			
		||||
#elif !defined(BOOST_HAS_THREADS)
 | 
			
		||||
#  include <boost/smart_ptr/detail/spinlock_nt.hpp>
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
#  error Unrecognized threading platform
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_HPP_INCLUDED
 | 
			
		||||
							
								
								
									
										102
									
								
								include/boost/smart_ptr/detail/spinlock_gcc_arm.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								include/boost/smart_ptr/detail/spinlock_gcc_arm.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,102 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2008, 2011 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/smart_ptr/detail/yield_k.hpp>
 | 
			
		||||
 | 
			
		||||
#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
 | 
			
		||||
 | 
			
		||||
# define BOOST_SP_ARM_BARRIER "dmb"
 | 
			
		||||
 | 
			
		||||
#elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__)
 | 
			
		||||
 | 
			
		||||
# define BOOST_SP_ARM_BARRIER "mcr p15, 0, r0, c7, c10, 5"
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
# define BOOST_SP_ARM_BARRIER ""
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
class spinlock
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    int v_;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    bool try_lock()
 | 
			
		||||
    {
 | 
			
		||||
        int r;
 | 
			
		||||
 | 
			
		||||
        __asm__ __volatile__(
 | 
			
		||||
            "swp %0, %1, [%2]\n\t"
 | 
			
		||||
			BOOST_SP_ARM_BARRIER :
 | 
			
		||||
            "=&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__( BOOST_SP_ARM_BARRIER ::: "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}
 | 
			
		||||
 | 
			
		||||
#undef BOOST_SP_ARM_BARRIER
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
 | 
			
		||||
							
								
								
									
										89
									
								
								include/boost/smart_ptr/detail/spinlock_nt.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								include/boost/smart_ptr/detail/spinlock_nt.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,89 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_NT_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_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_SMART_PTR_DETAIL_SPINLOCK_NT_HPP_INCLUDED
 | 
			
		||||
							
								
								
									
										91
									
								
								include/boost/smart_ptr/detail/spinlock_pool.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								include/boost/smart_ptr/detail/spinlock_pool.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,91 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_POOL_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_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/smart_ptr/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 )
 | 
			
		||||
    {
 | 
			
		||||
#if defined(__VMS) && __INITIAL_POINTER_SIZE == 64  
 | 
			
		||||
        std::size_t i = reinterpret_cast< unsigned long long >( pv ) % 41;
 | 
			
		||||
#else  
 | 
			
		||||
        std::size_t i = reinterpret_cast< std::size_t >( pv ) % 41;
 | 
			
		||||
#endif  
 | 
			
		||||
        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_SMART_PTR_DETAIL_SPINLOCK_POOL_HPP_INCLUDED
 | 
			
		||||
							
								
								
									
										79
									
								
								include/boost/smart_ptr/detail/spinlock_pt.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								include/boost/smart_ptr/detail/spinlock_pt.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,79 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_PT_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_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_SMART_PTR_DETAIL_SPINLOCK_PT_HPP_INCLUDED
 | 
			
		||||
							
								
								
									
										87
									
								
								include/boost/smart_ptr/detail/spinlock_sync.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								include/boost/smart_ptr/detail/spinlock_sync.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,87 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_SYNC_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_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/smart_ptr/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_SMART_PTR_DETAIL_SPINLOCK_SYNC_HPP_INCLUDED
 | 
			
		||||
							
								
								
									
										113
									
								
								include/boost/smart_ptr/detail/spinlock_w32.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								include/boost/smart_ptr/detail/spinlock_w32.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,113 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_W32_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_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/smart_ptr/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_SMART_PTR_DETAIL_SPINLOCK_W32_HPP_INCLUDED
 | 
			
		||||
							
								
								
									
										149
									
								
								include/boost/smart_ptr/detail/yield_k.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										149
									
								
								include/boost/smart_ptr/detail/yield_k.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,149 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_DETAIL_YIELD_K_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_DETAIL_YIELD_K_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
// MS compatible compilers support #pragma once
 | 
			
		||||
 | 
			
		||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
			
		||||
# pragma once
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  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 long 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_SMART_PTR_DETAIL_YIELD_K_HPP_INCLUDED
 | 
			
		||||
							
								
								
									
										79
									
								
								include/boost/smart_ptr/enable_shared_from_this.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								include/boost/smart_ptr/enable_shared_from_this.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,79 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  enable_shared_from_this.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright 2002, 2009 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
 | 
			
		||||
//
 | 
			
		||||
//  http://www.boost.org/libs/smart_ptr/enable_shared_from_this.html
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/smart_ptr/weak_ptr.hpp>
 | 
			
		||||
#include <boost/smart_ptr/shared_ptr.hpp>
 | 
			
		||||
#include <boost/assert.hpp>
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
template<class T> class enable_shared_from_this
 | 
			
		||||
{
 | 
			
		||||
protected:
 | 
			
		||||
 | 
			
		||||
    enable_shared_from_this()
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    enable_shared_from_this(enable_shared_from_this const &)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    enable_shared_from_this & operator=(enable_shared_from_this const &)
 | 
			
		||||
    {
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~enable_shared_from_this()
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    shared_ptr<T> shared_from_this()
 | 
			
		||||
    {
 | 
			
		||||
        shared_ptr<T> p( weak_this_ );
 | 
			
		||||
        BOOST_ASSERT( p.get() == this );
 | 
			
		||||
        return p;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    shared_ptr<T const> shared_from_this() const
 | 
			
		||||
    {
 | 
			
		||||
        shared_ptr<T const> p( weak_this_ );
 | 
			
		||||
        BOOST_ASSERT( p.get() == this );
 | 
			
		||||
        return p;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
public: // actually private, but avoids compiler template friendship issues
 | 
			
		||||
 | 
			
		||||
    // Note: invoked automatically by shared_ptr; do not call
 | 
			
		||||
    template<class X, class Y> void _internal_accept_owner( shared_ptr<X> const * ppx, Y * py ) const
 | 
			
		||||
    {
 | 
			
		||||
        if( weak_this_.expired() )
 | 
			
		||||
        {
 | 
			
		||||
            weak_this_ = shared_ptr<T>( *ppx, py );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    mutable weak_ptr<T> weak_this_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED
 | 
			
		||||
							
								
								
									
										132
									
								
								include/boost/smart_ptr/enable_shared_from_this2.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								include/boost/smart_ptr/enable_shared_from_this2.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,132 @@
 | 
			
		||||
#ifndef BOOST_ENABLE_SHARED_FROM_THIS2_HPP_INCLUDED
 | 
			
		||||
#define BOOST_ENABLE_SHARED_FROM_THIS2_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  enable_shared_from_this2.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright 2002, 2009 Peter Dimov
 | 
			
		||||
//  Copyright 2008 Frank Mori Hess
 | 
			
		||||
//
 | 
			
		||||
//  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>
 | 
			
		||||
#include <boost/shared_ptr.hpp>
 | 
			
		||||
#include <boost/assert.hpp>
 | 
			
		||||
#include <boost/detail/workaround.hpp>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
class esft2_deleter_wrapper
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    shared_ptr<void> deleter_;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    esft2_deleter_wrapper()
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template< class T > void set_deleter( shared_ptr<T> const & deleter )
 | 
			
		||||
    {
 | 
			
		||||
        deleter_ = deleter;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template< class T> void operator()( T* )
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ASSERT( deleter_.use_count() <= 1 );
 | 
			
		||||
        deleter_.reset();
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
template< class T > class enable_shared_from_this2
 | 
			
		||||
{
 | 
			
		||||
protected:
 | 
			
		||||
 | 
			
		||||
    enable_shared_from_this2()
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    enable_shared_from_this2( enable_shared_from_this2 const & )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    enable_shared_from_this2 & operator=( enable_shared_from_this2 const & )
 | 
			
		||||
    {
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~enable_shared_from_this2()
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ASSERT( shared_this_.use_count() <= 1 ); // make sure no dangling shared_ptr objects exist
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    mutable weak_ptr<T> weak_this_;
 | 
			
		||||
    mutable shared_ptr<T> shared_this_;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    shared_ptr<T> shared_from_this()
 | 
			
		||||
    {
 | 
			
		||||
        init_weak_once();
 | 
			
		||||
        return shared_ptr<T>( weak_this_ );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    shared_ptr<T const> shared_from_this() const
 | 
			
		||||
    {
 | 
			
		||||
        init_weak_once();
 | 
			
		||||
        return shared_ptr<T>( weak_this_ );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    void init_weak_once() const
 | 
			
		||||
    {
 | 
			
		||||
        if( weak_this_._empty() )
 | 
			
		||||
        {
 | 
			
		||||
            shared_this_.reset( static_cast< T* >( 0 ), detail::esft2_deleter_wrapper() );
 | 
			
		||||
            weak_this_ = shared_this_;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
public: // actually private, but avoids compiler template friendship issues
 | 
			
		||||
 | 
			
		||||
    // Note: invoked automatically by shared_ptr; do not call
 | 
			
		||||
    template<class X, class Y> void _internal_accept_owner( shared_ptr<X> * ppx, Y * py ) const
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ASSERT( ppx != 0 );
 | 
			
		||||
 | 
			
		||||
        if( weak_this_.use_count() == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            weak_this_ = shared_ptr<T>( *ppx, py );
 | 
			
		||||
        }
 | 
			
		||||
        else if( shared_this_.use_count() != 0 )
 | 
			
		||||
        {
 | 
			
		||||
            BOOST_ASSERT( ppx->unique() ); // no weak_ptrs should exist either, but there's no way to check that
 | 
			
		||||
 | 
			
		||||
            detail::esft2_deleter_wrapper * pd = boost::get_deleter<detail::esft2_deleter_wrapper>( shared_this_ );
 | 
			
		||||
            BOOST_ASSERT( pd != 0 );
 | 
			
		||||
 | 
			
		||||
            pd->set_deleter( *ppx );
 | 
			
		||||
 | 
			
		||||
            ppx->reset( shared_this_, ppx->get() );
 | 
			
		||||
            shared_this_.reset();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_ENABLE_SHARED_FROM_THIS2_HPP_INCLUDED
 | 
			
		||||
							
								
								
									
										299
									
								
								include/boost/smart_ptr/intrusive_ptr.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										299
									
								
								include/boost/smart_ptr/intrusive_ptr.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,299 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_INTRUSIVE_PTR_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_INTRUSIVE_PTR_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  intrusive_ptr.hpp
 | 
			
		||||
//
 | 
			
		||||
//  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)
 | 
			
		||||
//
 | 
			
		||||
//  See http://www.boost.org/libs/smart_ptr/intrusive_ptr.html for documentation.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
 | 
			
		||||
#include <boost/assert.hpp>
 | 
			
		||||
#include <boost/detail/workaround.hpp>
 | 
			
		||||
#include <boost/smart_ptr/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 <iosfwd>               // for std::basic_ostream
 | 
			
		||||
#else
 | 
			
		||||
#include <ostream>
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  intrusive_ptr
 | 
			
		||||
//
 | 
			
		||||
//  A smart pointer that uses intrusive reference counting.
 | 
			
		||||
//
 | 
			
		||||
//  Relies on unqualified calls to
 | 
			
		||||
//  
 | 
			
		||||
//      void intrusive_ptr_add_ref(T * p);
 | 
			
		||||
//      void intrusive_ptr_release(T * p);
 | 
			
		||||
//
 | 
			
		||||
//          (p != 0)
 | 
			
		||||
//
 | 
			
		||||
//  The object is responsible for destroying itself.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
template<class T> class intrusive_ptr
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    typedef intrusive_ptr this_type;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    typedef T element_type;
 | 
			
		||||
 | 
			
		||||
    intrusive_ptr(): px( 0 )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    intrusive_ptr( T * p, bool add_ref = true ): px( p )
 | 
			
		||||
    {
 | 
			
		||||
        if( px != 0 && add_ref ) intrusive_ptr_add_ref( px );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#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 boost::detail::sp_enable_if_convertible<U,T>::type = boost::detail::sp_empty() )
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
    intrusive_ptr( intrusive_ptr<U> const & rhs )
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
    : px( rhs.get() )
 | 
			
		||||
    {
 | 
			
		||||
        if( px != 0 ) intrusive_ptr_add_ref( px );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    intrusive_ptr(intrusive_ptr const & rhs): px( rhs.px )
 | 
			
		||||
    {
 | 
			
		||||
        if( px != 0 ) intrusive_ptr_add_ref( px );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~intrusive_ptr()
 | 
			
		||||
    {
 | 
			
		||||
        if( px != 0 ) intrusive_ptr_release( px );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES)
 | 
			
		||||
 | 
			
		||||
    template<class U> intrusive_ptr & operator=(intrusive_ptr<U> const & rhs)
 | 
			
		||||
    {
 | 
			
		||||
        this_type(rhs).swap(*this);
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Move support
 | 
			
		||||
 | 
			
		||||
#if defined( BOOST_HAS_RVALUE_REFS )
 | 
			
		||||
 | 
			
		||||
    intrusive_ptr(intrusive_ptr && rhs): px( rhs.px )
 | 
			
		||||
    {
 | 
			
		||||
        rhs.px = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    intrusive_ptr & operator=(intrusive_ptr && rhs)
 | 
			
		||||
    {
 | 
			
		||||
        this_type( static_cast< intrusive_ptr && >( rhs ) ).swap(*this);
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    intrusive_ptr & operator=(intrusive_ptr const & rhs)
 | 
			
		||||
    {
 | 
			
		||||
        this_type(rhs).swap(*this);
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    intrusive_ptr & operator=(T * rhs)
 | 
			
		||||
    {
 | 
			
		||||
        this_type(rhs).swap(*this);
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void reset()
 | 
			
		||||
    {
 | 
			
		||||
        this_type().swap( *this );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void reset( T * rhs )
 | 
			
		||||
    {
 | 
			
		||||
        this_type( rhs ).swap( *this );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    T * get() const
 | 
			
		||||
    {
 | 
			
		||||
        return px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    T & operator*() const
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ASSERT( px != 0 );
 | 
			
		||||
        return *px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    T * operator->() const
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ASSERT( px != 0 );
 | 
			
		||||
        return px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
// implicit conversion to "bool"
 | 
			
		||||
#include <boost/smart_ptr/detail/operator_bool.hpp>
 | 
			
		||||
 | 
			
		||||
    void swap(intrusive_ptr & rhs)
 | 
			
		||||
    {
 | 
			
		||||
        T * tmp = px;
 | 
			
		||||
        px = rhs.px;
 | 
			
		||||
        rhs.px = tmp;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    T * px;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<class T, class U> inline bool operator==(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b)
 | 
			
		||||
{
 | 
			
		||||
    return a.get() == b.get();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T, class U> inline bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b)
 | 
			
		||||
{
 | 
			
		||||
    return a.get() != b.get();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T, class U> inline bool operator==(intrusive_ptr<T> const & a, U * b)
 | 
			
		||||
{
 | 
			
		||||
    return a.get() == b;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T, class U> inline bool operator!=(intrusive_ptr<T> const & a, U * b)
 | 
			
		||||
{
 | 
			
		||||
    return a.get() != b;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T, class U> inline bool operator==(T * a, intrusive_ptr<U> const & b)
 | 
			
		||||
{
 | 
			
		||||
    return a == b.get();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T, class U> inline bool operator!=(T * a, intrusive_ptr<U> const & b)
 | 
			
		||||
{
 | 
			
		||||
    return a != b.get();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if __GNUC__ == 2 && __GNUC_MINOR__ <= 96
 | 
			
		||||
 | 
			
		||||
// Resolve the ambiguity between our op!= and the one in rel_ops
 | 
			
		||||
 | 
			
		||||
template<class T> inline bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b)
 | 
			
		||||
{
 | 
			
		||||
    return a.get() != b.get();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
template<class T> inline bool operator<(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b)
 | 
			
		||||
{
 | 
			
		||||
    return std::less<T *>()(a.get(), b.get());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> void swap(intrusive_ptr<T> & lhs, intrusive_ptr<T> & rhs)
 | 
			
		||||
{
 | 
			
		||||
    lhs.swap(rhs);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// mem_fn support
 | 
			
		||||
 | 
			
		||||
template<class T> T * get_pointer(intrusive_ptr<T> const & p)
 | 
			
		||||
{
 | 
			
		||||
    return p.get();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T, class U> intrusive_ptr<T> static_pointer_cast(intrusive_ptr<U> const & p)
 | 
			
		||||
{
 | 
			
		||||
    return static_cast<T *>(p.get());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T, class U> intrusive_ptr<T> const_pointer_cast(intrusive_ptr<U> const & p)
 | 
			
		||||
{
 | 
			
		||||
    return const_cast<T *>(p.get());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T, class U> intrusive_ptr<T> dynamic_pointer_cast(intrusive_ptr<U> const & p)
 | 
			
		||||
{
 | 
			
		||||
    return dynamic_cast<T *>(p.get());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// operator<<
 | 
			
		||||
 | 
			
		||||
#if !defined(BOOST_NO_IOSTREAM)
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_NO_TEMPLATED_IOSTREAMS) || ( defined(__GNUC__) &&  (__GNUC__ < 3) )
 | 
			
		||||
 | 
			
		||||
template<class Y> std::ostream & operator<< (std::ostream & os, intrusive_ptr<Y> const & p)
 | 
			
		||||
{
 | 
			
		||||
    os << p.get();
 | 
			
		||||
    return os;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#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)
 | 
			
		||||
// 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)
 | 
			
		||||
# else
 | 
			
		||||
template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, intrusive_ptr<Y> const & p)
 | 
			
		||||
# endif 
 | 
			
		||||
{
 | 
			
		||||
    os << p.get();
 | 
			
		||||
    return os;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // _STLP_NO_IOSTREAMS
 | 
			
		||||
 | 
			
		||||
#endif // __GNUC__ < 3
 | 
			
		||||
 | 
			
		||||
#endif // !defined(BOOST_NO_IOSTREAM)
 | 
			
		||||
 | 
			
		||||
// hash_value
 | 
			
		||||
 | 
			
		||||
template< class T > struct hash;
 | 
			
		||||
 | 
			
		||||
template< class T > std::size_t hash_value( boost::intrusive_ptr<T> const & p )
 | 
			
		||||
{
 | 
			
		||||
    return boost::hash< T* >()( p.get() );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_INTRUSIVE_PTR_HPP_INCLUDED
 | 
			
		||||
							
								
								
									
										981
									
								
								include/boost/smart_ptr/make_shared.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										981
									
								
								include/boost/smart_ptr/make_shared.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,981 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_MAKE_SHARED_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_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/smart_ptr/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_ )
 | 
			
		||||
        {
 | 
			
		||||
#if defined( __GNUC__ )
 | 
			
		||||
 | 
			
		||||
            // fixes incorrect aliasing warning
 | 
			
		||||
            T * p = reinterpret_cast< T* >( storage_.data_ );
 | 
			
		||||
            p->~T();
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
            reinterpret_cast< T* >( storage_.data_ )->~T();
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
            initialized_ = false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    sp_ms_deleter(): initialized_( false )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // optimization: do not copy storage_
 | 
			
		||||
    sp_ms_deleter( sp_ms_deleter const & ): initialized_( false )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~sp_ms_deleter()
 | 
			
		||||
    {
 | 
			
		||||
        destroy();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void operator()( T * )
 | 
			
		||||
    {
 | 
			
		||||
        destroy();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void * address()
 | 
			
		||||
    {
 | 
			
		||||
        return storage_.data_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void set_initialized()
 | 
			
		||||
    {
 | 
			
		||||
        initialized_ = true;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if defined( BOOST_HAS_RVALUE_REFS )
 | 
			
		||||
 | 
			
		||||
template< class T > T&& sp_forward( T & t )
 | 
			
		||||
{
 | 
			
		||||
    return static_cast< T&& >( t );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
 | 
			
		||||
# define BOOST_SP_MSD( T ) boost::detail::sp_inplace_tag< boost::detail::sp_ms_deleter< T > >()
 | 
			
		||||
#else
 | 
			
		||||
# define BOOST_SP_MSD( T ) boost::detail::sp_ms_deleter< T >()
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// 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 ), BOOST_SP_MSD( T ) );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T();
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A > boost::shared_ptr< T > allocate_shared( A const & a )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T();
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if defined( BOOST_HAS_VARIADIC_TMPL ) && defined( BOOST_HAS_RVALUE_REFS )
 | 
			
		||||
 | 
			
		||||
// Variadic templates, rvalue reference
 | 
			
		||||
 | 
			
		||||
template< class T, class Arg1, class... Args > boost::shared_ptr< T > make_shared( Arg1 && arg1, Args && ... args )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( boost::detail::sp_forward<Arg1>( arg1 ), boost::detail::sp_forward<Args>( args )... );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A, class Arg1, class... Args > boost::shared_ptr< T > allocate_shared( A const & a, Arg1 && arg1, Args && ... args )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( boost::detail::sp_forward<Arg1>( arg1 ), boost::detail::sp_forward<Args>( args )... );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#elif defined( BOOST_HAS_RVALUE_REFS )
 | 
			
		||||
 | 
			
		||||
// For example MSVC 10.0
 | 
			
		||||
 | 
			
		||||
template< class T, class A1 >
 | 
			
		||||
boost::shared_ptr< T > make_shared( A1 && a1 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T(
 | 
			
		||||
        boost::detail::sp_forward<A1>( a1 )
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A, class A1 >
 | 
			
		||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 && a1 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( 
 | 
			
		||||
        boost::detail::sp_forward<A1>( a1 )
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A1, class A2 >
 | 
			
		||||
boost::shared_ptr< T > make_shared( A1 && a1, A2 && a2 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T(
 | 
			
		||||
        boost::detail::sp_forward<A1>( a1 ), 
 | 
			
		||||
        boost::detail::sp_forward<A2>( a2 )
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A, class A1, class A2 >
 | 
			
		||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 && a1, A2 && a2 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( 
 | 
			
		||||
        boost::detail::sp_forward<A1>( a1 ), 
 | 
			
		||||
        boost::detail::sp_forward<A2>( a2 )
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A1, class A2, class A3 >
 | 
			
		||||
boost::shared_ptr< T > make_shared( A1 && a1, A2 && a2, A3 && a3 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T(
 | 
			
		||||
        boost::detail::sp_forward<A1>( a1 ), 
 | 
			
		||||
        boost::detail::sp_forward<A2>( a2 ), 
 | 
			
		||||
        boost::detail::sp_forward<A3>( a3 )
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A, class A1, class A2, class A3 >
 | 
			
		||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 && a1, A2 && a2, A3 && a3 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( 
 | 
			
		||||
        boost::detail::sp_forward<A1>( a1 ), 
 | 
			
		||||
        boost::detail::sp_forward<A2>( a2 ), 
 | 
			
		||||
        boost::detail::sp_forward<A3>( a3 )
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A1, class A2, class A3, class A4 >
 | 
			
		||||
boost::shared_ptr< T > make_shared( A1 && a1, A2 && a2, A3 && a3, A4 && a4 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T(
 | 
			
		||||
        boost::detail::sp_forward<A1>( a1 ), 
 | 
			
		||||
        boost::detail::sp_forward<A2>( a2 ), 
 | 
			
		||||
        boost::detail::sp_forward<A3>( a3 ), 
 | 
			
		||||
        boost::detail::sp_forward<A4>( a4 )
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A, class A1, class A2, class A3, class A4 >
 | 
			
		||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 && a1, A2 && a2, A3 && a3, A4 && a4 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( 
 | 
			
		||||
        boost::detail::sp_forward<A1>( a1 ), 
 | 
			
		||||
        boost::detail::sp_forward<A2>( a2 ), 
 | 
			
		||||
        boost::detail::sp_forward<A3>( a3 ), 
 | 
			
		||||
        boost::detail::sp_forward<A4>( a4 )
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A1, class A2, class A3, class A4, class A5 >
 | 
			
		||||
boost::shared_ptr< T > make_shared( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T(
 | 
			
		||||
        boost::detail::sp_forward<A1>( a1 ), 
 | 
			
		||||
        boost::detail::sp_forward<A2>( a2 ), 
 | 
			
		||||
        boost::detail::sp_forward<A3>( a3 ), 
 | 
			
		||||
        boost::detail::sp_forward<A4>( a4 ), 
 | 
			
		||||
        boost::detail::sp_forward<A5>( a5 )
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( 
 | 
			
		||||
        boost::detail::sp_forward<A1>( a1 ), 
 | 
			
		||||
        boost::detail::sp_forward<A2>( a2 ), 
 | 
			
		||||
        boost::detail::sp_forward<A3>( a3 ), 
 | 
			
		||||
        boost::detail::sp_forward<A4>( a4 ), 
 | 
			
		||||
        boost::detail::sp_forward<A5>( a5 )
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A1, class A2, class A3, class A4, class A5, class A6 >
 | 
			
		||||
boost::shared_ptr< T > make_shared( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T(
 | 
			
		||||
        boost::detail::sp_forward<A1>( a1 ), 
 | 
			
		||||
        boost::detail::sp_forward<A2>( a2 ), 
 | 
			
		||||
        boost::detail::sp_forward<A3>( a3 ), 
 | 
			
		||||
        boost::detail::sp_forward<A4>( a4 ), 
 | 
			
		||||
        boost::detail::sp_forward<A5>( a5 ), 
 | 
			
		||||
        boost::detail::sp_forward<A6>( a6 )
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( 
 | 
			
		||||
        boost::detail::sp_forward<A1>( a1 ), 
 | 
			
		||||
        boost::detail::sp_forward<A2>( a2 ), 
 | 
			
		||||
        boost::detail::sp_forward<A3>( a3 ), 
 | 
			
		||||
        boost::detail::sp_forward<A4>( a4 ), 
 | 
			
		||||
        boost::detail::sp_forward<A5>( a5 ), 
 | 
			
		||||
        boost::detail::sp_forward<A6>( a6 )
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7 >
 | 
			
		||||
boost::shared_ptr< T > make_shared( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T(
 | 
			
		||||
        boost::detail::sp_forward<A1>( a1 ), 
 | 
			
		||||
        boost::detail::sp_forward<A2>( a2 ), 
 | 
			
		||||
        boost::detail::sp_forward<A3>( a3 ), 
 | 
			
		||||
        boost::detail::sp_forward<A4>( a4 ), 
 | 
			
		||||
        boost::detail::sp_forward<A5>( a5 ), 
 | 
			
		||||
        boost::detail::sp_forward<A6>( a6 ), 
 | 
			
		||||
        boost::detail::sp_forward<A7>( a7 )
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( 
 | 
			
		||||
        boost::detail::sp_forward<A1>( a1 ), 
 | 
			
		||||
        boost::detail::sp_forward<A2>( a2 ), 
 | 
			
		||||
        boost::detail::sp_forward<A3>( a3 ), 
 | 
			
		||||
        boost::detail::sp_forward<A4>( a4 ), 
 | 
			
		||||
        boost::detail::sp_forward<A5>( a5 ), 
 | 
			
		||||
        boost::detail::sp_forward<A6>( a6 ), 
 | 
			
		||||
        boost::detail::sp_forward<A7>( a7 )
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7, A8 && a8 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T(
 | 
			
		||||
        boost::detail::sp_forward<A1>( a1 ), 
 | 
			
		||||
        boost::detail::sp_forward<A2>( a2 ), 
 | 
			
		||||
        boost::detail::sp_forward<A3>( a3 ), 
 | 
			
		||||
        boost::detail::sp_forward<A4>( a4 ), 
 | 
			
		||||
        boost::detail::sp_forward<A5>( a5 ), 
 | 
			
		||||
        boost::detail::sp_forward<A6>( a6 ), 
 | 
			
		||||
        boost::detail::sp_forward<A7>( a7 ), 
 | 
			
		||||
        boost::detail::sp_forward<A8>( a8 )
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7, A8 && a8 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( 
 | 
			
		||||
        boost::detail::sp_forward<A1>( a1 ), 
 | 
			
		||||
        boost::detail::sp_forward<A2>( a2 ), 
 | 
			
		||||
        boost::detail::sp_forward<A3>( a3 ), 
 | 
			
		||||
        boost::detail::sp_forward<A4>( a4 ), 
 | 
			
		||||
        boost::detail::sp_forward<A5>( a5 ), 
 | 
			
		||||
        boost::detail::sp_forward<A6>( a6 ), 
 | 
			
		||||
        boost::detail::sp_forward<A7>( a7 ), 
 | 
			
		||||
        boost::detail::sp_forward<A8>( a8 )
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7, A8 && a8, A9 && a9 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T(
 | 
			
		||||
        boost::detail::sp_forward<A1>( a1 ), 
 | 
			
		||||
        boost::detail::sp_forward<A2>( a2 ), 
 | 
			
		||||
        boost::detail::sp_forward<A3>( a3 ), 
 | 
			
		||||
        boost::detail::sp_forward<A4>( a4 ), 
 | 
			
		||||
        boost::detail::sp_forward<A5>( a5 ), 
 | 
			
		||||
        boost::detail::sp_forward<A6>( a6 ), 
 | 
			
		||||
        boost::detail::sp_forward<A7>( a7 ), 
 | 
			
		||||
        boost::detail::sp_forward<A8>( a8 ), 
 | 
			
		||||
        boost::detail::sp_forward<A9>( a9 )
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7, A8 && a8, A9 && a9 )
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( 
 | 
			
		||||
        boost::detail::sp_forward<A1>( a1 ), 
 | 
			
		||||
        boost::detail::sp_forward<A2>( a2 ), 
 | 
			
		||||
        boost::detail::sp_forward<A3>( a3 ), 
 | 
			
		||||
        boost::detail::sp_forward<A4>( a4 ), 
 | 
			
		||||
        boost::detail::sp_forward<A5>( a5 ), 
 | 
			
		||||
        boost::detail::sp_forward<A6>( a6 ), 
 | 
			
		||||
        boost::detail::sp_forward<A7>( a7 ), 
 | 
			
		||||
        boost::detail::sp_forward<A8>( a8 ), 
 | 
			
		||||
        boost::detail::sp_forward<A9>( a9 )
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#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 ), BOOST_SP_MSD( T ) );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( a1 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 ), BOOST_SP_MSD( T ), a );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( a1 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 ), BOOST_SP_MSD( T ) );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( a1, a2 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 ), BOOST_SP_MSD( T ), a );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( a1, a2 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 ), BOOST_SP_MSD( T ) );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( a1, a2, a3 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 ), BOOST_SP_MSD( T ), a );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( a1, a2, a3 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 ), BOOST_SP_MSD( T ) );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( a1, a2, a3, a4 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 ), BOOST_SP_MSD( T ), a );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( a1, a2, a3, a4 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 ), BOOST_SP_MSD( T ) );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( a1, a2, a3, a4, a5 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 ), BOOST_SP_MSD( T ), a );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( a1, a2, a3, a4, a5 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 ), BOOST_SP_MSD( T ) );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( a1, a2, a3, a4, a5, a6 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 ), BOOST_SP_MSD( T ), a );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( a1, a2, a3, a4, a5, a6 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 ), BOOST_SP_MSD( T ) );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 ), BOOST_SP_MSD( T ), a );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 ), BOOST_SP_MSD( T ) );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 ), BOOST_SP_MSD( T ), a );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
 | 
			
		||||
 | 
			
		||||
    void * pv = pd->address();
 | 
			
		||||
 | 
			
		||||
    ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8 );
 | 
			
		||||
    pd->set_initialized();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 ), BOOST_SP_MSD( T ) );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::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();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 ), BOOST_SP_MSD( T ), a );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::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();
 | 
			
		||||
 | 
			
		||||
    T * pt2 = static_cast< T* >( pv );
 | 
			
		||||
 | 
			
		||||
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
 | 
			
		||||
    return boost::shared_ptr< T >( pt, pt2 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#undef BOOST_SP_MSD
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_SMART_PTR_MAKE_SHARED_HPP_INCLUDED
 | 
			
		||||
							
								
								
									
										57
									
								
								include/boost/smart_ptr/owner_less.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								include/boost/smart_ptr/owner_less.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,57 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_OWNER_LESS_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_OWNER_LESS_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  owner_less.hpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2008 Frank Mori Hess
 | 
			
		||||
//
 | 
			
		||||
//  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/smart_ptr.htm for documentation.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <functional>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
  template<typename T> class shared_ptr;
 | 
			
		||||
  template<typename T> class weak_ptr;
 | 
			
		||||
 | 
			
		||||
  namespace detail
 | 
			
		||||
  {
 | 
			
		||||
    template<typename T, typename U>
 | 
			
		||||
      struct generic_owner_less : public std::binary_function<T, T, bool>
 | 
			
		||||
    {
 | 
			
		||||
      bool operator()(const T &lhs, const T &rhs) const
 | 
			
		||||
      {
 | 
			
		||||
        return lhs.owner_before(rhs);
 | 
			
		||||
      }
 | 
			
		||||
      bool operator()(const T &lhs, const U &rhs) const
 | 
			
		||||
      {
 | 
			
		||||
        return lhs.owner_before(rhs);
 | 
			
		||||
      }
 | 
			
		||||
      bool operator()(const U &lhs, const T &rhs) const
 | 
			
		||||
      {
 | 
			
		||||
        return lhs.owner_before(rhs);
 | 
			
		||||
      }
 | 
			
		||||
    };
 | 
			
		||||
  } // namespace detail
 | 
			
		||||
 | 
			
		||||
  template<typename T> struct owner_less;
 | 
			
		||||
 | 
			
		||||
  template<typename T>
 | 
			
		||||
    struct owner_less<shared_ptr<T> >:
 | 
			
		||||
    public detail::generic_owner_less<shared_ptr<T>, weak_ptr<T> >
 | 
			
		||||
  {};
 | 
			
		||||
 | 
			
		||||
  template<typename T>
 | 
			
		||||
    struct owner_less<weak_ptr<T> >:
 | 
			
		||||
    public detail::generic_owner_less<weak_ptr<T>, shared_ptr<T> >
 | 
			
		||||
  {};
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_OWNER_LESS_HPP_INCLUDED
 | 
			
		||||
							
								
								
									
										107
									
								
								include/boost/smart_ptr/scoped_array.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								include/boost/smart_ptr/scoped_array.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,107 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_SCOPED_ARRAY_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_SCOPED_ARRAY_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//  (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)
 | 
			
		||||
//
 | 
			
		||||
//  http://www.boost.org/libs/smart_ptr/scoped_array.htm
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/assert.hpp>
 | 
			
		||||
#include <boost/checked_delete.hpp>
 | 
			
		||||
#include <boost/config.hpp>   // in case ptrdiff_t not in std
 | 
			
		||||
 | 
			
		||||
#include <boost/detail/workaround.hpp>
 | 
			
		||||
 | 
			
		||||
#include <cstddef>            // for std::ptrdiff_t
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
// Debug hooks
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
 | 
			
		||||
void sp_array_constructor_hook(void * p);
 | 
			
		||||
void sp_array_destructor_hook(void * p);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//  scoped_array extends scoped_ptr to arrays. Deletion of the array pointed to
 | 
			
		||||
//  is guaranteed, either on destruction of the scoped_array or via an explicit
 | 
			
		||||
//  reset(). Use shared_array or std::vector if your needs are more complex.
 | 
			
		||||
 | 
			
		||||
template<class T> class scoped_array // noncopyable
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    T * px;
 | 
			
		||||
 | 
			
		||||
    scoped_array(scoped_array const &);
 | 
			
		||||
    scoped_array & operator=(scoped_array const &);
 | 
			
		||||
 | 
			
		||||
    typedef scoped_array<T> this_type;
 | 
			
		||||
 | 
			
		||||
    void operator==( scoped_array const& ) const;
 | 
			
		||||
    void operator!=( scoped_array const& ) const;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    typedef T element_type;
 | 
			
		||||
 | 
			
		||||
    explicit scoped_array( T * p = 0 ) : px( p ) // never throws
 | 
			
		||||
    {
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
        boost::sp_array_constructor_hook( px );
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~scoped_array() // never throws
 | 
			
		||||
    {
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
        boost::sp_array_destructor_hook( px );
 | 
			
		||||
#endif
 | 
			
		||||
        boost::checked_array_delete( px );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void reset(T * p = 0) // never throws
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ASSERT( p == 0 || p != px ); // catch self-reset errors
 | 
			
		||||
        this_type(p).swap(*this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    T & operator[](std::ptrdiff_t i) const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ASSERT( px != 0 );
 | 
			
		||||
        BOOST_ASSERT( i >= 0 );
 | 
			
		||||
        return px[i];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    T * get() const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
// implicit conversion to "bool"
 | 
			
		||||
#include <boost/smart_ptr/detail/operator_bool.hpp>
 | 
			
		||||
 | 
			
		||||
    void swap(scoped_array & b) // never throws
 | 
			
		||||
    {
 | 
			
		||||
        T * tmp = b.px;
 | 
			
		||||
        b.px = px;
 | 
			
		||||
        px = tmp;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<class T> inline void swap(scoped_array<T> & a, scoped_array<T> & b) // never throws
 | 
			
		||||
{
 | 
			
		||||
    a.swap(b);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_SCOPED_ARRAY_HPP_INCLUDED
 | 
			
		||||
							
								
								
									
										131
									
								
								include/boost/smart_ptr/scoped_ptr.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										131
									
								
								include/boost/smart_ptr/scoped_ptr.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,131 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_SCOPED_PTR_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_SCOPED_PTR_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//  (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)
 | 
			
		||||
//
 | 
			
		||||
//  http://www.boost.org/libs/smart_ptr/scoped_ptr.htm
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/assert.hpp>
 | 
			
		||||
#include <boost/checked_delete.hpp>
 | 
			
		||||
#include <boost/detail/workaround.hpp>
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_NO_AUTO_PTR
 | 
			
		||||
# include <memory>          // for std::auto_ptr
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
// Debug hooks
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
 | 
			
		||||
void sp_scalar_constructor_hook(void * p);
 | 
			
		||||
void sp_scalar_destructor_hook(void * p);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//  scoped_ptr mimics a built-in pointer except that it guarantees deletion
 | 
			
		||||
//  of the object pointed to, either on destruction of the scoped_ptr or via
 | 
			
		||||
//  an explicit reset(). scoped_ptr is a simple solution for simple needs;
 | 
			
		||||
//  use shared_ptr or std::auto_ptr if your needs are more complex.
 | 
			
		||||
 | 
			
		||||
template<class T> class scoped_ptr // noncopyable
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    T * px;
 | 
			
		||||
 | 
			
		||||
    scoped_ptr(scoped_ptr const &);
 | 
			
		||||
    scoped_ptr & operator=(scoped_ptr const &);
 | 
			
		||||
 | 
			
		||||
    typedef scoped_ptr<T> this_type;
 | 
			
		||||
 | 
			
		||||
    void operator==( scoped_ptr const& ) const;
 | 
			
		||||
    void operator!=( scoped_ptr const& ) const;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    typedef T element_type;
 | 
			
		||||
 | 
			
		||||
    explicit scoped_ptr( T * p = 0 ): px( p ) // never throws
 | 
			
		||||
    {
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
        boost::sp_scalar_constructor_hook( px );
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_NO_AUTO_PTR
 | 
			
		||||
 | 
			
		||||
    explicit scoped_ptr( std::auto_ptr<T> p ): px( p.release() ) // never throws
 | 
			
		||||
    {
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
        boost::sp_scalar_constructor_hook( px );
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    ~scoped_ptr() // never throws
 | 
			
		||||
    {
 | 
			
		||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 | 
			
		||||
        boost::sp_scalar_destructor_hook( px );
 | 
			
		||||
#endif
 | 
			
		||||
        boost::checked_delete( px );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void reset(T * p = 0) // never throws
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ASSERT( p == 0 || p != px ); // catch self-reset errors
 | 
			
		||||
        this_type(p).swap(*this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    T & operator*() const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ASSERT( px != 0 );
 | 
			
		||||
        return *px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    T * operator->() const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ASSERT( px != 0 );
 | 
			
		||||
        return px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    T * get() const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
// implicit conversion to "bool"
 | 
			
		||||
#include <boost/smart_ptr/detail/operator_bool.hpp>
 | 
			
		||||
 | 
			
		||||
    void swap(scoped_ptr & b) // never throws
 | 
			
		||||
    {
 | 
			
		||||
        T * tmp = b.px;
 | 
			
		||||
        b.px = px;
 | 
			
		||||
        px = tmp;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<class T> inline void swap(scoped_ptr<T> & a, scoped_ptr<T> & b) // never throws
 | 
			
		||||
{
 | 
			
		||||
    a.swap(b);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// get_pointer(p) is a generic way to say p.get()
 | 
			
		||||
 | 
			
		||||
template<class T> inline T * get_pointer(scoped_ptr<T> const & p)
 | 
			
		||||
{
 | 
			
		||||
    return p.get();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif // #ifndef BOOST_SMART_PTR_SCOPED_PTR_HPP_INCLUDED
 | 
			
		||||
							
								
								
									
										175
									
								
								include/boost/smart_ptr/shared_array.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										175
									
								
								include/boost/smart_ptr/shared_array.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,175 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_SHARED_ARRAY_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_SHARED_ARRAY_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  shared_array.hpp
 | 
			
		||||
//
 | 
			
		||||
//  (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)
 | 
			
		||||
//
 | 
			
		||||
//  See http://www.boost.org/libs/smart_ptr/shared_array.htm for documentation.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>   // for broken compiler workarounds
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
 | 
			
		||||
#include <boost/smart_ptr/detail/shared_array_nmt.hpp>
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
#include <memory>             // TR1 cyclic inclusion fix
 | 
			
		||||
 | 
			
		||||
#include <boost/assert.hpp>
 | 
			
		||||
#include <boost/checked_delete.hpp>
 | 
			
		||||
 | 
			
		||||
#include <boost/smart_ptr/detail/shared_count.hpp>
 | 
			
		||||
#include <boost/detail/workaround.hpp>
 | 
			
		||||
 | 
			
		||||
#include <cstddef>            // for std::ptrdiff_t
 | 
			
		||||
#include <algorithm>          // for std::swap
 | 
			
		||||
#include <functional>         // for std::less
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  shared_array
 | 
			
		||||
//
 | 
			
		||||
//  shared_array extends shared_ptr to arrays.
 | 
			
		||||
//  The array pointed to is deleted when the last shared_array pointing to it
 | 
			
		||||
//  is destroyed or reset.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
template<class T> class shared_array
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    // Borland 5.5.1 specific workarounds
 | 
			
		||||
    typedef checked_array_deleter<T> deleter;
 | 
			
		||||
    typedef shared_array<T> this_type;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    typedef T element_type;
 | 
			
		||||
 | 
			
		||||
    explicit shared_array(T * p = 0): px(p), pn(p, deleter())
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //
 | 
			
		||||
    // Requirements: D's copy constructor must not throw
 | 
			
		||||
    //
 | 
			
		||||
    // shared_array will release p by calling d(p)
 | 
			
		||||
    //
 | 
			
		||||
 | 
			
		||||
    template<class D> shared_array(T * p, D d): px(p), pn(p, d)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
//  generated copy constructor, destructor are fine...
 | 
			
		||||
 | 
			
		||||
#if defined( BOOST_HAS_RVALUE_REFS )
 | 
			
		||||
 | 
			
		||||
// ... except in C++0x, move disables the implicit copy
 | 
			
		||||
 | 
			
		||||
    shared_array( shared_array const & r ): px( r.px ), pn( r.pn ) // never throws
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    // assignment
 | 
			
		||||
 | 
			
		||||
    shared_array & operator=( shared_array const & r ) // never throws
 | 
			
		||||
    {
 | 
			
		||||
        this_type( r ).swap( *this );
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void reset(T * p = 0)
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ASSERT(p == 0 || p != px);
 | 
			
		||||
        this_type(p).swap(*this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template <class D> void reset(T * p, D d)
 | 
			
		||||
    {
 | 
			
		||||
        this_type(p, d).swap(*this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    T & operator[] (std::ptrdiff_t i) const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ASSERT(px != 0);
 | 
			
		||||
        BOOST_ASSERT(i >= 0);
 | 
			
		||||
        return px[i];
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    T * get() const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
// implicit conversion to "bool"
 | 
			
		||||
#include <boost/smart_ptr/detail/operator_bool.hpp>
 | 
			
		||||
 | 
			
		||||
    bool unique() const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return pn.unique();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long use_count() const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return pn.use_count();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void swap(shared_array<T> & other) // never throws
 | 
			
		||||
    {
 | 
			
		||||
        std::swap(px, other.px);
 | 
			
		||||
        pn.swap(other.pn);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void * _internal_get_deleter( boost::detail::sp_typeinfo const & ti ) const
 | 
			
		||||
    {
 | 
			
		||||
        return pn.get_deleter( ti );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    T * px;                     // contained pointer
 | 
			
		||||
    detail::shared_count pn;    // reference counter
 | 
			
		||||
 | 
			
		||||
};  // shared_array
 | 
			
		||||
 | 
			
		||||
template<class T> inline bool operator==(shared_array<T> const & a, shared_array<T> const & b) // never throws
 | 
			
		||||
{
 | 
			
		||||
    return a.get() == b.get();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> inline bool operator!=(shared_array<T> const & a, shared_array<T> const & b) // never throws
 | 
			
		||||
{
 | 
			
		||||
    return a.get() != b.get();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> inline bool operator<(shared_array<T> const & a, shared_array<T> const & b) // never throws
 | 
			
		||||
{
 | 
			
		||||
    return std::less<T*>()(a.get(), b.get());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> void swap(shared_array<T> & a, shared_array<T> & b) // never throws
 | 
			
		||||
{
 | 
			
		||||
    a.swap(b);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class D, class T > D * get_deleter( shared_array<T> const & p )
 | 
			
		||||
{
 | 
			
		||||
    return static_cast< D * >( p._internal_get_deleter( BOOST_SP_TYPEID(D) ) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_SHARED_ARRAY_HPP_INCLUDED
 | 
			
		||||
							
								
								
									
										717
									
								
								include/boost/smart_ptr/shared_ptr.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										717
									
								
								include/boost/smart_ptr/shared_ptr.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,717 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_SHARED_PTR_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_SHARED_PTR_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  shared_ptr.hpp
 | 
			
		||||
//
 | 
			
		||||
//  (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
 | 
			
		||||
//  Copyright (c) 2001-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/shared_ptr.htm for documentation.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>   // for broken compiler workarounds
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
 | 
			
		||||
#include <boost/smart_ptr/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/smart_ptr/detail/shared_count.hpp>
 | 
			
		||||
#include <boost/detail/workaround.hpp>
 | 
			
		||||
#include <boost/smart_ptr/detail/sp_convertible.hpp>
 | 
			
		||||
 | 
			
		||||
#if !defined(BOOST_SP_NO_ATOMIC_ACCESS)
 | 
			
		||||
#include <boost/smart_ptr/detail/spinlock_pool.hpp>
 | 
			
		||||
#include <boost/memory_order.hpp>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <algorithm>            // for std::swap
 | 
			
		||||
#include <functional>           // for std::less
 | 
			
		||||
#include <typeinfo>             // for std::bad_cast
 | 
			
		||||
#include <cstddef>              // for std::size_t
 | 
			
		||||
 | 
			
		||||
#if !defined(BOOST_NO_IOSTREAM)
 | 
			
		||||
#if !defined(BOOST_NO_IOSFWD)
 | 
			
		||||
#include <iosfwd>               // for std::basic_ostream
 | 
			
		||||
#else
 | 
			
		||||
#include <ostream>
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
template<class T> class shared_ptr;
 | 
			
		||||
template<class T> class weak_ptr;
 | 
			
		||||
template<class T> class enable_shared_from_this;
 | 
			
		||||
template<class T> class enable_shared_from_this2;
 | 
			
		||||
 | 
			
		||||
namespace detail
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
struct static_cast_tag {};
 | 
			
		||||
struct const_cast_tag {};
 | 
			
		||||
struct dynamic_cast_tag {};
 | 
			
		||||
struct polymorphic_cast_tag {};
 | 
			
		||||
 | 
			
		||||
template<class T> struct shared_ptr_traits
 | 
			
		||||
{
 | 
			
		||||
    typedef T & reference;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<> struct shared_ptr_traits<void>
 | 
			
		||||
{
 | 
			
		||||
    typedef void reference;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if !defined(BOOST_NO_CV_VOID_SPECIALIZATIONS)
 | 
			
		||||
 | 
			
		||||
template<> struct shared_ptr_traits<void const>
 | 
			
		||||
{
 | 
			
		||||
    typedef void reference;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<> struct shared_ptr_traits<void volatile>
 | 
			
		||||
{
 | 
			
		||||
    typedef void reference;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<> struct shared_ptr_traits<void const volatile>
 | 
			
		||||
{
 | 
			
		||||
    typedef void reference;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// enable_shared_from_this support
 | 
			
		||||
 | 
			
		||||
template< class X, class Y, class T > inline void sp_enable_shared_from_this( boost::shared_ptr<X> const * ppx, Y const * py, boost::enable_shared_from_this< T > const * pe )
 | 
			
		||||
{
 | 
			
		||||
    if( pe != 0 )
 | 
			
		||||
    {
 | 
			
		||||
        pe->_internal_accept_owner( ppx, const_cast< Y* >( py ) );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template< class X, class Y, class T > inline void sp_enable_shared_from_this( boost::shared_ptr<X> * ppx, Y const * py, boost::enable_shared_from_this2< T > const * pe )
 | 
			
		||||
{
 | 
			
		||||
    if( pe != 0 )
 | 
			
		||||
    {
 | 
			
		||||
        pe->_internal_accept_owner( ppx, const_cast< Y* >( py ) );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#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( sp_any_pointer, sp_any_pointer, sp_any_pointer )
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#else // _MANAGED
 | 
			
		||||
 | 
			
		||||
inline void sp_enable_shared_from_this( ... )
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  shared_ptr
 | 
			
		||||
//
 | 
			
		||||
//  An enhanced relative of scoped_ptr with reference counted copy semantics.
 | 
			
		||||
//  The object pointed to is deleted when the last shared_ptr pointing to it
 | 
			
		||||
//  is destroyed or reset.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
template<class T> class shared_ptr
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    // Borland 5.5.1 specific workaround
 | 
			
		||||
    typedef shared_ptr<T> this_type;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    typedef T element_type;
 | 
			
		||||
    typedef T value_type;
 | 
			
		||||
    typedef T * pointer;
 | 
			
		||||
    typedef typename boost::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
 | 
			
		||||
    {
 | 
			
		||||
        boost::detail::sp_enable_shared_from_this( this, p, p );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //
 | 
			
		||||
    // Requirements: D's copy constructor must not throw
 | 
			
		||||
    //
 | 
			
		||||
    // shared_ptr will release p by calling d(p)
 | 
			
		||||
    //
 | 
			
		||||
 | 
			
		||||
    template<class Y, class D> shared_ptr(Y * p, D d): px(p), pn(p, d)
 | 
			
		||||
    {
 | 
			
		||||
        boost::detail::sp_enable_shared_from_this( this, 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( this, p, p );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
//  generated copy constructor, destructor are fine...
 | 
			
		||||
 | 
			
		||||
#if defined( BOOST_HAS_RVALUE_REFS )
 | 
			
		||||
 | 
			
		||||
// ... except in C++0x, move disables the implicit copy
 | 
			
		||||
 | 
			
		||||
    shared_ptr( shared_ptr const & r ): px( r.px ), pn( r.pn ) // never throws
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
    explicit shared_ptr(weak_ptr<Y> const & r): pn(r.pn) // may throw
 | 
			
		||||
    {
 | 
			
		||||
        // it is now safe to copy r.px, as pn(r.pn) did not throw
 | 
			
		||||
        px = r.px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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 boost::detail::sp_enable_if_convertible<Y,T>::type = boost::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
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
    shared_ptr(shared_ptr<Y> const & r, boost::detail::dynamic_cast_tag): px(dynamic_cast<element_type *>(r.px)), pn(r.pn)
 | 
			
		||||
    {
 | 
			
		||||
        if(px == 0) // need to allocate new counter -- the cast failed
 | 
			
		||||
        {
 | 
			
		||||
            pn = boost::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)
 | 
			
		||||
    {
 | 
			
		||||
        if(px == 0)
 | 
			
		||||
        {
 | 
			
		||||
            boost::throw_exception(std::bad_cast());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_NO_AUTO_PTR
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
    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( this, tmp, tmp );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
 | 
			
		||||
 | 
			
		||||
    template<class Ap>
 | 
			
		||||
    explicit 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( this, tmp, tmp );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif // BOOST_NO_SFINAE, BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 | 
			
		||||
 | 
			
		||||
#endif // BOOST_NO_AUTO_PTR
 | 
			
		||||
 | 
			
		||||
    // assignment
 | 
			
		||||
 | 
			
		||||
    shared_ptr & operator=( shared_ptr const & r ) // never throws
 | 
			
		||||
    {
 | 
			
		||||
        this_type(r).swap(*this);
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1400)
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
    shared_ptr & operator=(shared_ptr<Y> const & r) // never throws
 | 
			
		||||
    {
 | 
			
		||||
        this_type(r).swap(*this);
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_NO_AUTO_PTR
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
    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 boost::detail::sp_enable_if_convertible<Y,T>::type = boost::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+
 | 
			
		||||
    {
 | 
			
		||||
        this_type().swap(*this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class Y> void reset(Y * p) // Y must be complete
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ASSERT(p == 0 || p != px); // catch self-reset errors
 | 
			
		||||
        this_type(p).swap(*this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    reference operator* () const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ASSERT(px != 0);
 | 
			
		||||
        return *px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    T * operator-> () const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ASSERT(px != 0);
 | 
			
		||||
        return px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    T * get() const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
// implicit conversion to "bool"
 | 
			
		||||
#include <boost/smart_ptr/detail/operator_bool.hpp>
 | 
			
		||||
 | 
			
		||||
    bool unique() const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return pn.unique();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long use_count() const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return pn.use_count();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void swap(shared_ptr<T> & other) // never throws
 | 
			
		||||
    {
 | 
			
		||||
        std::swap(px, other.px);
 | 
			
		||||
        pn.swap(other.pn);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class Y> bool owner_before( shared_ptr<Y> const & rhs ) const
 | 
			
		||||
    {
 | 
			
		||||
        return pn < rhs.pn;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class Y> bool owner_before( weak_ptr<Y> const & rhs ) const
 | 
			
		||||
    {
 | 
			
		||||
        return pn < rhs.pn;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void * _internal_get_deleter( boost::detail::sp_typeinfo const & ti ) const
 | 
			
		||||
    {
 | 
			
		||||
        return pn.get_deleter( ti );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool _internal_equiv( shared_ptr const & r ) const
 | 
			
		||||
    {
 | 
			
		||||
        return px == r.px && pn == r.pn;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
// Tasteless as this may seem, making all members public allows member templates
 | 
			
		||||
// to work in the absence of member template friends. (Matthew Langston)
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    template<class Y> friend class shared_ptr;
 | 
			
		||||
    template<class Y> friend class weak_ptr;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    T * px;                     // contained pointer
 | 
			
		||||
    boost::detail::shared_count pn;    // reference counter
 | 
			
		||||
 | 
			
		||||
};  // shared_ptr
 | 
			
		||||
 | 
			
		||||
template<class T, class U> inline bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b)
 | 
			
		||||
{
 | 
			
		||||
    return a.get() == b.get();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T, class U> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b)
 | 
			
		||||
{
 | 
			
		||||
    return a.get() != b.get();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if __GNUC__ == 2 && __GNUC_MINOR__ <= 96
 | 
			
		||||
 | 
			
		||||
// Resolve the ambiguity between our op!= and the one in rel_ops
 | 
			
		||||
 | 
			
		||||
template<class T> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<T> const & b)
 | 
			
		||||
{
 | 
			
		||||
    return a.get() != b.get();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
template<class T, class U> inline bool operator<(shared_ptr<T> const & a, shared_ptr<U> const & b)
 | 
			
		||||
{
 | 
			
		||||
    return a.owner_before( b );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> inline void swap(shared_ptr<T> & a, shared_ptr<T> & b)
 | 
			
		||||
{
 | 
			
		||||
    a.swap(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());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T, class U> shared_ptr<T> shared_polymorphic_downcast(shared_ptr<U> const & r)
 | 
			
		||||
{
 | 
			
		||||
    BOOST_ASSERT(dynamic_cast<T *>(r.get()) == r.get());
 | 
			
		||||
    return shared_static_cast<T>(r);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// get_pointer() enables boost::mem_fn to recognize shared_ptr
 | 
			
		||||
 | 
			
		||||
template<class T> inline T * get_pointer(shared_ptr<T> const & p)
 | 
			
		||||
{
 | 
			
		||||
    return p.get();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// operator<<
 | 
			
		||||
 | 
			
		||||
#if !defined(BOOST_NO_IOSTREAM)
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_NO_TEMPLATED_IOSTREAMS) || ( defined(__GNUC__) &&  (__GNUC__ < 3) )
 | 
			
		||||
 | 
			
		||||
template<class Y> std::ostream & operator<< (std::ostream & os, shared_ptr<Y> const & p)
 | 
			
		||||
{
 | 
			
		||||
    os << p.get();
 | 
			
		||||
    return os;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#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)
 | 
			
		||||
// 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
 | 
			
		||||
{
 | 
			
		||||
    os << p.get();
 | 
			
		||||
    return os;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // _STLP_NO_IOSTREAMS
 | 
			
		||||
 | 
			
		||||
#endif // __GNUC__ < 3
 | 
			
		||||
 | 
			
		||||
#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) )
 | 
			
		||||
 | 
			
		||||
// 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
 | 
			
		||||
 | 
			
		||||
template<class D, class T> D * get_deleter(shared_ptr<T> const & p)
 | 
			
		||||
{
 | 
			
		||||
    void const * q = p._internal_get_deleter(BOOST_SP_TYPEID(D));
 | 
			
		||||
    return const_cast<D *>(static_cast<D const *>(q));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
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 )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // !defined(BOOST_SP_NO_ATOMIC_ACCESS)
 | 
			
		||||
 | 
			
		||||
// hash_value
 | 
			
		||||
 | 
			
		||||
template< class T > struct hash;
 | 
			
		||||
 | 
			
		||||
template< class T > std::size_t hash_value( boost::shared_ptr<T> const & p )
 | 
			
		||||
{
 | 
			
		||||
    return boost::hash< T* >()( p.get() );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_SHARED_PTR_HPP_INCLUDED
 | 
			
		||||
							
								
								
									
										242
									
								
								include/boost/smart_ptr/weak_ptr.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										242
									
								
								include/boost/smart_ptr/weak_ptr.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,242 @@
 | 
			
		||||
#ifndef BOOST_SMART_PTR_WEAK_PTR_HPP_INCLUDED
 | 
			
		||||
#define BOOST_SMART_PTR_WEAK_PTR_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  weak_ptr.hpp
 | 
			
		||||
//
 | 
			
		||||
//  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)
 | 
			
		||||
//
 | 
			
		||||
//  See http://www.boost.org/libs/smart_ptr/weak_ptr.htm for documentation.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <memory> // boost.TR1 include order fix
 | 
			
		||||
#include <boost/smart_ptr/detail/shared_count.hpp>
 | 
			
		||||
#include <boost/smart_ptr/shared_ptr.hpp>
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
template<class T> class weak_ptr
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    // Borland 5.5.1 specific workarounds
 | 
			
		||||
    typedef weak_ptr<T> this_type;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    typedef T element_type;
 | 
			
		||||
 | 
			
		||||
    weak_ptr(): px(0), pn() // never throws in 1.30+
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
//  generated copy constructor, assignment, destructor are fine...
 | 
			
		||||
 | 
			
		||||
#if defined( BOOST_HAS_RVALUE_REFS )
 | 
			
		||||
 | 
			
		||||
// ... except in C++0x, move disables the implicit copy
 | 
			
		||||
 | 
			
		||||
    weak_ptr( weak_ptr const & r ): px( r.px ), pn( r.pn ) // never throws
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    weak_ptr & operator=( weak_ptr const & r ) // never throws
 | 
			
		||||
    {
 | 
			
		||||
        px = r.px;
 | 
			
		||||
        pn = r.pn;
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  The "obvious" converting constructor implementation:
 | 
			
		||||
//
 | 
			
		||||
//  template<class Y>
 | 
			
		||||
//  weak_ptr(weak_ptr<Y> const & r): px(r.px), pn(r.pn) // never throws
 | 
			
		||||
//  {
 | 
			
		||||
//  }
 | 
			
		||||
//
 | 
			
		||||
//  has a serious problem.
 | 
			
		||||
//
 | 
			
		||||
//  r.px may already have been invalidated. The px(r.px)
 | 
			
		||||
//  conversion may require access to *r.px (virtual inheritance).
 | 
			
		||||
//
 | 
			
		||||
//  It is not possible to avoid spurious access violations since
 | 
			
		||||
//  in multithreaded programs r.px may be invalidated at any point.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
 | 
			
		||||
 | 
			
		||||
    weak_ptr( weak_ptr<Y> const & r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() )
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
    weak_ptr( weak_ptr<Y> const & r )
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
    : px(r.lock().get()), pn(r.pn) // never throws
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if defined( BOOST_HAS_RVALUE_REFS )
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
 | 
			
		||||
 | 
			
		||||
    weak_ptr( weak_ptr<Y> && r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() )
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
    weak_ptr( weak_ptr<Y> && r )
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
    : px( r.lock().get() ), pn( static_cast< boost::detail::weak_count && >( r.pn ) ) // never throws
 | 
			
		||||
    {
 | 
			
		||||
        r.px = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // for better efficiency in the T == Y case
 | 
			
		||||
    weak_ptr( weak_ptr && r ): px( r.px ), pn( static_cast< boost::detail::weak_count && >( r.pn ) ) // never throws
 | 
			
		||||
    {
 | 
			
		||||
        r.px = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // for better efficiency in the T == Y case
 | 
			
		||||
    weak_ptr & operator=( weak_ptr && r ) // never throws
 | 
			
		||||
    {
 | 
			
		||||
        this_type( static_cast< weak_ptr && >( r ) ).swap( *this );
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
 | 
			
		||||
 | 
			
		||||
    weak_ptr( shared_ptr<Y> const & r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() )
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
    weak_ptr( shared_ptr<Y> const & r )
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
    : px( r.px ), pn( r.pn ) // never throws
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300)
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
    weak_ptr & operator=(weak_ptr<Y> const & r) // never throws
 | 
			
		||||
    {
 | 
			
		||||
        px = r.lock().get();
 | 
			
		||||
        pn = r.pn;
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if defined( BOOST_HAS_RVALUE_REFS )
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
    weak_ptr & operator=( weak_ptr<Y> && r )
 | 
			
		||||
    {
 | 
			
		||||
        this_type( static_cast< weak_ptr<Y> && >( r ) ).swap( *this );
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
    weak_ptr & operator=(shared_ptr<Y> const & r) // never throws
 | 
			
		||||
    {
 | 
			
		||||
        px = r.px;
 | 
			
		||||
        pn = r.pn;
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    shared_ptr<T> lock() const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return shared_ptr<element_type>( *this, boost::detail::sp_nothrow_tag() );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    long use_count() const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return pn.use_count();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool expired() const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return pn.use_count() == 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool _empty() const // extension, not in std::weak_ptr
 | 
			
		||||
    {
 | 
			
		||||
        return pn.empty();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void reset() // never throws in 1.30+
 | 
			
		||||
    {
 | 
			
		||||
        this_type().swap(*this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void swap(this_type & other) // never throws
 | 
			
		||||
    {
 | 
			
		||||
        std::swap(px, other.px);
 | 
			
		||||
        pn.swap(other.pn);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void _internal_assign(T * px2, boost::detail::shared_count const & pn2)
 | 
			
		||||
    {
 | 
			
		||||
        px = px2;
 | 
			
		||||
        pn = pn2;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class Y> bool owner_before( weak_ptr<Y> const & rhs ) const
 | 
			
		||||
    {
 | 
			
		||||
        return pn < rhs.pn;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class Y> bool owner_before( shared_ptr<Y> const & rhs ) const
 | 
			
		||||
    {
 | 
			
		||||
        return pn < rhs.pn;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
// Tasteless as this may seem, making all members public allows member templates
 | 
			
		||||
// to work in the absence of member template friends. (Matthew Langston)
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    template<class Y> friend class weak_ptr;
 | 
			
		||||
    template<class Y> friend class shared_ptr;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    T * px;                       // contained pointer
 | 
			
		||||
    boost::detail::weak_count pn; // reference counter
 | 
			
		||||
 | 
			
		||||
};  // weak_ptr
 | 
			
		||||
 | 
			
		||||
template<class T, class U> inline bool operator<(weak_ptr<T> const & a, weak_ptr<U> const & b)
 | 
			
		||||
{
 | 
			
		||||
    return a.owner_before( b );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> void swap(weak_ptr<T> & a, weak_ptr<T> & b)
 | 
			
		||||
{
 | 
			
		||||
    a.swap(b);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_SMART_PTR_WEAK_PTR_HPP_INCLUDED
 | 
			
		||||
@@ -6,189 +6,13 @@
 | 
			
		||||
//
 | 
			
		||||
//  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)
 | 
			
		||||
//  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/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
 | 
			
		||||
# pragma warning(push)
 | 
			
		||||
# pragma warning(disable:4284) // odd return type for operator->
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
template<class T> class weak_ptr
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    // Borland 5.5.1 specific workarounds
 | 
			
		||||
    typedef weak_ptr<T> this_type;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    typedef T element_type;
 | 
			
		||||
 | 
			
		||||
    weak_ptr(): px(0), pn() // never throws in 1.30+
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
//  generated copy constructor, assignment, destructor are fine
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  The "obvious" converting constructor implementation:
 | 
			
		||||
//
 | 
			
		||||
//  template<class Y>
 | 
			
		||||
//  weak_ptr(weak_ptr<Y> const & r): px(r.px), pn(r.pn) // never throws
 | 
			
		||||
//  {
 | 
			
		||||
//  }
 | 
			
		||||
//
 | 
			
		||||
//  has a serious problem.
 | 
			
		||||
//
 | 
			
		||||
//  r.px may already have been invalidated. The px(r.px)
 | 
			
		||||
//  conversion may require access to *r.px (virtual inheritance).
 | 
			
		||||
//
 | 
			
		||||
//  It is not possible to avoid spurious access violations since
 | 
			
		||||
//  in multithreaded programs r.px may be invalidated at any point.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
    weak_ptr(weak_ptr<Y> const & r): pn(r.pn) // never throws
 | 
			
		||||
    {
 | 
			
		||||
        px = r.lock().get();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
    weak_ptr(shared_ptr<Y> const & r): px(r.px), pn(r.pn) // never throws
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300)
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
    weak_ptr & operator=(weak_ptr<Y> const & r) // never throws
 | 
			
		||||
    {
 | 
			
		||||
        px = r.lock().get();
 | 
			
		||||
        pn = r.pn;
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class Y>
 | 
			
		||||
    weak_ptr & operator=(shared_ptr<Y> const & r) // never throws
 | 
			
		||||
    {
 | 
			
		||||
        px = r.px;
 | 
			
		||||
        pn = r.pn;
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    shared_ptr<T> lock() const // never throws
 | 
			
		||||
    {
 | 
			
		||||
#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
 | 
			
		||||
    {
 | 
			
		||||
        return pn.use_count();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool expired() const // never throws
 | 
			
		||||
    {
 | 
			
		||||
        return pn.use_count() == 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void reset() // never throws in 1.30+
 | 
			
		||||
    {
 | 
			
		||||
        this_type().swap(*this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void swap(this_type & other) // never throws
 | 
			
		||||
    {
 | 
			
		||||
        std::swap(px, other.px);
 | 
			
		||||
        pn.swap(other.pn);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void _internal_assign(T * px2, boost::detail::shared_count const & pn2)
 | 
			
		||||
    {
 | 
			
		||||
        px = px2;
 | 
			
		||||
        pn = pn2;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class Y> bool _internal_less(weak_ptr<Y> const & rhs) const
 | 
			
		||||
    {
 | 
			
		||||
        return pn < rhs.pn;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
// Tasteless as this may seem, making all members public allows member templates
 | 
			
		||||
// to work in the absence of member template friends. (Matthew Langston)
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    template<class Y> friend class weak_ptr;
 | 
			
		||||
    template<class Y> friend class shared_ptr;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    T * px;                       // contained pointer
 | 
			
		||||
    boost::detail::weak_count pn; // reference counter
 | 
			
		||||
 | 
			
		||||
};  // weak_ptr
 | 
			
		||||
 | 
			
		||||
template<class T, class U> inline bool operator<(weak_ptr<T> const & a, weak_ptr<U> const & b)
 | 
			
		||||
{
 | 
			
		||||
    return a._internal_less(b);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
# pragma warning(pop)
 | 
			
		||||
#endif    
 | 
			
		||||
#include <boost/smart_ptr/weak_ptr.hpp>
 | 
			
		||||
 | 
			
		||||
#endif  // #ifndef BOOST_WEAK_PTR_HPP_INCLUDED
 | 
			
		||||
 
 | 
			
		||||
@@ -61,7 +61,10 @@
 | 
			
		||||
 | 
			
		||||
      intrusive_ptr & <A href="#assignment" >operator=</A>(intrusive_ptr const & r);
 | 
			
		||||
      template<class Y> intrusive_ptr & <A href="#assignment" >operator=</A>(intrusive_ptr<Y> const & r);
 | 
			
		||||
      template<class Y> intrusive_ptr & <A href="#assignment" >operator=</A>(T * r);
 | 
			
		||||
      intrusive_ptr & <A href="#assignment" >operator=</A>(T * r);
 | 
			
		||||
 | 
			
		||||
      void <a href="#reset" >reset</a>();
 | 
			
		||||
      void <a href="#reset" >reset</a>(T * r);
 | 
			
		||||
 | 
			
		||||
      T & <A href="#indirection" >operator*</A>() const; // never throws
 | 
			
		||||
      T * <A href="#indirection" >operator-></A>() const; // never throws
 | 
			
		||||
@@ -146,6 +149,15 @@ intrusive_ptr & operator=(T * r);</pre>
 | 
			
		||||
			<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>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										119
									
								
								make_shared.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								make_shared.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,119 @@
 | 
			
		||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 | 
			
		||||
<html>
 | 
			
		||||
	<head>
 | 
			
		||||
		<title>make_shared and allocate_shared</title>
 | 
			
		||||
		<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>make_shared and allocate_shared function templates</h1>
 | 
			
		||||
		<p><A href="#Introduction">Introduction</A><br>
 | 
			
		||||
			<A href="#Synopsis">Synopsis</A><br>
 | 
			
		||||
			<A href="#functions">Free Functions</A><br>
 | 
			
		||||
			<A href="#example">Example</A><br>
 | 
			
		||||
		<h2><a name="Introduction">Introduction</a></h2>
 | 
			
		||||
		<p>Consistent use of <a href="shared_ptr.htm"><code>shared_ptr</code></a>
 | 
			
		||||
			can eliminate the need to use an explicit <code>delete</code>,
 | 
			
		||||
			but alone it provides no support in avoiding explicit <code>new</code>.
 | 
			
		||||
			There have been repeated requests from users for a factory function that creates
 | 
			
		||||
			an object of a given type and returns a <code>shared_ptr</code> to it.
 | 
			
		||||
			Besides convenience and style, such a function is also exception safe and
 | 
			
		||||
			considerably faster because it can use a single allocation for both the object
 | 
			
		||||
			and its corresponding control block, eliminating a significant portion of
 | 
			
		||||
			<code>shared_ptr</code>'s construction overhead.
 | 
			
		||||
			This eliminates one of the major efficiency complaints about <code>shared_ptr</code>.
 | 
			
		||||
		</p>
 | 
			
		||||
		<p>The header file <boost/make_shared.hpp> provides a family of overloaded function templates,
 | 
			
		||||
			<code>make_shared</code> and <code>allocate_shared</code>, to address this need.
 | 
			
		||||
			<code>make_shared</code> uses the global operator <code>new</code> to allocate memory,
 | 
			
		||||
			whereas <code>allocate_shared</code> uses an user-supplied allocator, allowing finer control.</p>
 | 
			
		||||
		<p>
 | 
			
		||||
			The rationale for choosing the name <code>make_shared</code> is that the expression
 | 
			
		||||
			<code>make_shared<Widget>()</code> can be read aloud and conveys the intended meaning.</p>
 | 
			
		||||
		<h2><a name="Synopsis">Synopsis</a></h2>
 | 
			
		||||
		<pre>namespace boost {
 | 
			
		||||
 | 
			
		||||
  template<typename T> class shared_ptr;
 | 
			
		||||
 | 
			
		||||
  template<typename T>
 | 
			
		||||
    shared_ptr<T> <a href="#functions">make_shared</a>();
 | 
			
		||||
 | 
			
		||||
  template<typename T, typename A>
 | 
			
		||||
    shared_ptr<T> <a href="#functions">allocate_shared</a>( A const & );
 | 
			
		||||
 | 
			
		||||
#if defined( BOOST_HAS_VARIADIC_TMPL ) && defined( BOOST_HAS_RVALUE_REFS )	// C++0x prototypes
 | 
			
		||||
 | 
			
		||||
  template<typename T, typename... Args>
 | 
			
		||||
    shared_ptr<T> <a href="#functions">make_shared</a>( Args && ... args );
 | 
			
		||||
 | 
			
		||||
  template<typename T, typename A, typename... Args>
 | 
			
		||||
    shared_ptr<T> <a href="#functions">allocate_shared</a>( A const & a, Args && ... args );
 | 
			
		||||
 | 
			
		||||
#else // no C++0X support
 | 
			
		||||
 | 
			
		||||
  template<typename T, typename Arg1 >
 | 
			
		||||
    shared_ptr<T> <a href="#functions">make_shared</a>( Arg1 const & arg1 );
 | 
			
		||||
  template<typename T, typename Arg1, typename Arg2 >
 | 
			
		||||
    shared_ptr<T> <a href="#functions">make_shared</a>( Arg1 const & arg1, Arg2 const & arg2 );
 | 
			
		||||
// ...
 | 
			
		||||
  template<typename T, typename Arg1, typename Arg2, ..., typename ArgN >
 | 
			
		||||
    shared_ptr<T> <a href="#functions">make_shared</a>( Arg1 const & arg1, Arg2 const & arg2, ..., ArgN const & argN );
 | 
			
		||||
 | 
			
		||||
  template<typename T, typename A, typename Arg1 >
 | 
			
		||||
    shared_ptr<T> <a href="#functions">allocate_shared</a>( A const & a, Arg1 const & arg1 );
 | 
			
		||||
  template<typename T, typename A, typename Arg1, typename Arg2 >
 | 
			
		||||
    shared_ptr<T> <a href="#functions">allocate_shared</a>( Arg1 const & arg1, Arg2 const & arg2 );
 | 
			
		||||
// ...
 | 
			
		||||
  template<typename T, typename A, typename Arg1, typename Arg2, ..., typename ArgN >
 | 
			
		||||
    shared_ptr<T> <a href="#functions">allocate_shared</a>( A const & a, Arg1 const & arg1, Arg2 const & arg2, ..., ArgN const & argN );
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
}</pre>
 | 
			
		||||
		<h2><a name="functions">Free Functions</a></h2>
 | 
			
		||||
		<pre>template<class T, class... Args>
 | 
			
		||||
    shared_ptr<T> make_shared( Args && ... args );
 | 
			
		||||
template<class T, class A, class... Args>
 | 
			
		||||
    shared_ptr<T> allocate_shared( A const & a, Args && ... args );</pre>
 | 
			
		||||
		<blockquote>
 | 
			
		||||
			<p><b>Requires:</b> The expression <code>new( pv ) T( std::forward<Args>(args)... )</code>,
 | 
			
		||||
				where <code>pv</code> is a <code>void*</code> pointing to storage suitable
 | 
			
		||||
				to hold an object of type <code>T</code>,
 | 
			
		||||
				shall be well-formed.  <code>A</code> shall be an <em>Allocator</em>,
 | 
			
		||||
				as described in section 20.1.5 (<stong>Allocator requirements</strong>) of the C++ Standard.
 | 
			
		||||
				The copy constructor and destructor of <code>A</code> shall not throw.</p>
 | 
			
		||||
			<p><b>Effects:</b> Allocates memory suitable for an object of type <code>T</code>
 | 
			
		||||
				and constructs an object in it via the placement new expression <code>new( pv ) T()</code>
 | 
			
		||||
				or <code>new( pv ) T( std::forward<Args>(args)... )</code>.
 | 
			
		||||
				<code>allocate_shared</code> uses a copy of <code>a</code> to allocate memory.
 | 
			
		||||
				If an exception is thrown, has no effect.</p>
 | 
			
		||||
			<p><b>Returns:</b> A <code>shared_ptr</code> instance that stores and owns the address
 | 
			
		||||
				of the newly constructed object of type <code>T</code>.</p>
 | 
			
		||||
			<p><b>Postconditions:</b> <code>get() != 0 && use_count() == 1</code>.</p>
 | 
			
		||||
			<p><b>Throws:</b> <code>bad_alloc</code>, or an exception thrown from <code>A::allocate</code>
 | 
			
		||||
				or the constructor of <code>T</code>.</p>
 | 
			
		||||
			<p><b>Notes:</b> This implementation allocates the memory required for the
 | 
			
		||||
			returned <code>shared_ptr</code> and an object of type <code>T</code> in a single
 | 
			
		||||
			allocation. This provides efficiency equivalent to an intrusive smart pointer.</p>
 | 
			
		||||
			<p>The prototypes shown above are used if your compiler supports rvalue references
 | 
			
		||||
			and variadic templates.  They perfectly forward the <code>args</code> parameters to
 | 
			
		||||
			the constructors of <code>T</code>.</p>
 | 
			
		||||
			<p>Otherwise, the implementation will fall back on
 | 
			
		||||
			forwarding the arguments to the constructors of <code>T</code> as const references.
 | 
			
		||||
			If you need to pass a non-const reference to a constructor of <code>T</code>,
 | 
			
		||||
			you may do so by wrapping the parameter in a call to <code>boost::ref</code>.
 | 
			
		||||
			In addition, you will be
 | 
			
		||||
			limited to a maximum of 9 arguments (not counting the allocator argument of
 | 
			
		||||
			allocate_shared).</p>
 | 
			
		||||
		</blockquote>
 | 
			
		||||
		<h2><a name="example">Example</a></h2>
 | 
			
		||||
		<pre>boost::shared_ptr<std::string> x = boost::make_shared<std::string>("hello, world!");
 | 
			
		||||
std::cout << *x;</pre>
 | 
			
		||||
		<hr>
 | 
			
		||||
		<p>
 | 
			
		||||
			$Date: 2008-05-19 15:42:39 -0400 (Mon, 19 May 2008) $</p>
 | 
			
		||||
		<p><small>Copyright 2008 Peter Dimov. Copyright 2008 Frank Mori Hess.
 | 
			
		||||
				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>
 | 
			
		||||
</html>
 | 
			
		||||
@@ -108,10 +108,9 @@
 | 
			
		||||
		<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>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. 
 | 
			
		||||
			Copyright 2002-2005 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>
 | 
			
		||||
		<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>
 | 
			
		||||
	</body>
 | 
			
		||||
</html>
 | 
			
		||||
 
 | 
			
		||||
@@ -173,10 +173,9 @@ Buckle my shoe</pre>
 | 
			
		||||
		<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>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. 
 | 
			
		||||
			Copyright 2002-2005 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>
 | 
			
		||||
		<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>
 | 
			
		||||
	</body>
 | 
			
		||||
</html>
 | 
			
		||||
 
 | 
			
		||||
@@ -47,7 +47,7 @@
 | 
			
		||||
      void <a href="#reset">reset</a>(T * p = 0);
 | 
			
		||||
      template<class D> void <a href="#reset">reset</a>(T * p, D d);
 | 
			
		||||
 | 
			
		||||
      T & <a href="#indexing">operator[]</a>(std::ptrdiff_t i) const() const; // never throws
 | 
			
		||||
      T & <a href="#indexing">operator[]</a>(std::ptrdiff_t i) const; // never throws
 | 
			
		||||
      T * <a href="#get">get</a>() const; // never throws
 | 
			
		||||
 | 
			
		||||
      bool <a href="#unique">unique</a>() const; // never throws
 | 
			
		||||
@@ -177,10 +177,9 @@ 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>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. 
 | 
			
		||||
			Copyright 2002-2005 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>
 | 
			
		||||
		<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>
 | 
			
		||||
	</body>
 | 
			
		||||
</html>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										332
									
								
								shared_ptr.htm
									
									
									
									
									
								
							
							
						
						
									
										332
									
								
								shared_ptr.htm
									
									
									
									
									
								
							@@ -19,54 +19,54 @@
 | 
			
		||||
			<A href="smarttests.htm">Smart Pointer Timings</A><br>
 | 
			
		||||
			<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 
 | 
			
		||||
			guaranteed to be deleted when the last <b>shared_ptr</b> pointing to it is 
 | 
			
		||||
		<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
 | 
			
		||||
			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> 
 | 
			
		||||
			requirements of the C++ Standard Library, and so can be used in standard 
 | 
			
		||||
			library containers. Comparison operators are supplied so that <b>shared_ptr</b> 
 | 
			
		||||
		<p>Every <b>shared_ptr</b> meets the <b>CopyConstructible</b> and <b>Assignable</b>
 | 
			
		||||
			requirements of the C++ Standard Library, and so can be used in standard
 | 
			
		||||
			library containers. Comparison operators are supplied so that <b>shared_ptr</b>
 | 
			
		||||
			works with the standard library's associative containers.</p>
 | 
			
		||||
		<p>Normally, a <b>shared_ptr</b> cannot correctly hold a pointer to a dynamically 
 | 
			
		||||
			allocated array. See <A href="shared_array.htm"><b>shared_array</b></A> for 
 | 
			
		||||
		<p>Normally, a <b>shared_ptr</b> cannot correctly hold a pointer to a dynamically
 | 
			
		||||
			allocated array. See <A href="shared_array.htm"><b>shared_array</b></A> for
 | 
			
		||||
			that usage.</p>
 | 
			
		||||
		<p>Because the implementation uses reference counting, cycles of <b>shared_ptr</b> instances 
 | 
			
		||||
		<p>Because the implementation uses reference counting, cycles of <b>shared_ptr</b> instances
 | 
			
		||||
			will not be reclaimed. For example, if <b>main()</b> holds a <b>shared_ptr</b> to
 | 
			
		||||
			<b>A</b>, which directly or indirectly holds a <b>shared_ptr</b> back to <b>A</b>,
 | 
			
		||||
			<b>A</b>'s use count will be 2. Destruction of the original <b>shared_ptr</b> will 
 | 
			
		||||
			<b>A</b>'s use count will be 2. Destruction of the original <b>shared_ptr</b> will
 | 
			
		||||
			leave <b>A</b> dangling with a use count of 1. Use <A href="weak_ptr.htm">weak_ptr</A>
 | 
			
		||||
			to "break cycles."</p>
 | 
			
		||||
		<p>The class template is parameterized on <b>T</b>, the type of the object pointed 
 | 
			
		||||
			to. <STRONG>shared_ptr</STRONG> and most of its member functions place no 
 | 
			
		||||
		<p>The class template is parameterized on <b>T</b>, the type of the object pointed
 | 
			
		||||
			to. <STRONG>shared_ptr</STRONG> and most of its member functions place no
 | 
			
		||||
			requirements on <STRONG>T</STRONG>; it is allowed to be an incomplete type, or <STRONG>
 | 
			
		||||
				void</STRONG>. Member functions that do place additional requirements (<A href="#constructors">constructors</A>,
 | 
			
		||||
			<A href="#reset">reset</A>) are explicitly documented below.</p>
 | 
			
		||||
		<P><STRONG>shared_ptr<T></STRONG> can be implicitly converted to <STRONG>shared_ptr<U></STRONG>
 | 
			
		||||
			whenever <STRONG>T*</STRONG> can be implicitly converted to <STRONG>U*</STRONG>. 
 | 
			
		||||
			In particular, <STRONG>shared_ptr<T></STRONG> is implicitly convertible 
 | 
			
		||||
			whenever <STRONG>T*</STRONG> can be implicitly converted to <STRONG>U*</STRONG>.
 | 
			
		||||
			In particular, <STRONG>shared_ptr<T></STRONG> is implicitly convertible
 | 
			
		||||
			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 
 | 
			
		||||
		<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 
 | 
			
		||||
		<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: 
 | 
			
		||||
		<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>
 | 
			
		||||
			Every occurence of the <STRONG>new</STRONG> keyword in the code should have the 
 | 
			
		||||
			Every occurence of the <STRONG>new</STRONG> keyword in the code should have the
 | 
			
		||||
			form:</P>
 | 
			
		||||
		<PRE>shared_ptr<T> p(new Y);</PRE>
 | 
			
		||||
		<P>It is, of course, acceptable to use another smart pointer in place of <STRONG>shared_ptr</STRONG>
 | 
			
		||||
			above; having <STRONG>T</STRONG> and <STRONG>Y</STRONG> be the same type, or 
 | 
			
		||||
			above; having <STRONG>T</STRONG> and <STRONG>Y</STRONG> be the same type, or
 | 
			
		||||
			passing arguments to <STRONG>Y</STRONG>'s constructor is also OK.</P>
 | 
			
		||||
		<P>If you observe this guideline, it naturally follows that you will have no 
 | 
			
		||||
			explicit <STRONG>delete</STRONG>s; <STRONG>try/catch</STRONG> constructs will 
 | 
			
		||||
		<P>If you observe this guideline, it naturally follows that you will have no
 | 
			
		||||
			explicit <STRONG>delete</STRONG>s; <STRONG>try/catch</STRONG> constructs will
 | 
			
		||||
			be rare.</P>
 | 
			
		||||
		<P>Avoid using unnamed <STRONG>shared_ptr</STRONG> temporaries to save typing; to 
 | 
			
		||||
		<P>Avoid using unnamed <STRONG>shared_ptr</STRONG> temporaries to save typing; to
 | 
			
		||||
			see why this is dangerous, consider this example:</P>
 | 
			
		||||
		<PRE>void f(shared_ptr<int>, int);
 | 
			
		||||
int g();
 | 
			
		||||
@@ -83,13 +83,18 @@ void bad()
 | 
			
		||||
}
 | 
			
		||||
</PRE>
 | 
			
		||||
		<P>The function <STRONG>ok</STRONG> follows the guideline to the letter, whereas <STRONG>
 | 
			
		||||
				bad</STRONG> constructs the temporary <STRONG>shared_ptr</STRONG> in place, 
 | 
			
		||||
			admitting the possibility of a memory leak. Since function arguments are 
 | 
			
		||||
			evaluated in unspecified order, it is possible for <STRONG>new int(2)</STRONG> to 
 | 
			
		||||
				bad</STRONG> constructs the temporary <STRONG>shared_ptr</STRONG> in place,
 | 
			
		||||
			admitting the possibility of a memory leak. Since function arguments are
 | 
			
		||||
			evaluated in unspecified order, it is possible for <STRONG>new int(2)</STRONG> to
 | 
			
		||||
			be evaluated first, <STRONG>g()</STRONG> second, and we may never get to the <STRONG>
 | 
			
		||||
				shared_ptr </STRONG>constructor if <STRONG>g</STRONG> throws an exception. 
 | 
			
		||||
				shared_ptr </STRONG>constructor if <STRONG>g</STRONG> throws an exception.
 | 
			
		||||
			See <A href="http://www.gotw.ca/gotw/056.htm">Herb Sutter's treatment</A> (also <A href="http://www.cuj.com/reference/articles/2002/0212/0212_sutter.htm">
 | 
			
		||||
				here</A>) of the issue for more information.</P>
 | 
			
		||||
		<P>The exception safety problem described above may also be eliminated by using
 | 
			
		||||
			the <a href="make_shared.html"><code>make_shared</code></a>
 | 
			
		||||
			or <a href="make_shared.html"><code>allocate_shared</code></a>
 | 
			
		||||
			factory functions defined in boost/make_shared.hpp.  These factory functions also provide
 | 
			
		||||
			an efficiency benefit by consolidating allocations.<P>
 | 
			
		||||
		<h2><a name="Synopsis">Synopsis</a></h2>
 | 
			
		||||
		<pre>namespace boost {
 | 
			
		||||
 | 
			
		||||
@@ -111,10 +116,11 @@ void bad()
 | 
			
		||||
 | 
			
		||||
      <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);
 | 
			
		||||
 | 
			
		||||
      shared_ptr & <A href="#assignment" >operator=</A>(shared_ptr const & r); // never throws  
 | 
			
		||||
      shared_ptr & <A href="#assignment" >operator=</A>(shared_ptr const & r); // never throws
 | 
			
		||||
      template<class Y> shared_ptr & <A href="#assignment" >operator=</A>(shared_ptr<Y> const & r); // never throws
 | 
			
		||||
      template<class Y> shared_ptr & <A href="#assignment" >operator=</A>(std::auto_ptr<Y> & r);
 | 
			
		||||
 | 
			
		||||
@@ -122,6 +128,7 @@ void bad()
 | 
			
		||||
      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
 | 
			
		||||
@@ -176,32 +183,32 @@ void bad()
 | 
			
		||||
			<p><b>Postconditions:</b> <code>use_count() == 0 && 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 
 | 
			
		||||
		<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>
 | 
			
		||||
		<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>
 | 
			
		||||
				must be a complete type. The expression <code>delete p</code> must be 
 | 
			
		||||
				must be a complete type. The expression <code>delete p</code> must be
 | 
			
		||||
				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 <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 
 | 
			
		||||
			<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>Exception safety:</b> If an exception is thrown, <code>delete p</code> is 
 | 
			
		||||
			<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 
 | 
			
		||||
			<P><STRONG>Notes:</STRONG> <B>p</B> must be a pointer to an object that was
 | 
			
		||||
				allocated via a C++ <B>new</B> expression or be 0. The postcondition that <A href="#use_count">
 | 
			
		||||
					use count</A> is 1 holds even if <b>p</b> is 0; invoking <STRONG>delete</STRONG>
 | 
			
		||||
				on a pointer that has a value of 0 is harmless.</P>
 | 
			
		||||
		</blockquote>
 | 
			
		||||
		<P><EM>[This constructor has been changed to a template in order to remember the actual 
 | 
			
		||||
				pointer type passed. The destructor will call <STRONG>delete</STRONG> with the 
 | 
			
		||||
				same pointer, complete with its original type, even when <STRONG>T</STRONG> does 
 | 
			
		||||
		<P><EM>[This constructor has been changed to a template in order to remember the actual
 | 
			
		||||
				pointer type passed. The destructor will call <STRONG>delete</STRONG> with the
 | 
			
		||||
				same pointer, complete with its original type, even when <STRONG>T</STRONG> does
 | 
			
		||||
				not have a virtual destructor, or is <STRONG>void</STRONG>.</EM></P>
 | 
			
		||||
		<P><EM>The optional intrusive counting support has been dropped as it exposes too much 
 | 
			
		||||
				implementation details and doesn't interact well with <STRONG>weak_ptr</STRONG>. 
 | 
			
		||||
		<P><EM>The optional intrusive counting support has been dropped as it exposes too much
 | 
			
		||||
				implementation details and doesn't interact well with <STRONG>weak_ptr</STRONG>.
 | 
			
		||||
				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>
 | 
			
		||||
@@ -210,70 +217,77 @@ void bad()
 | 
			
		||||
template<class Y, class D, class A> shared_ptr(Y * p, D d, A a);</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 
 | 
			
		||||
				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 
 | 
			
		||||
					A</STRONG> must be an <EM>Allocator</EM>, as described in section 20.1.5 (<STRONG>Allocator
 | 
			
		||||
					requirements</STRONG>) of the C++ Standard.
 | 
			
		||||
			</p>
 | 
			
		||||
			<p><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 
 | 
			
		||||
					p</STRONG> and the deleter <b>d</b>. The second constructor allocates
 | 
			
		||||
				memory using a copy of <STRONG>a</STRONG>.</p>
 | 
			
		||||
			<p><b>Postconditions:</b> <code>use_count() == 1 && get() == p</code>.</p>
 | 
			
		||||
			<p><b>Throws:</b> <STRONG>std::bad_alloc</STRONG>, or an implementation-defined 
 | 
			
		||||
			<p><b>Throws:</b> <STRONG>std::bad_alloc</STRONG>, or an implementation-defined
 | 
			
		||||
				exception when a resource other than memory could not be obtained.</p>
 | 
			
		||||
			<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>, 
 | 
			
		||||
			<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>
 | 
			
		||||
				as an argument.</p>
 | 
			
		||||
		</blockquote>
 | 
			
		||||
		<P><EM>[Custom deallocators allow a factory function returning a <STRONG>shared_ptr</STRONG>
 | 
			
		||||
				to insulate the user from its memory allocation strategy. Since the deallocator 
 | 
			
		||||
				is not part of the type, changing the allocation strategy does not break source 
 | 
			
		||||
				or binary compatibility, and does not require a client recompilation. For 
 | 
			
		||||
				to insulate the user from its memory allocation strategy. Since the deallocator
 | 
			
		||||
				is not part of the type, changing the allocation strategy does not break source
 | 
			
		||||
				or binary compatibility, and does not require a client recompilation. For
 | 
			
		||||
				example, a "no-op" deallocator is useful when returning a <STRONG>shared_ptr</STRONG>
 | 
			
		||||
				to a statically allocated object, and other variations allow a <STRONG>shared_ptr</STRONG>
 | 
			
		||||
				to be used as a wrapper for another smart pointer, easing interoperability.</EM></P>
 | 
			
		||||
		<P><EM>The support for custom deallocators does not impose significant overhead. Other <STRONG>
 | 
			
		||||
					shared_ptr</STRONG> features still require a deallocator to be kept.</EM></P>
 | 
			
		||||
		<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. 
 | 
			
		||||
		<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 
 | 
			
		||||
		<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">
 | 
			
		||||
					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>
 | 
			
		||||
		<blockquote>
 | 
			
		||||
			<p><b>Effects:</b> If <b>r</b> is <EM>empty</EM>, constructs an <EM>empty</EM> <b>shared_ptr</b>; 
 | 
			
		||||
			<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>.</p>
 | 
			
		||||
			<p><b>Postconditions:</b> <code>get() == r.get() && use_count() == 
 | 
			
		||||
			<p><b>Postconditions:</b> <code>get() == r.get() && use_count() ==
 | 
			
		||||
					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>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 
 | 
			
		||||
			<p><b>Exception safety:</b> If an exception is thrown, the constructor has no
 | 
			
		||||
				effect.</p>
 | 
			
		||||
		</blockquote>
 | 
			
		||||
		<pre>template<class Y> shared_ptr(std::auto_ptr<Y> & r);</pre>
 | 
			
		||||
		<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 
 | 
			
		||||
			<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>Exception safety:</B> If an exception is thrown, the constructor has no 
 | 
			
		||||
			<P><B>Exception safety:</B> If an exception is thrown, the constructor has no
 | 
			
		||||
				effect.</P>
 | 
			
		||||
		</BLOCKQUOTE>
 | 
			
		||||
		<P><EM>[This constructor takes a the source <STRONG>auto_ptr</STRONG> by reference and 
 | 
			
		||||
				not by value, and cannot accept <STRONG>auto_ptr</STRONG> temporaries. This is 
 | 
			
		||||
				by design, as the constructor offers the strong guarantee; an rvalue reference 
 | 
			
		||||
		<P><EM>[This constructor takes a the source <STRONG>auto_ptr</STRONG> by reference and
 | 
			
		||||
				not by value, and cannot accept <STRONG>auto_ptr</STRONG> temporaries. This is
 | 
			
		||||
				by design, as the constructor offers the strong guarantee; an rvalue reference
 | 
			
		||||
				would solve this problem, too.]</EM></P>
 | 
			
		||||
		<h3><a name="destructor">destructor</a></h3>
 | 
			
		||||
		<pre>~shared_ptr(); // never throws</pre>
 | 
			
		||||
@@ -281,15 +295,15 @@ template<class Y> shared_ptr(shared_ptr<Y> const & r); // never
 | 
			
		||||
			<P><B>Effects:</B></P>
 | 
			
		||||
			<UL>
 | 
			
		||||
				<LI>
 | 
			
		||||
					If <STRONG>*this</STRONG> is <EM>empty</EM>, or <EM>shares ownership</EM> with 
 | 
			
		||||
					another <STRONG>shared_ptr</STRONG> instance (<code>use_count() > 1</code>), 
 | 
			
		||||
					If <STRONG>*this</STRONG> is <EM>empty</EM>, or <EM>shares ownership</EM> with
 | 
			
		||||
					another <STRONG>shared_ptr</STRONG> instance (<code>use_count() > 1</code>),
 | 
			
		||||
				there are no side effects.
 | 
			
		||||
				<LI>
 | 
			
		||||
					Otherwise, if <STRONG>*this</STRONG> <EM>owns</EM> a pointer <STRONG>p</STRONG> 
 | 
			
		||||
					Otherwise, if <STRONG>*this</STRONG> <EM>owns</EM> a pointer <STRONG>p</STRONG>
 | 
			
		||||
					and a deleter <STRONG>d</STRONG>, <code>d(p)</code>
 | 
			
		||||
				is called.
 | 
			
		||||
				<LI>
 | 
			
		||||
					Otherwise, <STRONG>*this</STRONG> <EM>owns</EM> a pointer <STRONG>p</STRONG>, 
 | 
			
		||||
					Otherwise, <STRONG>*this</STRONG> <EM>owns</EM> a pointer <STRONG>p</STRONG>,
 | 
			
		||||
					and <code>delete p</code> is called.</LI></UL>
 | 
			
		||||
			<P><B>Throws:</B> nothing.</P>
 | 
			
		||||
		</BLOCKQUOTE>
 | 
			
		||||
@@ -300,9 +314,9 @@ template<class Y> shared_ptr & operator=(std::auto_ptr<Y> &
 | 
			
		||||
		<BLOCKQUOTE>
 | 
			
		||||
			<P><B>Effects:</B> Equivalent to <code>shared_ptr(r).swap(*this)</code>.</P>
 | 
			
		||||
			<P><B>Returns:</B> <code>*this</code>.</P>
 | 
			
		||||
			<P><B>Notes:</B> The use count updates caused by the temporary object construction 
 | 
			
		||||
				and destruction are not considered observable side effects, and the 
 | 
			
		||||
				implementation is free to meet the effects (and the implied guarantees) via 
 | 
			
		||||
			<P><B>Notes:</B> The use count updates caused by the temporary object construction
 | 
			
		||||
				and destruction are not considered observable side effects, and the
 | 
			
		||||
				implementation is free to meet the effects (and the implied guarantees) via
 | 
			
		||||
				different means, without creating a temporary. In particular, in the example:</P>
 | 
			
		||||
			<pre>shared_ptr<int> p(new int);
 | 
			
		||||
shared_ptr<void> q(p);
 | 
			
		||||
@@ -328,6 +342,10 @@ q = p;
 | 
			
		||||
		<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>
 | 
			
		||||
@@ -352,32 +370,32 @@ q = p;
 | 
			
		||||
		<blockquote>
 | 
			
		||||
			<p><b>Returns:</b> <code>use_count() == 1</code>.</p>
 | 
			
		||||
			<p><b>Throws:</b> nothing.</p>
 | 
			
		||||
			<P><B>Notes:</B> <code>unique()</code> may be faster than <code>use_count()</code>. 
 | 
			
		||||
				If you are using <code>unique()</code> to implement copy on write, do not rely 
 | 
			
		||||
			<P><B>Notes:</B> <code>unique()</code> may be faster than <code>use_count()</code>.
 | 
			
		||||
				If you are using <code>unique()</code> to implement copy on write, do not rely
 | 
			
		||||
				on a specific value when the stored pointer is zero.</P>
 | 
			
		||||
		</blockquote>
 | 
			
		||||
		<h3><a name="use_count">use_count</a></h3>
 | 
			
		||||
		<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 an unspecified nonnegative 
 | 
			
		||||
				value when <STRONG>*this</STRONG> is <EM>empty</EM>.</p>
 | 
			
		||||
			<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>
 | 
			
		||||
			<p><b>Throws:</b> nothing.</p>
 | 
			
		||||
			<P><B>Notes:</B> <code>use_count()</code> is not necessarily efficient. Use only 
 | 
			
		||||
			<P><B>Notes:</B> <code>use_count()</code> is not necessarily efficient. Use only
 | 
			
		||||
				for debugging and testing purposes, not for production code.</P>
 | 
			
		||||
		</blockquote>
 | 
			
		||||
		<h3><a name="conversions">conversions</a></h3>
 | 
			
		||||
		<pre>operator <i>unspecified-bool-type</i> () const; // never throws</pre>
 | 
			
		||||
		<blockquote>
 | 
			
		||||
			<p><b>Returns:</b> an unspecified value that, when used in boolean contexts, is 
 | 
			
		||||
			<p><b>Returns:</b> an unspecified value that, when used in boolean contexts, is
 | 
			
		||||
				equivalent to <code>get() != 0</code>.</p>
 | 
			
		||||
			<p><b>Throws:</b> nothing.</p>
 | 
			
		||||
			<P><B>Notes:</B> This conversion operator allows <b>shared_ptr</b> objects to be 
 | 
			
		||||
				used in boolean contexts, like <code>if (p && p->valid()) {}</code>. 
 | 
			
		||||
				The actual target type is typically a pointer to a member function, avoiding 
 | 
			
		||||
			<P><B>Notes:</B> This conversion operator allows <b>shared_ptr</b> objects to be
 | 
			
		||||
				used in boolean contexts, like <code>if (p && p->valid()) {}</code>.
 | 
			
		||||
				The actual target type is typically a pointer to a member function, avoiding
 | 
			
		||||
				many of the implicit conversion pitfalls.</P>
 | 
			
		||||
		</blockquote>
 | 
			
		||||
		<P><EM>[The conversion to bool is not merely syntactic sugar. It allows <STRONG>shared_ptr</STRONG>s 
 | 
			
		||||
		<P><EM>[The conversion to bool is not merely syntactic sugar. It allows <STRONG>shared_ptr</STRONG>s
 | 
			
		||||
				to be declared in conditions when using <A href="#dynamic_pointer_cast">dynamic_pointer_cast</A>
 | 
			
		||||
				or <A href="weak_ptr.htm#lock">weak_ptr::lock</A>.]</EM></P>
 | 
			
		||||
		<h3><a name="swap">swap</a></h3>
 | 
			
		||||
@@ -409,19 +427,19 @@ q = p;
 | 
			
		||||
					<b>operator<</b> is a strict weak ordering as described in section 25.3 <code>[lib.alg.sorting]</code>
 | 
			
		||||
				of the C++ standard;
 | 
			
		||||
				<LI>
 | 
			
		||||
					under the equivalence relation defined by <STRONG>operator<</STRONG>, <code>!(a 
 | 
			
		||||
						< b) && !(b < a)</code>, two <STRONG>shared_ptr</STRONG> instances 
 | 
			
		||||
					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>
 | 
			
		||||
			<p><b>Throws:</b> nothing.</p>
 | 
			
		||||
			<P><B>Notes:</B> Allows <STRONG>shared_ptr</STRONG> objects to be used as keys in 
 | 
			
		||||
			<P><B>Notes:</B> Allows <STRONG>shared_ptr</STRONG> objects to be used as keys in
 | 
			
		||||
				associative containers.</P>
 | 
			
		||||
		</blockquote>
 | 
			
		||||
		<P><EM>[<STRONG>Operator<</STRONG> has been preferred over a <STRONG>std::less </STRONG>
 | 
			
		||||
				specialization for consistency and legality reasons, as <STRONG>std::less</STRONG>
 | 
			
		||||
				is required to return the results of <STRONG>operator<</STRONG>, and many 
 | 
			
		||||
				is required to return the results of <STRONG>operator<</STRONG>, and many
 | 
			
		||||
				standard algorithms use <STRONG>operator<</STRONG> instead of <STRONG>std::less</STRONG>
 | 
			
		||||
				for comparisons when a predicate is not supplied. Composite objects, like <STRONG>std::pair</STRONG>, 
 | 
			
		||||
				also implement their <STRONG>operator<</STRONG> in terms of their contained 
 | 
			
		||||
				for comparisons when a predicate is not supplied. Composite objects, like <STRONG>std::pair</STRONG>,
 | 
			
		||||
				also implement their <STRONG>operator<</STRONG> in terms of their contained
 | 
			
		||||
				subobjects' <STRONG>operator<</STRONG>.</EM></P>
 | 
			
		||||
		<P><EM>The rest of the comparison operators are omitted by design.]</EM></P>
 | 
			
		||||
		<h3><a name="free-swap">swap</a></h3>
 | 
			
		||||
@@ -430,11 +448,11 @@ q = p;
 | 
			
		||||
		<BLOCKQUOTE>
 | 
			
		||||
			<P><B>Effects:</B> Equivalent to <code>a.swap(b)</code>.</P>
 | 
			
		||||
			<P><B>Throws:</B> nothing.</P>
 | 
			
		||||
			<P><B>Notes:</B> Matches the interface of <B>std::swap</B>. Provided as an aid to 
 | 
			
		||||
			<P><B>Notes:</B> Matches the interface of <B>std::swap</B>. Provided as an aid to
 | 
			
		||||
				generic programming.</P>
 | 
			
		||||
		</BLOCKQUOTE>
 | 
			
		||||
		<P><EM>[<STRONG>swap</STRONG> is defined in the same namespace as <STRONG>shared_ptr</STRONG>
 | 
			
		||||
				as this is currently the only legal way to supply a <STRONG>swap</STRONG> function 
 | 
			
		||||
				as this is currently the only legal way to supply a <STRONG>swap</STRONG> function
 | 
			
		||||
				that has a chance to be used by the standard library.]</EM></P>
 | 
			
		||||
		<h3><a name="get_pointer">get_pointer</a></h3>
 | 
			
		||||
		<pre>template<class T>
 | 
			
		||||
@@ -451,13 +469,13 @@ q = p;
 | 
			
		||||
		<BLOCKQUOTE>
 | 
			
		||||
			<P><STRONG>Requires:</STRONG> The expression <code>static_cast<T*>(r.get())</code>
 | 
			
		||||
				must be well-formed.</P>
 | 
			
		||||
			<P><B>Returns:</B> If <b>r</b> is <i>empty</i>, an <i>empty</i> <b>shared_ptr<T></b>; 
 | 
			
		||||
			<P><B>Returns:</B> If <b>r</b> is <i>empty</i>, an <i>empty</i> <b>shared_ptr<T></b>;
 | 
			
		||||
				otherwise, a <STRONG>shared_ptr<T></STRONG> object that stores a copy of <code>
 | 
			
		||||
					static_cast<T*>(r.get())</code> and <i>shares ownership</i> with <b>r</b>.</P>
 | 
			
		||||
			<P><B>Throws:</B> nothing.</P>
 | 
			
		||||
			<P><B>Notes:</B> the seemingly equivalent expression</P>
 | 
			
		||||
			<p><code>shared_ptr<T>(static_cast<T*>(r.get()))</code></p>
 | 
			
		||||
			<p>will eventually result in undefined behavior, attempting to delete the same 
 | 
			
		||||
			<p>will eventually result in undefined behavior, attempting to delete the same
 | 
			
		||||
				object twice.</p>
 | 
			
		||||
		</BLOCKQUOTE>
 | 
			
		||||
		<h3><a name="const_pointer_cast">const_pointer_cast</a></h3>
 | 
			
		||||
@@ -466,13 +484,13 @@ q = p;
 | 
			
		||||
		<BLOCKQUOTE>
 | 
			
		||||
			<P><STRONG>Requires:</STRONG> The expression <code>const_cast<T*>(r.get())</code>
 | 
			
		||||
				must be well-formed.</P>
 | 
			
		||||
			<P><B>Returns:</B> If <b>r</b> is <i>empty</i>, an <i>empty</i> <b>shared_ptr<T></b>; 
 | 
			
		||||
			<P><B>Returns:</B> If <b>r</b> is <i>empty</i>, an <i>empty</i> <b>shared_ptr<T></b>;
 | 
			
		||||
				otherwise, a <STRONG>shared_ptr<T></STRONG> object that stores a copy of <code>
 | 
			
		||||
					const_cast<T*>(r.get())</code> and <i>shares ownership</i> with <b>r</b>.</P>
 | 
			
		||||
			<P><B>Throws:</B> nothing.</P>
 | 
			
		||||
			<P><B>Notes:</B> the seemingly equivalent expression</P>
 | 
			
		||||
			<p><code>shared_ptr<T>(const_cast<T*>(r.get()))</code></p>
 | 
			
		||||
			<p>will eventually result in undefined behavior, attempting to delete the same 
 | 
			
		||||
			<p>will eventually result in undefined behavior, attempting to delete the same
 | 
			
		||||
				object twice.</p>
 | 
			
		||||
		</BLOCKQUOTE>
 | 
			
		||||
		<h3><a name="dynamic_pointer_cast">dynamic_pointer_cast</a></h3>
 | 
			
		||||
@@ -485,14 +503,14 @@ q = p;
 | 
			
		||||
			<UL>
 | 
			
		||||
				<LI>
 | 
			
		||||
					When <CODE>dynamic_cast<T*>(r.get())</CODE> returns a nonzero value, a <STRONG>
 | 
			
		||||
						shared_ptr<T></STRONG> object that stores a copy of it and <i>shares 
 | 
			
		||||
						shared_ptr<T></STRONG> object that stores a copy of it and <i>shares
 | 
			
		||||
						ownership</i> with <STRONG>r</STRONG>;
 | 
			
		||||
				<LI>
 | 
			
		||||
					Otherwise, an <i>empty</i> <STRONG>shared_ptr<T></STRONG> object.</LI></UL>
 | 
			
		||||
			<P><B>Throws:</B> nothing.</P>
 | 
			
		||||
			<P><B>Notes:</B> the seemingly equivalent expression</P>
 | 
			
		||||
			<P><CODE>shared_ptr<T>(dynamic_cast<T*>(r.get()))</CODE></P>
 | 
			
		||||
			<P>will eventually result in undefined behavior, attempting to delete the same 
 | 
			
		||||
			<P>will eventually result in undefined behavior, attempting to delete the same
 | 
			
		||||
				object twice.</P>
 | 
			
		||||
		</BLOCKQUOTE>
 | 
			
		||||
		<h3><a name="insertion-operator">operator<<</a></h3>
 | 
			
		||||
@@ -507,40 +525,41 @@ q = p;
 | 
			
		||||
    D * get_deleter(shared_ptr<T> const & p);</pre>
 | 
			
		||||
		<BLOCKQUOTE>
 | 
			
		||||
			<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>; 
 | 
			
		||||
				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 
 | 
			
		||||
		<p>See <A href="example/shared_ptr_example.cpp">shared_ptr_example.cpp</A> for a
 | 
			
		||||
			complete example program. The program builds a <b>std::vector</b> and <b>std::set</b>
 | 
			
		||||
			of <b>shared_ptr</b> objects.</p>
 | 
			
		||||
		<p>Note that after the containers have been populated, some of the <b>shared_ptr</b>
 | 
			
		||||
			objects will have a use count of 1 rather than a use count of 2, since the set 
 | 
			
		||||
			is a <b>std::set</b> rather than a <b>std::multiset</b>, and thus does not 
 | 
			
		||||
			contain duplicate entries. Furthermore, the use count may be even higher at 
 | 
			
		||||
			various times while <b>push_back</b> and <b>insert</b> container operations are 
 | 
			
		||||
			performed. More complicated yet, the container operations may throw exceptions 
 | 
			
		||||
			under a variety of circumstances. Getting the memory management and exception 
 | 
			
		||||
			objects will have a use count of 1 rather than a use count of 2, since the set
 | 
			
		||||
			is a <b>std::set</b> rather than a <b>std::multiset</b>, and thus does not
 | 
			
		||||
			contain duplicate entries. Furthermore, the use count may be even higher at
 | 
			
		||||
			various times while <b>push_back</b> and <b>insert</b> container operations are
 | 
			
		||||
			performed. More complicated yet, the container operations may throw exceptions
 | 
			
		||||
			under a variety of circumstances. Getting the memory management and exception
 | 
			
		||||
			handling in this example right without a smart pointer would be a nightmare.</p>
 | 
			
		||||
		<h2><a name="Handle/Body">Handle/Body</a> Idiom</h2>
 | 
			
		||||
		<p>One common usage of <b>shared_ptr</b> is to implement a handle/body (also called 
 | 
			
		||||
			pimpl) idiom which avoids exposing the body (implementation) in the header 
 | 
			
		||||
		<p>One common usage of <b>shared_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/shared_ptr_example2_test.cpp">shared_ptr_example2_test.cpp</A>
 | 
			
		||||
			sample program includes a header file, <A href="example/shared_ptr_example2.hpp">shared_ptr_example2.hpp</A>, 
 | 
			
		||||
			which uses a <b>shared_ptr<></b> to an incomplete type to hide the 
 | 
			
		||||
			implementation. The instantiation of member functions which require a complete 
 | 
			
		||||
			sample program includes a header file, <A href="example/shared_ptr_example2.hpp">shared_ptr_example2.hpp</A>,
 | 
			
		||||
			which uses a <b>shared_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/shared_ptr_example2.cpp">shared_ptr_example2.cpp</A>
 | 
			
		||||
			implementation file. Note that there is no need for an explicit destructor. 
 | 
			
		||||
			Unlike ~scoped_ptr, ~shared_ptr does not require that <b>T</b> be a complete 
 | 
			
		||||
			implementation file. Note that there is no need for an explicit destructor.
 | 
			
		||||
			Unlike ~scoped_ptr, ~shared_ptr does not require that <b>T</b> be a complete
 | 
			
		||||
			type.</p>
 | 
			
		||||
		<h2><a name="ThreadSafety">Thread Safety</a></h2>
 | 
			
		||||
		<p><STRONG>shared_ptr</STRONG> objects offer the same level of thread safety as 
 | 
			
		||||
			built-in types. A <STRONG>shared_ptr</STRONG> instance can be "read" (accessed 
 | 
			
		||||
		<p><STRONG>shared_ptr</STRONG> objects offer the same level of thread safety as
 | 
			
		||||
			built-in types. A <STRONG>shared_ptr</STRONG> instance can be "read" (accessed
 | 
			
		||||
			using only const operations) simultaneously by multiple threads. Different <STRONG>shared_ptr</STRONG>
 | 
			
		||||
			instances can be "written to" (accessed using mutable operations such as <STRONG>operator=
 | 
			
		||||
			</STRONG>or <STRONG>reset</STRONG>) simultaneosly by multiple threads (even 
 | 
			
		||||
			when these instances are copies, and share the same reference count 
 | 
			
		||||
			</STRONG>or <STRONG>reset</STRONG>) simultaneosly by multiple threads (even
 | 
			
		||||
			when these instances are copies, and share the same reference count
 | 
			
		||||
			underneath.)</p>
 | 
			
		||||
		<P>Any other simultaneous accesses result in undefined behavior.</P>
 | 
			
		||||
		<P>Examples:</P>
 | 
			
		||||
@@ -587,7 +606,7 @@ p3.reset(new int(1));
 | 
			
		||||
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 
 | 
			
		||||
		<P>Starting with Boost release 1.33.0, <STRONG>shared_ptr</STRONG> uses a lock-free
 | 
			
		||||
			implementation on the following platforms:</P>
 | 
			
		||||
		<UL>
 | 
			
		||||
			<LI>
 | 
			
		||||
@@ -600,75 +619,75 @@ p3.reset(new int(2)); // undefined, multiple writes
 | 
			
		||||
			GNU GCC on PowerPC;
 | 
			
		||||
			<LI>
 | 
			
		||||
				Windows.</LI></UL>
 | 
			
		||||
		<P>If your program is single-threaded and does not link to any libraries that might 
 | 
			
		||||
		<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 
 | 
			
		||||
				#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. 
 | 
			
		||||
		<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 
 | 
			
		||||
		<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>
 | 
			
		||||
		<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 
 | 
			
		||||
			implementation? It would be useful to be able to experiment with each type so 
 | 
			
		||||
		<P><B>Q.</B> There are several variations of shared pointers, with different
 | 
			
		||||
			tradeoffs; why does the smart pointer library supply only a single
 | 
			
		||||
			implementation? It would be useful to be able to experiment with each type so
 | 
			
		||||
			as to find the most suitable for the job at hand?</P>
 | 
			
		||||
		<P>
 | 
			
		||||
			<b>A.</b> An important goal of <STRONG>shared_ptr</STRONG> is to provide a 
 | 
			
		||||
			standard shared-ownership pointer. Having a single pointer type is important 
 | 
			
		||||
			for stable library interfaces, since different shared pointers typically cannot 
 | 
			
		||||
			interoperate, i.e. a reference counted pointer (used by library A) cannot share 
 | 
			
		||||
			<b>A.</b> An important goal of <STRONG>shared_ptr</STRONG> is to provide a
 | 
			
		||||
			standard shared-ownership pointer. Having a single pointer type is important
 | 
			
		||||
			for stable library interfaces, since different shared pointers typically cannot
 | 
			
		||||
			interoperate, i.e. a reference counted pointer (used by library A) cannot share
 | 
			
		||||
			ownership with a linked pointer (used by library B.)<BR>
 | 
			
		||||
		</P>
 | 
			
		||||
		<P><B>Q.</B> Why doesn't <B>shared_ptr</B> have template parameters supplying 
 | 
			
		||||
		<P><B>Q.</B> Why doesn't <B>shared_ptr</B> have template parameters supplying
 | 
			
		||||
			traits or policies to allow extensive user customization?</P>
 | 
			
		||||
		<P>
 | 
			
		||||
			<B>A.</B> Parameterization discourages users. The <B>shared_ptr</B> template is 
 | 
			
		||||
			carefully crafted to meet common needs without extensive parameterization. Some 
 | 
			
		||||
			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 
 | 
			
		||||
			<B>A.</B> Parameterization discourages users. The <B>shared_ptr</B> template is
 | 
			
		||||
			carefully crafted to meet common needs without extensive parameterization. Some
 | 
			
		||||
			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">
 | 
			
		||||
				Modern C++ Design</A> by Andrei Alexandrescu.)<BR>
 | 
			
		||||
		</P>
 | 
			
		||||
		<P><B>Q.</B> I am not convinced. Default parameters can be used where appropriate 
 | 
			
		||||
		<P><B>Q.</B> I am not convinced. Default parameters can be used where appropriate
 | 
			
		||||
			to hide the complexity. Again, why not policies?</P>
 | 
			
		||||
		<P>
 | 
			
		||||
			<B>A.</B> Template parameters affect the type. See the answer to the first 
 | 
			
		||||
			<B>A.</B> Template parameters affect the type. See the answer to the first
 | 
			
		||||
			question above.<BR>
 | 
			
		||||
		</P>
 | 
			
		||||
		<P><B>Q.</B> Why doesn't <b>shared_ptr</b> use a linked list implementation?</P>
 | 
			
		||||
		<P>
 | 
			
		||||
			<b>A.</b> A linked list implementation does not offer enough advantages to 
 | 
			
		||||
			<b>A.</b> A linked list implementation does not offer enough advantages to
 | 
			
		||||
			offset the added cost of an extra pointer. See <A href="smarttests.htm">timings</A>
 | 
			
		||||
			page. In addition, it is expensive to make a linked list implementation thread 
 | 
			
		||||
			page. In addition, it is expensive to make a linked list implementation thread
 | 
			
		||||
			safe.<BR>
 | 
			
		||||
		</P>
 | 
			
		||||
		<P><b>Q.</b> Why doesn't <b>shared_ptr</b> (or any of the other Boost smart 
 | 
			
		||||
		<P><b>Q.</b> Why doesn't <b>shared_ptr</b> (or any of the other Boost smart
 | 
			
		||||
			pointers) supply an automatic conversion to <b>T*</b>?</P>
 | 
			
		||||
		<P>
 | 
			
		||||
			<b>A.</b> Automatic conversion is believed to be too error prone.<BR>
 | 
			
		||||
		</P>
 | 
			
		||||
		<P><B>Q.</B> Why does <b>shared_ptr</b> supply use_count()?</P>
 | 
			
		||||
		<P>
 | 
			
		||||
			<b>A.</b> As an aid to writing test cases and debugging displays. One of the 
 | 
			
		||||
			progenitors had use_count(), and it was useful in tracking down bugs in a 
 | 
			
		||||
			<b>A.</b> As an aid to writing test cases and debugging displays. One of the
 | 
			
		||||
			progenitors had use_count(), and it was useful in tracking down bugs in a
 | 
			
		||||
			complex project that turned out to have cyclic-dependencies.<BR>
 | 
			
		||||
		</P>
 | 
			
		||||
		<P><B>Q.</B> Why doesn't <b>shared_ptr</b> specify complexity requirements?</P>
 | 
			
		||||
		<P>
 | 
			
		||||
			<b>A.</b> Because complexity requirements limit implementors and complicate the 
 | 
			
		||||
			specification without apparent benefit to <b>shared_ptr</b> users. For example, 
 | 
			
		||||
			error-checking implementations might become non-conforming if they had to meet 
 | 
			
		||||
			<b>A.</b> Because complexity requirements limit implementors and complicate the
 | 
			
		||||
			specification without apparent benefit to <b>shared_ptr</b> users. For example,
 | 
			
		||||
			error-checking implementations might become non-conforming if they had to meet
 | 
			
		||||
			stringent complexity requirements.<BR>
 | 
			
		||||
		</P>
 | 
			
		||||
		<P><b>Q.</b> Why doesn't <b>shared_ptr</b> provide a release() function?</P>
 | 
			
		||||
		<P>
 | 
			
		||||
			<b>A.</b> <b>shared_ptr</b> cannot give away ownership unless it's unique() 
 | 
			
		||||
			<b>A.</b> <b>shared_ptr</b> cannot give away ownership unless it's unique()
 | 
			
		||||
			because the other copy will still destroy the object.</P>
 | 
			
		||||
		<p>Consider:</p>
 | 
			
		||||
		<blockquote><pre>shared_ptr<int> a(new int);
 | 
			
		||||
@@ -678,27 +697,26 @@ int * p = a.release();
 | 
			
		||||
 | 
			
		||||
// Who owns p now? b will still call delete on it in its destructor.</pre>
 | 
			
		||||
		</blockquote>
 | 
			
		||||
		<p>Furthermore, the pointer returned by <code>release()</code> would be difficult 
 | 
			
		||||
			to deallocate reliably, as the source <b>shared_ptr</b> could have been created 
 | 
			
		||||
		<p>Furthermore, the pointer returned by <code>release()</code> would be difficult
 | 
			
		||||
			to deallocate reliably, as the source <b>shared_ptr</b> could have been created
 | 
			
		||||
			with a custom deleter.<BR>
 | 
			
		||||
		</p>
 | 
			
		||||
		<P><b>Q.</b> Why is <code>operator->()</code> const, but its return value is a 
 | 
			
		||||
		<P><b>Q.</b> Why is <code>operator->()</code> const, but its return value is a
 | 
			
		||||
			non-const pointer to the element type?</P>
 | 
			
		||||
		<P>
 | 
			
		||||
			<b>A.</b> Shallow copy pointers, including raw pointers, typically don't 
 | 
			
		||||
			propagate constness. It makes little sense for them to do so, as you can always 
 | 
			
		||||
			obtain a non-const pointer from a const one and then proceed to modify the 
 | 
			
		||||
			object through it.<b>shared_ptr</b> is "as close to raw pointers as possible 
 | 
			
		||||
			<b>A.</b> Shallow copy pointers, including raw pointers, typically don't
 | 
			
		||||
			propagate constness. It makes little sense for them to do so, as you can always
 | 
			
		||||
			obtain a non-const pointer from a const one and then proceed to modify the
 | 
			
		||||
			object through it.<b>shared_ptr</b> is "as close to raw pointers as possible
 | 
			
		||||
			but no closer".<BR>
 | 
			
		||||
			<BR>
 | 
			
		||||
		</P>
 | 
			
		||||
		<hr>
 | 
			
		||||
		<p>
 | 
			
		||||
			$Date$</p>
 | 
			
		||||
		<p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. 
 | 
			
		||||
				Copyright 2002-2005 Peter Dimov. Permission to copy, use, modify, sell and 
 | 
			
		||||
				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>
 | 
			
		||||
		<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>
 | 
			
		||||
	</body>
 | 
			
		||||
</html>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										168
									
								
								smart_ptr.htm
									
									
									
									
									
								
							
							
						
						
									
										168
									
								
								smart_ptr.htm
									
									
									
									
									
								
							@@ -14,15 +14,15 @@
 | 
			
		||||
			<a href="#History">History and Acknowledgements</a><br>
 | 
			
		||||
			<a href="#References">References</a></p>
 | 
			
		||||
		<h2><a name="Introduction">Introduction</a></h2>
 | 
			
		||||
		<p>Smart pointers are objects which store pointers to dynamically allocated (heap) 
 | 
			
		||||
			objects. They behave much like built-in C++ pointers except that they 
 | 
			
		||||
			automatically delete the object pointed to at the appropriate time. Smart 
 | 
			
		||||
			pointers are particularly useful in the face of exceptions as they ensure 
 | 
			
		||||
			proper destruction of dynamically allocated objects. They can also be used to 
 | 
			
		||||
		<p>Smart pointers are objects which store pointers to dynamically allocated (heap)
 | 
			
		||||
			objects. They behave much like built-in C++ pointers except that they
 | 
			
		||||
			automatically delete the object pointed to at the appropriate time. Smart
 | 
			
		||||
			pointers are particularly useful in the face of exceptions as they ensure
 | 
			
		||||
			proper destruction of dynamically allocated objects. They can also be used to
 | 
			
		||||
			keep track of dynamically allocated objects shared by multiple owners.</p>
 | 
			
		||||
		<p>Conceptually, smart pointers are seen as owning the object pointed to, and thus 
 | 
			
		||||
		<p>Conceptually, smart pointers are seen as owning the object pointed to, and thus
 | 
			
		||||
			responsible for deletion of the object when it is no longer needed.</p>
 | 
			
		||||
		<p>The smart pointer library provides five smart pointer class templates:</p>
 | 
			
		||||
		<p>The smart pointer library provides six smart pointer class templates:</p>
 | 
			
		||||
		<div align="left">
 | 
			
		||||
			<table border="1" cellpadding="4" cellspacing="0">
 | 
			
		||||
				<tr>
 | 
			
		||||
@@ -38,7 +38,7 @@
 | 
			
		||||
				<tr>
 | 
			
		||||
					<td><a href="shared_ptr.htm"><b>shared_ptr</b></a></td>
 | 
			
		||||
					<td><a href="../../boost/shared_ptr.hpp"><boost/shared_ptr.hpp></a></td>
 | 
			
		||||
					<td>Object ownership shared among multiple pointers</td>
 | 
			
		||||
					<td>Object ownership shared among multiple pointers.</td>
 | 
			
		||||
				</tr>
 | 
			
		||||
				<tr>
 | 
			
		||||
					<td><a href="shared_array.htm"><b>shared_array</b></a></td>
 | 
			
		||||
@@ -58,129 +58,139 @@
 | 
			
		||||
			</table>
 | 
			
		||||
		</div>
 | 
			
		||||
		<p>These templates are designed to complement the <b>std::auto_ptr</b> template.</p>
 | 
			
		||||
		<p>They are examples of the "resource acquisition is initialization" idiom 
 | 
			
		||||
			described in Bjarne Stroustrup's "The C++ Programming Language", 3rd edition, 
 | 
			
		||||
		<p>They are examples of the "resource acquisition is initialization" idiom
 | 
			
		||||
			described in Bjarne Stroustrup's "The C++ Programming Language", 3rd edition,
 | 
			
		||||
			Section 14.4, Resource Management.</p>
 | 
			
		||||
		<p>A test program, <a href="test/smart_ptr_test.cpp">smart_ptr_test.cpp</a>, is 
 | 
			
		||||
		<p>Additionally, the smart pointer library provides efficient factory functions
 | 
			
		||||
			for creating <code>shared_ptr</code> objects:</p>
 | 
			
		||||
		<div align="left">
 | 
			
		||||
			<table border="1" cellpadding="4" cellspacing="0">
 | 
			
		||||
				<tr>
 | 
			
		||||
					<td><a href="make_shared.html"><b>make_shared and allocate_shared</b></a></td>
 | 
			
		||||
					<td><a href="../../boost/make_shared.hpp"><boost/make_shared.hpp></a></td>
 | 
			
		||||
					<td>Efficient creation of <code>shared_ptr</code> objects.</td>
 | 
			
		||||
				</tr>
 | 
			
		||||
			</table>
 | 
			
		||||
		</div>
 | 
			
		||||
		<p>A test program, <a href="test/smart_ptr_test.cpp">smart_ptr_test.cpp</a>, is
 | 
			
		||||
			provided to verify correct operation.</p>
 | 
			
		||||
		<p>A page on <a href="compatibility.htm">compatibility</a> with older versions of 
 | 
			
		||||
			the Boost smart pointer library describes some of the changes since earlier 
 | 
			
		||||
		<p>A page on <a href="compatibility.htm">compatibility</a> with older versions of
 | 
			
		||||
			the Boost smart pointer library describes some of the changes since earlier
 | 
			
		||||
			versions of the smart pointer implementation.</p>
 | 
			
		||||
		<p>A page on <a href="smarttests.htm">smart pointer timings</a> will be of interest 
 | 
			
		||||
		<p>A page on <a href="smarttests.htm">smart pointer timings</a> will be of interest
 | 
			
		||||
			to those curious about performance issues.</p>
 | 
			
		||||
		<P>A page on <A href="sp_techniques.html">smart pointer programming techniques</A> lists 
 | 
			
		||||
		<P>A page on <A href="sp_techniques.html">smart pointer programming techniques</A> lists
 | 
			
		||||
			some advanced applications of <code>shared_ptr</code> and <code>weak_ptr</code>.</P>
 | 
			
		||||
		<h2><a name="common_requirements">Common Requirements</a></h2>
 | 
			
		||||
		<p>These smart pointer class templates have a template parameter, <b>T</b>, which 
 | 
			
		||||
			specifies the type of the object pointed to by the smart pointer. The behavior 
 | 
			
		||||
		<p>These smart pointer class templates have a template parameter, <b>T</b>, which
 | 
			
		||||
			specifies the type of the object pointed to by the smart pointer. The behavior
 | 
			
		||||
			of the smart pointer templates is undefined if the destructor or <b>operator delete</b>
 | 
			
		||||
			for objects of type <b>T</b> throw exceptions.</p>
 | 
			
		||||
		<p><b>T</b> may be an incomplete type at the point of smart pointer declaration. 
 | 
			
		||||
			Unless otherwise specified, it is required that <b>T</b> be a complete type at 
 | 
			
		||||
			points of smart pointer instantiation. Implementations are required to diagnose 
 | 
			
		||||
			(treat as an error) all violations of this requirement, including deletion of 
 | 
			
		||||
		<p><b>T</b> may be an incomplete type at the point of smart pointer declaration.
 | 
			
		||||
			Unless otherwise specified, it is required that <b>T</b> be a complete type at
 | 
			
		||||
			points of smart pointer instantiation. Implementations are required to diagnose
 | 
			
		||||
			(treat as an error) all violations of this requirement, including deletion of
 | 
			
		||||
			an incomplete type. See the description of the <a href="../utility/utility.htm#checked_delete">
 | 
			
		||||
				<b>checked_delete</b></a> function template.</p>
 | 
			
		||||
		<P>Note that <STRONG>shared_ptr</STRONG> does not have this restriction, as most of 
 | 
			
		||||
		<P>Note that <STRONG>shared_ptr</STRONG> does not have this restriction, as most of
 | 
			
		||||
			its member functions do not require <STRONG>T</STRONG> to be a complete type.</P>
 | 
			
		||||
		<h3>Rationale</h3>
 | 
			
		||||
		<p>The requirements on <b>T</b> are carefully crafted to maximize safety yet allow 
 | 
			
		||||
			handle-body (also called pimpl) and similar idioms. In these idioms a smart 
 | 
			
		||||
			pointer may appear in translation units where <b>T</b> is an incomplete type. 
 | 
			
		||||
			This separates interface from implementation and hides implementation from 
 | 
			
		||||
			translation units which merely use the interface. Examples described in the 
 | 
			
		||||
			documentation for specific smart pointers illustrate use of smart pointers in 
 | 
			
		||||
		<p>The requirements on <b>T</b> are carefully crafted to maximize safety yet allow
 | 
			
		||||
			handle-body (also called pimpl) and similar idioms. In these idioms a smart
 | 
			
		||||
			pointer may appear in translation units where <b>T</b> is an incomplete type.
 | 
			
		||||
			This separates interface from implementation and hides implementation from
 | 
			
		||||
			translation units which merely use the interface. Examples described in the
 | 
			
		||||
			documentation for specific smart pointers illustrate use of smart pointers in
 | 
			
		||||
			these idioms.</p>
 | 
			
		||||
		<p>Note that <b>scoped_ptr</b> requires that <b>T</b> be a complete type at 
 | 
			
		||||
		<p>Note that <b>scoped_ptr</b> requires that <b>T</b> be a complete type at
 | 
			
		||||
			destruction time, but <b>shared_ptr</b> does not.</p>
 | 
			
		||||
		<h2><a name="Exception_Safety">Exception Safety</a></h2>
 | 
			
		||||
		<p>Several functions in these smart pointer classes are specified as having "no 
 | 
			
		||||
			effect" or "no effect except such-and-such" if an exception is thrown. This 
 | 
			
		||||
			means that when an exception is thrown by an object of one of these classes, 
 | 
			
		||||
			the entire program state remains the same as it was prior to the function call 
 | 
			
		||||
			which resulted in the exception being thrown. This amounts to a guarantee that 
 | 
			
		||||
			there are no detectable side effects. Other functions never throw exceptions. 
 | 
			
		||||
			The only exception ever thrown by functions which do throw (assuming <b>T</b> meets 
 | 
			
		||||
			the <a href="#common_requirements">common requirements</a>) is <b>std::bad_alloc</b>, 
 | 
			
		||||
			and that is thrown only by functions which are explicitly documented as 
 | 
			
		||||
		<p>Several functions in these smart pointer classes are specified as having "no
 | 
			
		||||
			effect" or "no effect except such-and-such" if an exception is thrown. This
 | 
			
		||||
			means that when an exception is thrown by an object of one of these classes,
 | 
			
		||||
			the entire program state remains the same as it was prior to the function call
 | 
			
		||||
			which resulted in the exception being thrown. This amounts to a guarantee that
 | 
			
		||||
			there are no detectable side effects. Other functions never throw exceptions.
 | 
			
		||||
			The only exception ever thrown by functions which do throw (assuming <b>T</b> meets
 | 
			
		||||
			the <a href="#common_requirements">common requirements</a>) is <b>std::bad_alloc</b>,
 | 
			
		||||
			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="../../more/lib_guide.htm#Exception-specification">
 | 
			
		||||
		<p>Exception-specifications are not used; see <a href="http://www.boost.org/more/lib_guide.htm#Exception-specification">
 | 
			
		||||
				exception-specification rationale</a>.</p>
 | 
			
		||||
		<p>All the smart pointer templates contain member functions which can never throw 
 | 
			
		||||
			exceptions, because they neither throw exceptions themselves nor call other 
 | 
			
		||||
		<p>All the smart pointer templates contain member functions which can never throw
 | 
			
		||||
			exceptions, because they neither throw exceptions themselves nor call other
 | 
			
		||||
			functions which may throw exceptions. These members are indicated by a comment: <code>
 | 
			
		||||
				// never throws</code>.
 | 
			
		||||
		</p>
 | 
			
		||||
		<p>Functions which destroy objects of the pointed to type are prohibited from 
 | 
			
		||||
		<p>Functions which destroy objects of the pointed to type are prohibited from
 | 
			
		||||
			throwing exceptions by the <a href="#common_requirements">common requirements</a>.</p>
 | 
			
		||||
		<h2><a name="History">History</a> and Acknowledgements</h2>
 | 
			
		||||
		<p>January 2002. Peter Dimov reworked all four classes, adding features, fixing 
 | 
			
		||||
			bugs, and splitting them into four separate headers, and added <b>weak_ptr</b>. 
 | 
			
		||||
			See the <a href="compatibility.htm">compatibility</a> page for a summary of the 
 | 
			
		||||
		<p>January 2002. Peter Dimov reworked all four classes, adding features, fixing
 | 
			
		||||
			bugs, and splitting them into four separate headers, and added <b>weak_ptr</b>.
 | 
			
		||||
			See the <a href="compatibility.htm">compatibility</a> page for a summary of the
 | 
			
		||||
			changes.</p>
 | 
			
		||||
		<p>May 2001. Vladimir Prus suggested requiring a complete type on destruction. 
 | 
			
		||||
			Refinement evolved in discussions including Dave Abrahams, Greg Colvin, Beman 
 | 
			
		||||
			Dawes, Rainer Deyke, Peter Dimov, John Maddock, Vladimir Prus, Shankar Sai, and 
 | 
			
		||||
		<p>May 2001. Vladimir Prus suggested requiring a complete type on destruction.
 | 
			
		||||
			Refinement evolved in discussions including Dave Abrahams, Greg Colvin, Beman
 | 
			
		||||
			Dawes, Rainer Deyke, Peter Dimov, John Maddock, Vladimir Prus, Shankar Sai, and
 | 
			
		||||
			others.</p>
 | 
			
		||||
		<p>November 1999. Darin Adler provided <b>operator ==</b>, <b>operator !=</b>, and <b>std::swap</b>
 | 
			
		||||
			and <b>std::less</b> specializations for shared types.</p>
 | 
			
		||||
		<p>September 1999. Luis Coelho provided <b>shared_ptr::swap</b> and <b>shared_array::swap</b></p>
 | 
			
		||||
		<p>May 1999. In April and May, 1999, Valentin Bonnard and David Abrahams made a 
 | 
			
		||||
		<p>May 1999. In April and May, 1999, Valentin Bonnard and David Abrahams made a
 | 
			
		||||
			number of suggestions resulting in numerous improvements.</p>
 | 
			
		||||
		<p>October 1998. Beman Dawes proposed reviving the original semantics under the 
 | 
			
		||||
			names <b>safe_ptr</b> and <b>counted_ptr</b>, meeting of Per Andersson, Matt 
 | 
			
		||||
			Austern, Greg Colvin, Sean Corfield, Pete Becker, Nico Josuttis, Dietmar K<EFBFBD>hl, 
 | 
			
		||||
			Nathan Myers, Chichiang Wan and Judy Ward. During the discussion, the four new 
 | 
			
		||||
			class names were finalized, it was decided that there was no need to exactly 
 | 
			
		||||
			follow the <b>std::auto_ptr</b> interface, and various function signatures and 
 | 
			
		||||
		<p>October 1998. Beman Dawes proposed reviving the original semantics under the
 | 
			
		||||
			names <b>safe_ptr</b> and <b>counted_ptr</b>, meeting of Per Andersson, Matt
 | 
			
		||||
			Austern, Greg Colvin, Sean Corfield, Pete Becker, Nico Josuttis, Dietmar Kühl,
 | 
			
		||||
			Nathan Myers, Chichiang Wan and Judy Ward. During the discussion, the four new
 | 
			
		||||
			class names were finalized, it was decided that there was no need to exactly
 | 
			
		||||
			follow the <b>std::auto_ptr</b> interface, and various function signatures and
 | 
			
		||||
			semantics were finalized.</p>
 | 
			
		||||
		<p>Over the next three months, several implementations were considered for <b>shared_ptr</b>, 
 | 
			
		||||
			and discussed on the <a href="http://www.boost.org">boost.org</a> mailing list. 
 | 
			
		||||
			The implementation questions revolved around the reference count which must be 
 | 
			
		||||
			kept, either attached to the pointed to object, or detached elsewhere. Each of 
 | 
			
		||||
		<p>Over the next three months, several implementations were considered for <b>shared_ptr</b>,
 | 
			
		||||
			and discussed on the <a href="http://www.boost.org">boost.org</a> mailing list.
 | 
			
		||||
			The implementation questions revolved around the reference count which must be
 | 
			
		||||
			kept, either attached to the pointed to object, or detached elsewhere. Each of
 | 
			
		||||
			those variants have themselves two major variants:
 | 
			
		||||
			<ul>
 | 
			
		||||
				<li>
 | 
			
		||||
				Direct detached: the shared_ptr contains a pointer to the object, and a pointer 
 | 
			
		||||
				Direct detached: the shared_ptr contains a pointer to the object, and a pointer
 | 
			
		||||
				to the count.
 | 
			
		||||
				<li>
 | 
			
		||||
				Indirect detached: the shared_ptr contains a pointer to a helper object, which 
 | 
			
		||||
				Indirect detached: the shared_ptr contains a pointer to a helper object, which
 | 
			
		||||
				in turn contains a pointer to the object and the count.
 | 
			
		||||
				<li>
 | 
			
		||||
				Embedded attached: the count is a member of the object pointed to.
 | 
			
		||||
				<li>
 | 
			
		||||
					Placement attached: the count is attached via operator new manipulations.</li>
 | 
			
		||||
			</ul>
 | 
			
		||||
		<p>Each implementation technique has advantages and disadvantages. We went so far 
 | 
			
		||||
			as to run various timings of the direct and indirect approaches, and found that 
 | 
			
		||||
			at least on Intel Pentium chips there was very little measurable difference. 
 | 
			
		||||
			Kevlin Henney provided a paper he wrote on "Counted Body Techniques." Dietmar 
 | 
			
		||||
			K<EFBFBD>hl suggested an elegant partial template specialization technique to allow 
 | 
			
		||||
			users to choose which implementation they preferred, and that was also 
 | 
			
		||||
		<p>Each implementation technique has advantages and disadvantages. We went so far
 | 
			
		||||
			as to run various timings of the direct and indirect approaches, and found that
 | 
			
		||||
			at least on Intel Pentium chips there was very little measurable difference.
 | 
			
		||||
			Kevlin Henney provided a paper he wrote on "Counted Body Techniques." Dietmar
 | 
			
		||||
			Kühl suggested an elegant partial template specialization technique to allow
 | 
			
		||||
			users to choose which implementation they preferred, and that was also
 | 
			
		||||
			experimented with.</p>
 | 
			
		||||
		<p>But Greg Colvin and Jerry Schwarz argued that "parameterization will discourage 
 | 
			
		||||
		<p>But Greg Colvin and Jerry Schwarz argued that "parameterization will discourage
 | 
			
		||||
			users", and in the end we choose to supply only the direct implementation.</p>
 | 
			
		||||
		<p>Summer, 1994. Greg Colvin proposed to the C++ Standards Committee classes named <b>auto_ptr</b>
 | 
			
		||||
			and <b>counted_ptr</b> which were very similar to what we now call <b>scoped_ptr</b>
 | 
			
		||||
			and <b>shared_ptr</b>. <a href="#Col-94">[Col-94]</a> In one of the very few 
 | 
			
		||||
			cases where the Library Working Group's recommendations were not followed by 
 | 
			
		||||
			the full committee, <b>counted_ptr</b> was rejected and surprising 
 | 
			
		||||
			and <b>shared_ptr</b>. <a href="#Col-94">[Col-94]</a> In one of the very few
 | 
			
		||||
			cases where the Library Working Group's recommendations were not followed by
 | 
			
		||||
			the full committee, <b>counted_ptr</b> was rejected and surprising
 | 
			
		||||
			transfer-of-ownership semantics were added to <b>auto_ptr</b>.</p>
 | 
			
		||||
		<h2><a name="References">References</a></h2>
 | 
			
		||||
		<p>[<a name="Col-94">Col-94</a>] Gregory Colvin, <a href="http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/1994/N0555.pdf">
 | 
			
		||||
				Exception Safe Smart Pointers</a>, C++ committee document 94-168/N0555, 
 | 
			
		||||
				Exception Safe Smart Pointers</a>, C++ committee document 94-168/N0555,
 | 
			
		||||
			July, 1994.</p>
 | 
			
		||||
		<p>[<a name="E&D-94">E&D-94</a>] John R. Ellis & David L. Detlefs, <a href="http://www.usenix.org/publications/library/proceedings/c++94/full_papers/ellis.a">
 | 
			
		||||
				Safe, Efficient Garbage Collection for C++</a>, Usenix Proceedings, 
 | 
			
		||||
			February, 1994. This paper includes an extensive discussion of weak pointers 
 | 
			
		||||
				Safe, Efficient Garbage Collection for C++</a>, Usenix Proceedings,
 | 
			
		||||
			February, 1994. This paper includes an extensive discussion of weak pointers
 | 
			
		||||
			and an extensive bibliography.</p>
 | 
			
		||||
		<hr>
 | 
			
		||||
		<p>$Date$</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>
 | 
			
		||||
		<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>
 | 
			
		||||
	</body>
 | 
			
		||||
</html>
 | 
			
		||||
 
 | 
			
		||||
@@ -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="../../people/dave_abrahams.htm">Dave Abrahams</a>,
 | 
			
		||||
<p>Thanks are due to <a href="http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a>,
 | 
			
		||||
Gavin Collings,
 | 
			
		||||
<a href="../../people/greg_colvin.htm">Greg Colvin</a> and
 | 
			
		||||
<a href="../../people/beman_dawes.html">Beman Dawes</a> 
 | 
			
		||||
<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> 
 | 
			
		||||
  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>
 | 
			
		||||
 
 | 
			
		||||
@@ -104,6 +104,8 @@ static void find_unreachable_objects_impl(map_type const & m, map2_type & m2)
 | 
			
		||||
 | 
			
		||||
            BOOST_ASSERT(p->use_count() != 0); // there should be no inactive counts in the map
 | 
			
		||||
 | 
			
		||||
            m2[ i->first ];
 | 
			
		||||
 | 
			
		||||
            scan_and_count(i->second.first, i->second.second, m, m2);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -121,7 +123,7 @@ static void find_unreachable_objects_impl(map_type const & m, map2_type & m2)
 | 
			
		||||
            if(p->use_count() != i->second) open.push_back(p);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        std::cout << "... " << m2.size() << " objects in open.\n";
 | 
			
		||||
        std::cout << "... " << open.size() << " objects in open.\n";
 | 
			
		||||
 | 
			
		||||
        for(open_type::iterator j = open.begin(); j != open.end(); ++j)
 | 
			
		||||
        {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
#  Boost.SmartPtr Library test Jamfile
 | 
			
		||||
#
 | 
			
		||||
#  Copyright (c) 2003-2005 Peter Dimov
 | 
			
		||||
#  Copyright (c) 2003-2007 Peter Dimov
 | 
			
		||||
#  Copyright (c) 2003 Dave Abrahams
 | 
			
		||||
#
 | 
			
		||||
#  Distributed under the Boost Software License, Version 1.0. (See
 | 
			
		||||
@@ -16,16 +16,57 @@ import testing ;
 | 
			
		||||
          [ 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 weak_ptr_move_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 intrusive_ptr_move_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 make_shared_perfect_forwarding_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 ]
 | 
			
		||||
          [ run esft_void_test.cpp ]
 | 
			
		||||
          [ run esft_second_ptr_test.cpp ]
 | 
			
		||||
          [ run make_shared_esft_test.cpp ]
 | 
			
		||||
          [ run allocate_shared_esft_test.cpp ]
 | 
			
		||||
          [ run sp_recursive_assign_test.cpp ]
 | 
			
		||||
          [ run sp_recursive_assign2_test.cpp ]
 | 
			
		||||
          [ run sp_recursive_assign_rv_test.cpp ]
 | 
			
		||||
          [ run sp_recursive_assign2_rv_test.cpp ]
 | 
			
		||||
          [ run esft_constructor_test.cpp ]
 | 
			
		||||
          [ compile-fail auto_ptr_lv_fail.cpp ]
 | 
			
		||||
          [ run atomic_count_test2.cpp ]
 | 
			
		||||
          [ run sp_typeinfo_test.cpp ]
 | 
			
		||||
          [ compile make_shared_fp_test.cpp ]
 | 
			
		||||
          [ run sp_hash_test.cpp ]
 | 
			
		||||
          [ run get_deleter_array_test.cpp ]
 | 
			
		||||
          [ run ip_hash_test.cpp ]
 | 
			
		||||
          [ run owner_less_test.cpp ]
 | 
			
		||||
        ;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										264
									
								
								test/allocate_shared_esft_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										264
									
								
								test/allocate_shared_esft_test.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,264 @@
 | 
			
		||||
//  allocate_shared_esft_test.cpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright 2007-2009 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/enable_shared_from_this.hpp>
 | 
			
		||||
#include <memory>
 | 
			
		||||
 | 
			
		||||
class X: public boost::enable_shared_from_this<X>
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    X( X const & );
 | 
			
		||||
    X & operator=( X const & );
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    static int instances;
 | 
			
		||||
 | 
			
		||||
    explicit X( int = 0, int = 0, int = 0, int = 0, int = 0, int = 0, int = 0, int = 0, int = 0 )
 | 
			
		||||
    {
 | 
			
		||||
        ++instances;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~X()
 | 
			
		||||
    {
 | 
			
		||||
        --instances;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int X::instances = 0;
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    BOOST_TEST( X::instances == 0 );
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > px = boost::allocate_shared< X >( std::allocator<void>() );
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            boost::shared_ptr< X > qx = px->shared_from_this();
 | 
			
		||||
 | 
			
		||||
            BOOST_TEST( px == qx );
 | 
			
		||||
            BOOST_TEST( !( px < qx ) && !( qx < px ) );
 | 
			
		||||
 | 
			
		||||
            px.reset();
 | 
			
		||||
            BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        }
 | 
			
		||||
        catch( boost::bad_weak_ptr const& )
 | 
			
		||||
        {
 | 
			
		||||
            BOOST_ERROR( "px->shared_from_this() failed" );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( X::instances == 0 );
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > px = boost::allocate_shared< X >( std::allocator<void>(), 1 );
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            boost::shared_ptr< X > qx = px->shared_from_this();
 | 
			
		||||
 | 
			
		||||
            BOOST_TEST( px == qx );
 | 
			
		||||
            BOOST_TEST( !( px < qx ) && !( qx < px ) );
 | 
			
		||||
 | 
			
		||||
            px.reset();
 | 
			
		||||
            BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        }
 | 
			
		||||
        catch( boost::bad_weak_ptr const& )
 | 
			
		||||
        {
 | 
			
		||||
            BOOST_ERROR( "px->shared_from_this() failed" );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( X::instances == 0 );
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > px = boost::allocate_shared< X >( std::allocator<void>(), 1, 2 );
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            boost::shared_ptr< X > qx = px->shared_from_this();
 | 
			
		||||
 | 
			
		||||
            BOOST_TEST( px == qx );
 | 
			
		||||
            BOOST_TEST( !( px < qx ) && !( qx < px ) );
 | 
			
		||||
 | 
			
		||||
            px.reset();
 | 
			
		||||
            BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        }
 | 
			
		||||
        catch( boost::bad_weak_ptr const& )
 | 
			
		||||
        {
 | 
			
		||||
            BOOST_ERROR( "px->shared_from_this() failed" );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( X::instances == 0 );
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > px = boost::allocate_shared< X >( std::allocator<void>(), 1, 2, 3 );
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            boost::shared_ptr< X > qx = px->shared_from_this();
 | 
			
		||||
 | 
			
		||||
            BOOST_TEST( px == qx );
 | 
			
		||||
            BOOST_TEST( !( px < qx ) && !( qx < px ) );
 | 
			
		||||
 | 
			
		||||
            px.reset();
 | 
			
		||||
            BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        }
 | 
			
		||||
        catch( boost::bad_weak_ptr const& )
 | 
			
		||||
        {
 | 
			
		||||
            BOOST_ERROR( "px->shared_from_this() failed" );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( X::instances == 0 );
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > px = boost::allocate_shared< X >( std::allocator<void>(), 1, 2, 3, 4 );
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            boost::shared_ptr< X > qx = px->shared_from_this();
 | 
			
		||||
 | 
			
		||||
            BOOST_TEST( px == qx );
 | 
			
		||||
            BOOST_TEST( !( px < qx ) && !( qx < px ) );
 | 
			
		||||
 | 
			
		||||
            px.reset();
 | 
			
		||||
            BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        }
 | 
			
		||||
        catch( boost::bad_weak_ptr const& )
 | 
			
		||||
        {
 | 
			
		||||
            BOOST_ERROR( "px->shared_from_this() failed" );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( X::instances == 0 );
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > px = boost::allocate_shared< X >( std::allocator<void>(), 1, 2, 3, 4, 5 );
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            boost::shared_ptr< X > qx = px->shared_from_this();
 | 
			
		||||
 | 
			
		||||
            BOOST_TEST( px == qx );
 | 
			
		||||
            BOOST_TEST( !( px < qx ) && !( qx < px ) );
 | 
			
		||||
 | 
			
		||||
            px.reset();
 | 
			
		||||
            BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        }
 | 
			
		||||
        catch( boost::bad_weak_ptr const& )
 | 
			
		||||
        {
 | 
			
		||||
            BOOST_ERROR( "px->shared_from_this() failed" );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( X::instances == 0 );
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > px = boost::allocate_shared< X >( std::allocator<void>(), 1, 2, 3, 4, 5, 6 );
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            boost::shared_ptr< X > qx = px->shared_from_this();
 | 
			
		||||
 | 
			
		||||
            BOOST_TEST( px == qx );
 | 
			
		||||
            BOOST_TEST( !( px < qx ) && !( qx < px ) );
 | 
			
		||||
 | 
			
		||||
            px.reset();
 | 
			
		||||
            BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        }
 | 
			
		||||
        catch( boost::bad_weak_ptr const& )
 | 
			
		||||
        {
 | 
			
		||||
            BOOST_ERROR( "px->shared_from_this() failed" );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( X::instances == 0 );
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > px = boost::allocate_shared< X >( std::allocator<void>(), 1, 2, 3, 4, 5, 6, 7 );
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            boost::shared_ptr< X > qx = px->shared_from_this();
 | 
			
		||||
 | 
			
		||||
            BOOST_TEST( px == qx );
 | 
			
		||||
            BOOST_TEST( !( px < qx ) && !( qx < px ) );
 | 
			
		||||
 | 
			
		||||
            px.reset();
 | 
			
		||||
            BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        }
 | 
			
		||||
        catch( boost::bad_weak_ptr const& )
 | 
			
		||||
        {
 | 
			
		||||
            BOOST_ERROR( "px->shared_from_this() failed" );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( X::instances == 0 );
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > px = boost::allocate_shared< X >( std::allocator<void>(), 1, 2, 3, 4, 5, 6, 7, 8 );
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            boost::shared_ptr< X > qx = px->shared_from_this();
 | 
			
		||||
 | 
			
		||||
            BOOST_TEST( px == qx );
 | 
			
		||||
            BOOST_TEST( !( px < qx ) && !( qx < px ) );
 | 
			
		||||
 | 
			
		||||
            px.reset();
 | 
			
		||||
            BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        }
 | 
			
		||||
        catch( boost::bad_weak_ptr const& )
 | 
			
		||||
        {
 | 
			
		||||
            BOOST_ERROR( "px->shared_from_this() failed" );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( X::instances == 0 );
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > px = boost::allocate_shared< X >( std::allocator<void>(), 1, 2, 3, 4, 5, 6, 7, 8, 9 );
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            boost::shared_ptr< X > qx = px->shared_from_this();
 | 
			
		||||
 | 
			
		||||
            BOOST_TEST( px == qx );
 | 
			
		||||
            BOOST_TEST( !( px < qx ) && !( qx < px ) );
 | 
			
		||||
 | 
			
		||||
            px.reset();
 | 
			
		||||
            BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        }
 | 
			
		||||
        catch( boost::bad_weak_ptr const& )
 | 
			
		||||
        {
 | 
			
		||||
            BOOST_ERROR( "px->shared_from_this() failed" );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( X::instances == 0 );
 | 
			
		||||
 | 
			
		||||
    return boost::report_errors();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										204
									
								
								test/allocate_shared_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										204
									
								
								test/allocate_shared_test.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,204 @@
 | 
			
		||||
// allocate_shared_test.cpp
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2007-2009 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>
 | 
			
		||||
#include <cstddef>
 | 
			
		||||
 | 
			
		||||
class X
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    X( X const & );
 | 
			
		||||
    X & operator=( X const & );
 | 
			
		||||
 | 
			
		||||
    void * operator new( std::size_t n )
 | 
			
		||||
    {
 | 
			
		||||
        // lack of this definition causes link errors on Comeau C++
 | 
			
		||||
        BOOST_ERROR( "private X::new called" );
 | 
			
		||||
        return ::operator new( n );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void operator delete( void * p )
 | 
			
		||||
    {
 | 
			
		||||
        // lack of this definition causes link errors on MSVC
 | 
			
		||||
        BOOST_ERROR( "private X::delete called" );
 | 
			
		||||
        ::operator delete( p );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
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();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										55
									
								
								test/atomic_count_test2.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								test/atomic_count_test2.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,55 @@
 | 
			
		||||
//
 | 
			
		||||
// atomic_count_test2.cpp
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2009 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 == 4 );
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( ++n == 5 );
 | 
			
		||||
    BOOST_TEST( ++n == 6 );
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( n == 6 );
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( --n == 5 );
 | 
			
		||||
    BOOST_TEST( --n == 4 );
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( n == 4 );
 | 
			
		||||
 | 
			
		||||
    boost::detail::atomic_count m( 0 );
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( m == 0 );
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( ++m == 1 );
 | 
			
		||||
    BOOST_TEST( ++m == 2 );
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( m == 2 );
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( --m == 1 );
 | 
			
		||||
    BOOST_TEST( --m == 0 );
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( m == 0 );
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( --m == -1 );
 | 
			
		||||
    BOOST_TEST( --m == -2 );
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( m == -2 );
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( ++m == -1 );
 | 
			
		||||
    BOOST_TEST( ++m == 0 );
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( m == 0 );
 | 
			
		||||
 | 
			
		||||
    return boost::report_errors();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										32
									
								
								test/auto_ptr_lv_fail.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								test/auto_ptr_lv_fail.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,32 @@
 | 
			
		||||
#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
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  auto_ptr_lv_fail.cpp - a negative test for converting an auto_ptr to shared_ptr
 | 
			
		||||
//
 | 
			
		||||
//  Copyright 2009 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 <memory>
 | 
			
		||||
 | 
			
		||||
void f( boost::shared_ptr<int> )
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    std::auto_ptr<int> p;
 | 
			
		||||
    f( p ); // must fail
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										169
									
								
								test/esft_constructor_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										169
									
								
								test/esft_constructor_test.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,169 @@
 | 
			
		||||
//
 | 
			
		||||
//  esft_constructor_test.cpp
 | 
			
		||||
//
 | 
			
		||||
//  A test for the new enable_shared_from_this support for calling
 | 
			
		||||
//  shared_from_this from constructors (that is, prior to the
 | 
			
		||||
//  object's ownership being passed to an external shared_ptr).
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2008 Frank Mori Hess
 | 
			
		||||
//  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/smart_ptr/enable_shared_from_this2.hpp>
 | 
			
		||||
#include <boost/shared_ptr.hpp>
 | 
			
		||||
#include <boost/weak_ptr.hpp>
 | 
			
		||||
#include <boost/detail/lightweight_test.hpp>
 | 
			
		||||
#include <memory>
 | 
			
		||||
 | 
			
		||||
class X: public boost::enable_shared_from_this2< 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, boost::shared_ptr<X> *early_px = 0 ): destroyed_( 0 ), deleted_( 0 ), expected_( expected )
 | 
			
		||||
    {
 | 
			
		||||
        ++instances;
 | 
			
		||||
        if( early_px ) *early_px = shared_from_this();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~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;
 | 
			
		||||
 | 
			
		||||
template<typename T, typename U>
 | 
			
		||||
bool are_shared_owners(const boost::shared_ptr<T> &a, const boost::shared_ptr<U> &b)
 | 
			
		||||
{
 | 
			
		||||
    return !(a < b) && !(b < a);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct Y: public boost::enable_shared_from_this2<Y>
 | 
			
		||||
{};
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    BOOST_TEST( X::instances == 0 );
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<X> early_px;
 | 
			
		||||
        X* x = new X( 1, &early_px );
 | 
			
		||||
        BOOST_TEST( early_px.use_count() > 0 );
 | 
			
		||||
        BOOST_TEST( boost::get_deleter<X::deleter_type>(early_px) == 0 );
 | 
			
		||||
        boost::shared_ptr<X> px( x, &X::deleter2 );
 | 
			
		||||
        BOOST_TEST( early_px.use_count() == 2 && px.use_count() == 2 );
 | 
			
		||||
        BOOST_TEST(are_shared_owners(early_px, px));
 | 
			
		||||
        px.reset();
 | 
			
		||||
        BOOST_TEST( early_px.use_count() == 1 );
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        // X::deleter_type *pd = boost::get_deleter<X::deleter_type>(early_px);
 | 
			
		||||
        // BOOST_TEST(pd && *pd == &X::deleter2 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( X::instances == 0 );
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<X> early_px;
 | 
			
		||||
        X* x = new X( 1, &early_px );
 | 
			
		||||
        boost::weak_ptr<X> early_weak_px = early_px;
 | 
			
		||||
        early_px.reset();
 | 
			
		||||
        BOOST_TEST( !early_weak_px.expired() );
 | 
			
		||||
        boost::shared_ptr<X> px( x, &X::deleter2 );
 | 
			
		||||
        BOOST_TEST( px.use_count() == 1 );
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        BOOST_TEST(are_shared_owners(early_weak_px.lock(), px));
 | 
			
		||||
        px.reset();
 | 
			
		||||
        BOOST_TEST( early_weak_px.expired() );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( X::instances == 0 );
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<X> early_px;
 | 
			
		||||
        X x( 1, &early_px );
 | 
			
		||||
        BOOST_TEST( early_px.use_count() > 0 );
 | 
			
		||||
        boost::shared_ptr<X> px( &x, &X::deleter );
 | 
			
		||||
        BOOST_TEST( early_px.use_count() == 2 && px.use_count() == 2 );
 | 
			
		||||
        early_px.reset();
 | 
			
		||||
        BOOST_TEST( px.use_count() == 1 );
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        px.reset();
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            x.shared_from_this();
 | 
			
		||||
            BOOST_ERROR("x did not throw bad_weak_ptr");
 | 
			
		||||
        }
 | 
			
		||||
        catch( const boost::bad_weak_ptr & )
 | 
			
		||||
        {}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( X::instances == 0 );
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::weak_ptr<X> early_weak_px;
 | 
			
		||||
        {
 | 
			
		||||
            boost::shared_ptr<X> early_px;
 | 
			
		||||
            X x( 0, &early_px );
 | 
			
		||||
            early_weak_px = early_px;
 | 
			
		||||
            early_px.reset();
 | 
			
		||||
            BOOST_TEST( !early_weak_px.expired() );
 | 
			
		||||
            BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        }
 | 
			
		||||
        BOOST_TEST( early_weak_px.expired() );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( X::instances == 0 );
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<Y> px(new Y());
 | 
			
		||||
        Y y(*px);
 | 
			
		||||
        px.reset();
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            y.shared_from_this();
 | 
			
		||||
        }
 | 
			
		||||
        catch( const boost::bad_weak_ptr & )
 | 
			
		||||
        {
 | 
			
		||||
            BOOST_ERROR("y threw bad_weak_ptr");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    return boost::report_errors();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										221
									
								
								test/esft_regtest.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										221
									
								
								test/esft_regtest.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,221 @@
 | 
			
		||||
//
 | 
			
		||||
//  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();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										51
									
								
								test/esft_second_ptr_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								test/esft_second_ptr_test.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,51 @@
 | 
			
		||||
//
 | 
			
		||||
//  esft_second_ptr_test.cpp
 | 
			
		||||
//
 | 
			
		||||
//  This test has been extracted from a real
 | 
			
		||||
//  scenario that occurs in Boost.Python
 | 
			
		||||
//
 | 
			
		||||
//  Copyright 2009 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/detail/lightweight_test.hpp>
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
class X: public boost::enable_shared_from_this<X>
 | 
			
		||||
{
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void null_deleter( void const* )
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr<X> px( new X );
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr<X> px2( px.get(), null_deleter );
 | 
			
		||||
        BOOST_TEST( px == px2 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    try
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > qx = px->shared_from_this();
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( px == qx );
 | 
			
		||||
        BOOST_TEST( !( px < qx ) && !( qx < px ) );
 | 
			
		||||
    }
 | 
			
		||||
    catch( boost::bad_weak_ptr const& )
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ERROR( "px->shared_from_this() failed" );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return boost::report_errors();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										41
									
								
								test/esft_void_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								test/esft_void_test.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
			
		||||
//
 | 
			
		||||
//  esft_void_test.cpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright 2009 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/detail/lightweight_test.hpp>
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
class X: public boost::enable_shared_from_this<X>
 | 
			
		||||
{
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    boost::shared_ptr< void const volatile > pv( new X );
 | 
			
		||||
    boost::shared_ptr< void > pv2 = boost::const_pointer_cast< void >( pv );
 | 
			
		||||
    boost::shared_ptr< X > px = boost::static_pointer_cast< X >( pv2 );
 | 
			
		||||
 | 
			
		||||
    try
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > qx = px->shared_from_this();
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST( px == qx );
 | 
			
		||||
        BOOST_TEST( !( px < qx ) && !( qx < px ) );
 | 
			
		||||
    }
 | 
			
		||||
    catch( boost::bad_weak_ptr const& )
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_ERROR( "px->shared_from_this() failed" );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return boost::report_errors();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										95
									
								
								test/get_deleter_array_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								test/get_deleter_array_test.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,95 @@
 | 
			
		||||
//
 | 
			
		||||
//  get_deleter_array_test.cpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2002, 2011 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_array.hpp>
 | 
			
		||||
#include <boost/detail/lightweight_test.hpp>
 | 
			
		||||
 | 
			
		||||
struct deleter
 | 
			
		||||
{
 | 
			
		||||
    int data;
 | 
			
		||||
 | 
			
		||||
    deleter(): data(0)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void operator()(void *)
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_TEST(data == 17041);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct deleter2
 | 
			
		||||
{
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct X
 | 
			
		||||
{
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_array<X> p;
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST(boost::get_deleter<void>(p) == 0);
 | 
			
		||||
        BOOST_TEST(boost::get_deleter<void const>(p) == 0);
 | 
			
		||||
        BOOST_TEST(boost::get_deleter<int>(p) == 0);
 | 
			
		||||
        BOOST_TEST(boost::get_deleter<int const>(p) == 0);
 | 
			
		||||
        BOOST_TEST(boost::get_deleter<X>(p) == 0);
 | 
			
		||||
        BOOST_TEST(boost::get_deleter<X const>(p) == 0);
 | 
			
		||||
        BOOST_TEST(boost::get_deleter<deleter>(p) == 0);
 | 
			
		||||
        BOOST_TEST(boost::get_deleter<deleter const>(p) == 0);
 | 
			
		||||
        BOOST_TEST(boost::get_deleter<deleter2>(p) == 0);
 | 
			
		||||
        BOOST_TEST(boost::get_deleter<deleter2 const>(p) == 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_array<X> p(new X[1]);
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST(boost::get_deleter<void>(p) == 0);
 | 
			
		||||
        BOOST_TEST(boost::get_deleter<void const>(p) == 0);
 | 
			
		||||
        BOOST_TEST(boost::get_deleter<int>(p) == 0);
 | 
			
		||||
        BOOST_TEST(boost::get_deleter<int const>(p) == 0);
 | 
			
		||||
        BOOST_TEST(boost::get_deleter<X>(p) == 0);
 | 
			
		||||
        BOOST_TEST(boost::get_deleter<X const>(p) == 0);
 | 
			
		||||
        BOOST_TEST(boost::get_deleter<deleter>(p) == 0);
 | 
			
		||||
        BOOST_TEST(boost::get_deleter<deleter const>(p) == 0);
 | 
			
		||||
        BOOST_TEST(boost::get_deleter<deleter2>(p) == 0);
 | 
			
		||||
        BOOST_TEST(boost::get_deleter<deleter2 const>(p) == 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        X x[1];
 | 
			
		||||
        boost::shared_array<X> p(x, deleter());
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST(boost::get_deleter<void>(p) == 0);
 | 
			
		||||
        BOOST_TEST(boost::get_deleter<void const>(p) == 0);
 | 
			
		||||
        BOOST_TEST(boost::get_deleter<int>(p) == 0);
 | 
			
		||||
        BOOST_TEST(boost::get_deleter<int const>(p) == 0);
 | 
			
		||||
        BOOST_TEST(boost::get_deleter<X>(p) == 0);
 | 
			
		||||
        BOOST_TEST(boost::get_deleter<X const>(p) == 0);
 | 
			
		||||
        BOOST_TEST(boost::get_deleter<deleter2>(p) == 0);
 | 
			
		||||
        BOOST_TEST(boost::get_deleter<deleter2 const>(p) == 0);
 | 
			
		||||
 | 
			
		||||
        deleter * q = boost::get_deleter<deleter>(p);
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST(q != 0);
 | 
			
		||||
        BOOST_TEST(q->data == 0);
 | 
			
		||||
 | 
			
		||||
        q->data = 17041;
 | 
			
		||||
 | 
			
		||||
        deleter const * r = boost::get_deleter<deleter const>(p);
 | 
			
		||||
 | 
			
		||||
        BOOST_TEST(r == q);
 | 
			
		||||
        BOOST_TEST(r->data == 17041);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return boost::report_errors();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										183
									
								
								test/intrusive_ptr_move_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										183
									
								
								test/intrusive_ptr_move_test.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,183 @@
 | 
			
		||||
#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
 | 
			
		||||
#pragma warning(disable: 4355)  // 'this' : used in base member initializer list
 | 
			
		||||
#pragma warning(disable: 4511)  // copy constructor could not be generated
 | 
			
		||||
#pragma warning(disable: 4512)  // assignment operator could not be generated
 | 
			
		||||
 | 
			
		||||
#if (BOOST_MSVC >= 1310)
 | 
			
		||||
#pragma warning(disable: 4675)  // resolved overload found with Koenig lookup
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  intrusive_ptr_move_test.cpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2002-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/intrusive_ptr.hpp>
 | 
			
		||||
#include <boost/detail/atomic_count.hpp>
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#include <utility>
 | 
			
		||||
 | 
			
		||||
#if defined( BOOST_HAS_RVALUE_REFS )
 | 
			
		||||
 | 
			
		||||
namespace N
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
class base
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    boost::detail::atomic_count use_count_;
 | 
			
		||||
 | 
			
		||||
    base(base const &);
 | 
			
		||||
    base & operator=(base const &);
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
 | 
			
		||||
    base(): use_count_(0)
 | 
			
		||||
    {
 | 
			
		||||
        ++instances;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual ~base()
 | 
			
		||||
    {
 | 
			
		||||
        --instances;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    static long instances;
 | 
			
		||||
 | 
			
		||||
    long use_count() const
 | 
			
		||||
    {
 | 
			
		||||
        return use_count_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
 | 
			
		||||
 | 
			
		||||
    inline friend void intrusive_ptr_add_ref(base * p)
 | 
			
		||||
    {
 | 
			
		||||
        ++p->use_count_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    inline friend void intrusive_ptr_release(base * p)
 | 
			
		||||
    {
 | 
			
		||||
        if(--p->use_count_ == 0) delete p;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
    void add_ref()
 | 
			
		||||
    {
 | 
			
		||||
        ++use_count_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void release()
 | 
			
		||||
    {
 | 
			
		||||
        if(--use_count_ == 0) delete this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
long base::instances = 0;
 | 
			
		||||
 | 
			
		||||
} // namespace N
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
 | 
			
		||||
 | 
			
		||||
namespace boost
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
inline void intrusive_ptr_add_ref(N::base * p)
 | 
			
		||||
{
 | 
			
		||||
    p->add_ref();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void intrusive_ptr_release(N::base * p)
 | 
			
		||||
{
 | 
			
		||||
    p->release();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
struct X: public virtual N::base
 | 
			
		||||
{
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct Y: public X
 | 
			
		||||
{
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    BOOST_TEST( N::base::instances == 0 );
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::intrusive_ptr<X> p( new X );
 | 
			
		||||
        BOOST_TEST( N::base::instances == 1 );
 | 
			
		||||
 | 
			
		||||
        boost::intrusive_ptr<X> p2( std::move( p ) );
 | 
			
		||||
        BOOST_TEST( N::base::instances == 1 );
 | 
			
		||||
        BOOST_TEST( p.get() == 0 );
 | 
			
		||||
 | 
			
		||||
        p2.reset();
 | 
			
		||||
        BOOST_TEST( N::base::instances == 0 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::intrusive_ptr<X> p( new X );
 | 
			
		||||
        BOOST_TEST( N::base::instances == 1 );
 | 
			
		||||
 | 
			
		||||
        boost::intrusive_ptr<X> p2;
 | 
			
		||||
        p2 = std::move( p );
 | 
			
		||||
        BOOST_TEST( N::base::instances == 1 );
 | 
			
		||||
        BOOST_TEST( p.get() == 0 );
 | 
			
		||||
 | 
			
		||||
        p2.reset();
 | 
			
		||||
        BOOST_TEST( N::base::instances == 0 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::intrusive_ptr<X> p( new X );
 | 
			
		||||
        BOOST_TEST( N::base::instances == 1 );
 | 
			
		||||
 | 
			
		||||
        boost::intrusive_ptr<X> p2( new X );
 | 
			
		||||
        BOOST_TEST( N::base::instances == 2 );
 | 
			
		||||
        p2 = std::move( p );
 | 
			
		||||
        BOOST_TEST( N::base::instances == 1 );
 | 
			
		||||
        BOOST_TEST( p.get() == 0 );
 | 
			
		||||
 | 
			
		||||
        p2.reset();
 | 
			
		||||
        BOOST_TEST( N::base::instances == 0 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return boost::report_errors();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#else // !defined( BOOST_HAS_RVALUE_REFS )
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										54
									
								
								test/ip_convertible_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								test/ip_convertible_test.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,54 @@
 | 
			
		||||
#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();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										75
									
								
								test/ip_hash_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								test/ip_hash_test.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,75 @@
 | 
			
		||||
//
 | 
			
		||||
// ip_hash_test.cpp
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2011 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/intrusive_ptr.hpp>
 | 
			
		||||
#include <boost/functional/hash.hpp>
 | 
			
		||||
#include <boost/detail/lightweight_test.hpp>
 | 
			
		||||
 | 
			
		||||
class base
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    int use_count_;
 | 
			
		||||
 | 
			
		||||
    base(base const &);
 | 
			
		||||
    base & operator=(base const &);
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
 | 
			
		||||
    base(): use_count_(0)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual ~base()
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    long use_count() const
 | 
			
		||||
    {
 | 
			
		||||
        return use_count_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    inline friend void intrusive_ptr_add_ref(base * p)
 | 
			
		||||
    {
 | 
			
		||||
        ++p->use_count_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    inline friend void intrusive_ptr_release(base * p)
 | 
			
		||||
    {
 | 
			
		||||
        if(--p->use_count_ == 0) delete p;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct X: public base
 | 
			
		||||
{
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    boost::hash< boost::intrusive_ptr<X> > hasher;
 | 
			
		||||
 | 
			
		||||
    boost::intrusive_ptr<X> p1, p2( p1 ), p3( new X ), p4( p3 ), p5( new X );
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST_EQ( p1, p2 );
 | 
			
		||||
    BOOST_TEST_EQ( hasher( p1 ), hasher( p2 ) );
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST_NE( p1, p3 );
 | 
			
		||||
    BOOST_TEST_NE( hasher( p1 ), hasher( p3 ) );
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST_EQ( p3, p4 );
 | 
			
		||||
    BOOST_TEST_EQ( hasher( p3 ), hasher( p4 ) );
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST_NE( p3, p5 );
 | 
			
		||||
    BOOST_TEST_NE( hasher( p3 ), hasher( p5 ) );
 | 
			
		||||
 | 
			
		||||
    return boost::report_errors();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										263
									
								
								test/make_shared_esft_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										263
									
								
								test/make_shared_esft_test.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,263 @@
 | 
			
		||||
//  make_shared_esft_test.cpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright 2007-2009 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/enable_shared_from_this.hpp>
 | 
			
		||||
 | 
			
		||||
class X: public boost::enable_shared_from_this<X>
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    X( X const & );
 | 
			
		||||
    X & operator=( X const & );
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    static int instances;
 | 
			
		||||
 | 
			
		||||
    explicit X( int = 0, int = 0, int = 0, int = 0, int = 0, int = 0, int = 0, int = 0, int = 0 )
 | 
			
		||||
    {
 | 
			
		||||
        ++instances;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~X()
 | 
			
		||||
    {
 | 
			
		||||
        --instances;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int X::instances = 0;
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    BOOST_TEST( X::instances == 0 );
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > px = boost::make_shared< X >();
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            boost::shared_ptr< X > qx = px->shared_from_this();
 | 
			
		||||
 | 
			
		||||
            BOOST_TEST( px == qx );
 | 
			
		||||
            BOOST_TEST( !( px < qx ) && !( qx < px ) );
 | 
			
		||||
 | 
			
		||||
            px.reset();
 | 
			
		||||
            BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        }
 | 
			
		||||
        catch( boost::bad_weak_ptr const& )
 | 
			
		||||
        {
 | 
			
		||||
            BOOST_ERROR( "px->shared_from_this() failed" );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( X::instances == 0 );
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > px = boost::make_shared< X >( 1 );
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            boost::shared_ptr< X > qx = px->shared_from_this();
 | 
			
		||||
 | 
			
		||||
            BOOST_TEST( px == qx );
 | 
			
		||||
            BOOST_TEST( !( px < qx ) && !( qx < px ) );
 | 
			
		||||
 | 
			
		||||
            px.reset();
 | 
			
		||||
            BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        }
 | 
			
		||||
        catch( boost::bad_weak_ptr const& )
 | 
			
		||||
        {
 | 
			
		||||
            BOOST_ERROR( "px->shared_from_this() failed" );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( X::instances == 0 );
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > px = boost::make_shared< X >( 1, 2 );
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            boost::shared_ptr< X > qx = px->shared_from_this();
 | 
			
		||||
 | 
			
		||||
            BOOST_TEST( px == qx );
 | 
			
		||||
            BOOST_TEST( !( px < qx ) && !( qx < px ) );
 | 
			
		||||
 | 
			
		||||
            px.reset();
 | 
			
		||||
            BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        }
 | 
			
		||||
        catch( boost::bad_weak_ptr const& )
 | 
			
		||||
        {
 | 
			
		||||
            BOOST_ERROR( "px->shared_from_this() failed" );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( X::instances == 0 );
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > px = boost::make_shared< X >( 1, 2, 3 );
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            boost::shared_ptr< X > qx = px->shared_from_this();
 | 
			
		||||
 | 
			
		||||
            BOOST_TEST( px == qx );
 | 
			
		||||
            BOOST_TEST( !( px < qx ) && !( qx < px ) );
 | 
			
		||||
 | 
			
		||||
            px.reset();
 | 
			
		||||
            BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        }
 | 
			
		||||
        catch( boost::bad_weak_ptr const& )
 | 
			
		||||
        {
 | 
			
		||||
            BOOST_ERROR( "px->shared_from_this() failed" );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( X::instances == 0 );
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > px = boost::make_shared< X >( 1, 2, 3, 4 );
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            boost::shared_ptr< X > qx = px->shared_from_this();
 | 
			
		||||
 | 
			
		||||
            BOOST_TEST( px == qx );
 | 
			
		||||
            BOOST_TEST( !( px < qx ) && !( qx < px ) );
 | 
			
		||||
 | 
			
		||||
            px.reset();
 | 
			
		||||
            BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        }
 | 
			
		||||
        catch( boost::bad_weak_ptr const& )
 | 
			
		||||
        {
 | 
			
		||||
            BOOST_ERROR( "px->shared_from_this() failed" );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( X::instances == 0 );
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > px = boost::make_shared< X >( 1, 2, 3, 4, 5 );
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            boost::shared_ptr< X > qx = px->shared_from_this();
 | 
			
		||||
 | 
			
		||||
            BOOST_TEST( px == qx );
 | 
			
		||||
            BOOST_TEST( !( px < qx ) && !( qx < px ) );
 | 
			
		||||
 | 
			
		||||
            px.reset();
 | 
			
		||||
            BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        }
 | 
			
		||||
        catch( boost::bad_weak_ptr const& )
 | 
			
		||||
        {
 | 
			
		||||
            BOOST_ERROR( "px->shared_from_this() failed" );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( X::instances == 0 );
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > px = boost::make_shared< X >( 1, 2, 3, 4, 5, 6 );
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            boost::shared_ptr< X > qx = px->shared_from_this();
 | 
			
		||||
 | 
			
		||||
            BOOST_TEST( px == qx );
 | 
			
		||||
            BOOST_TEST( !( px < qx ) && !( qx < px ) );
 | 
			
		||||
 | 
			
		||||
            px.reset();
 | 
			
		||||
            BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        }
 | 
			
		||||
        catch( boost::bad_weak_ptr const& )
 | 
			
		||||
        {
 | 
			
		||||
            BOOST_ERROR( "px->shared_from_this() failed" );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( X::instances == 0 );
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > px = boost::make_shared< X >( 1, 2, 3, 4, 5, 6, 7 );
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            boost::shared_ptr< X > qx = px->shared_from_this();
 | 
			
		||||
 | 
			
		||||
            BOOST_TEST( px == qx );
 | 
			
		||||
            BOOST_TEST( !( px < qx ) && !( qx < px ) );
 | 
			
		||||
 | 
			
		||||
            px.reset();
 | 
			
		||||
            BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        }
 | 
			
		||||
        catch( boost::bad_weak_ptr const& )
 | 
			
		||||
        {
 | 
			
		||||
            BOOST_ERROR( "px->shared_from_this() failed" );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( X::instances == 0 );
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > px = boost::make_shared< X >( 1, 2, 3, 4, 5, 6, 7, 8 );
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            boost::shared_ptr< X > qx = px->shared_from_this();
 | 
			
		||||
 | 
			
		||||
            BOOST_TEST( px == qx );
 | 
			
		||||
            BOOST_TEST( !( px < qx ) && !( qx < px ) );
 | 
			
		||||
 | 
			
		||||
            px.reset();
 | 
			
		||||
            BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        }
 | 
			
		||||
        catch( boost::bad_weak_ptr const& )
 | 
			
		||||
        {
 | 
			
		||||
            BOOST_ERROR( "px->shared_from_this() failed" );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( X::instances == 0 );
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > px = boost::make_shared< X >( 1, 2, 3, 4, 5, 6, 7, 8, 9 );
 | 
			
		||||
        BOOST_TEST( X::instances == 1 );
 | 
			
		||||
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            boost::shared_ptr< X > qx = px->shared_from_this();
 | 
			
		||||
 | 
			
		||||
            BOOST_TEST( px == qx );
 | 
			
		||||
            BOOST_TEST( !( px < qx ) && !( qx < px ) );
 | 
			
		||||
 | 
			
		||||
            px.reset();
 | 
			
		||||
            BOOST_TEST( X::instances == 1 );
 | 
			
		||||
        }
 | 
			
		||||
        catch( boost::bad_weak_ptr const& )
 | 
			
		||||
        {
 | 
			
		||||
            BOOST_ERROR( "px->shared_from_this() failed" );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( X::instances == 0 );
 | 
			
		||||
 | 
			
		||||
    return boost::report_errors();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										19
									
								
								test/make_shared_fp_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								test/make_shared_fp_test.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
			
		||||
//
 | 
			
		||||
//  make_shared_fp_test.cpp
 | 
			
		||||
//
 | 
			
		||||
//  Copyright 2010 Georg Fritzsche
 | 
			
		||||
//
 | 
			
		||||
//  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/make_shared.hpp>
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    typedef boost::shared_ptr<int>(*FP)(); 
 | 
			
		||||
    FP fp = boost::make_shared<int>;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										98
									
								
								test/make_shared_perfect_forwarding_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								test/make_shared_perfect_forwarding_test.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,98 @@
 | 
			
		||||
// make_shared_perfect_forwarding_test.cpp - a test of make_shared
 | 
			
		||||
//   perfect forwarding of constructor arguments when using a C++0x
 | 
			
		||||
//   compiler.
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2009 Frank Mori Hess
 | 
			
		||||
//
 | 
			
		||||
// 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>
 | 
			
		||||
 | 
			
		||||
#if !defined( BOOST_HAS_RVALUE_REFS )
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#else // BOOST_HAS_RVALUE_REFS
 | 
			
		||||
 | 
			
		||||
class myarg
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    myarg()
 | 
			
		||||
    {}
 | 
			
		||||
private:
 | 
			
		||||
    myarg(myarg && other)
 | 
			
		||||
    {}
 | 
			
		||||
    myarg& operator=(myarg && other)
 | 
			
		||||
    {
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
    myarg(const myarg & other)
 | 
			
		||||
    {}
 | 
			
		||||
    myarg& operator=(const myarg & other)
 | 
			
		||||
    {
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class X
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    enum constructor_id
 | 
			
		||||
    {
 | 
			
		||||
        move_constructor,
 | 
			
		||||
        const_ref_constructor,
 | 
			
		||||
        ref_constructor
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    X(myarg &&arg): constructed_by_(move_constructor)
 | 
			
		||||
    {}
 | 
			
		||||
    X(const myarg &arg): constructed_by_(const_ref_constructor)
 | 
			
		||||
    {}
 | 
			
		||||
    X(myarg &arg): constructed_by_(ref_constructor)
 | 
			
		||||
    {}
 | 
			
		||||
 | 
			
		||||
    constructor_id constructed_by_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct Y
 | 
			
		||||
{
 | 
			
		||||
    Y(int &value): ref(value)
 | 
			
		||||
    {}
 | 
			
		||||
    int &ref;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    {
 | 
			
		||||
        myarg a;
 | 
			
		||||
        boost::shared_ptr< X > x = boost::make_shared< X >(a);
 | 
			
		||||
        BOOST_TEST( x->constructed_by_ == X::ref_constructor);
 | 
			
		||||
    }
 | 
			
		||||
    {
 | 
			
		||||
        const myarg ca;
 | 
			
		||||
        boost::shared_ptr< X > x = boost::make_shared< X >(ca);
 | 
			
		||||
        BOOST_TEST( x->constructed_by_ == X::const_ref_constructor);
 | 
			
		||||
    }
 | 
			
		||||
    {
 | 
			
		||||
        boost::shared_ptr< X > x = boost::make_shared< X >(myarg());
 | 
			
		||||
        BOOST_TEST( x->constructed_by_ == X::move_constructor);
 | 
			
		||||
    }
 | 
			
		||||
    {
 | 
			
		||||
        int value = 1;
 | 
			
		||||
        boost::shared_ptr< Y > y = boost::make_shared< Y >(value);
 | 
			
		||||
        BOOST_TEST( y->ref == 1 && value == y->ref );
 | 
			
		||||
        ++y->ref;
 | 
			
		||||
        BOOST_TEST( value == y->ref );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return boost::report_errors();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // BOOST_HAS_RVALUE_REFS
 | 
			
		||||
							
								
								
									
										204
									
								
								test/make_shared_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										204
									
								
								test/make_shared_test.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,204 @@
 | 
			
		||||
// make_shared_test.cpp
 | 
			
		||||
//
 | 
			
		||||
// Copyright 2007-2009 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>
 | 
			
		||||
#include <cstddef>
 | 
			
		||||
 | 
			
		||||
class X
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    X( X const & );
 | 
			
		||||
    X & operator=( X const & );
 | 
			
		||||
 | 
			
		||||
    void * operator new( std::size_t n )
 | 
			
		||||
    {
 | 
			
		||||
        // lack of this definition causes link errors on Comeau C++
 | 
			
		||||
        BOOST_ERROR( "private X::new called" );
 | 
			
		||||
        return ::operator new( n );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void operator delete( void * p )
 | 
			
		||||
    {
 | 
			
		||||
        // lack of this definition causes link errors on MSVC
 | 
			
		||||
        BOOST_ERROR( "private X::delete called" );
 | 
			
		||||
        ::operator delete( p );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
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();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										67
									
								
								test/owner_less_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								test/owner_less_test.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,67 @@
 | 
			
		||||
//
 | 
			
		||||
//  owner_less_test.cpp
 | 
			
		||||
//
 | 
			
		||||
//  A regression test for owner_less
 | 
			
		||||
//
 | 
			
		||||
//  Copyright (c) 2008 Frank Mori Hess
 | 
			
		||||
//
 | 
			
		||||
//  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/smart_ptr/owner_less.hpp>
 | 
			
		||||
#include <boost/shared_ptr.hpp>
 | 
			
		||||
#include <boost/weak_ptr.hpp>
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
  boost::owner_less<boost::shared_ptr<int> > comp;
 | 
			
		||||
  {
 | 
			
		||||
    boost::shared_ptr<int> x;
 | 
			
		||||
    boost::shared_ptr<int> y;
 | 
			
		||||
    boost::weak_ptr<int> w;
 | 
			
		||||
    BOOST_TEST(!(comp(x, w) || comp(w, x)));
 | 
			
		||||
  }
 | 
			
		||||
  {
 | 
			
		||||
    boost::shared_ptr<int> z((int*)0);
 | 
			
		||||
    boost::weak_ptr<int> w;
 | 
			
		||||
    BOOST_TEST(comp(z, w) || comp(w, z));
 | 
			
		||||
    {
 | 
			
		||||
      boost::shared_ptr<int> zz(z);
 | 
			
		||||
      w = boost::weak_ptr<int>(zz);
 | 
			
		||||
      BOOST_TEST(!(comp(z, zz) || comp(z, zz)));
 | 
			
		||||
      BOOST_TEST(!(comp(z, w) || comp(z, w)));
 | 
			
		||||
    }
 | 
			
		||||
    BOOST_TEST(!(comp(z, w) || comp(w, z)));
 | 
			
		||||
  }
 | 
			
		||||
  {
 | 
			
		||||
    boost::shared_ptr<int> x;
 | 
			
		||||
    boost::shared_ptr<int> z((int*)0);
 | 
			
		||||
    BOOST_TEST(comp(x, z) || comp(z, x));
 | 
			
		||||
  }
 | 
			
		||||
  {
 | 
			
		||||
    boost::shared_ptr<int> a((int*)0);
 | 
			
		||||
    boost::shared_ptr<int> b((int*)0);
 | 
			
		||||
    BOOST_TEST(comp(a, b) || comp(b, a));
 | 
			
		||||
    boost::weak_ptr<int> w(a);
 | 
			
		||||
    BOOST_TEST(!(comp(a, w) || comp(w, a)));
 | 
			
		||||
    BOOST_TEST(comp(b, w) || comp(w, b));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  boost::owner_less<boost::weak_ptr<int> > weak_comp;
 | 
			
		||||
  {
 | 
			
		||||
    boost::shared_ptr<int> a((int*)0);
 | 
			
		||||
    boost::weak_ptr<int> wa(a);
 | 
			
		||||
    boost::shared_ptr<int> b((int*)0);
 | 
			
		||||
    boost::weak_ptr<int> wb(b);
 | 
			
		||||
    BOOST_TEST(!(weak_comp(a, wa) || weak_comp(wa, a)));
 | 
			
		||||
    BOOST_TEST(!(weak_comp(b, wb) || weak_comp(wb, b)));
 | 
			
		||||
    BOOST_TEST(weak_comp(wa, wb) || weak_comp(wb, wa));
 | 
			
		||||
    BOOST_TEST(weak_comp(wa, b) || weak_comp(b, wa));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  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