mirror of
				https://github.com/boostorg/smart_ptr.git
				synced 2025-10-30 23:31:42 +01:00 
			
		
		
		
	Compare commits
	
		
			170 Commits
		
	
	
		
			boost-1.35
			...
			boost-1.41
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | c57e8ef5b4 | ||
|  | 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 | ||
|  | 7ca6d86bdc | ||
|  | b2a3c9e59d | ||
|  | e6f6ec9fa3 | ||
|  | f854829d86 | ||
|  | 7b5beeedde | ||
|  | 9e41d1f194 | ||
|  | f49a2fb1e1 | ||
|  | 9db307eda5 | ||
|  | 5a85c1f0f2 | ||
|  | f5ce4dbc4c | ||
|  | b2354d0a5e | ||
|  | e0ca42bb88 | ||
|  | bca336bf35 | ||
|  | 6646d8acd2 | ||
|  | 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 | 
| @@ -12,113 +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( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) | ||||
|  | ||||
| # include <boost/detail/atomic_count_gcc_x86.hpp> | ||||
|  | ||||
| #elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) | ||||
|  | ||||
| #  include <boost/detail/atomic_count_win32.hpp> | ||||
|  | ||||
| #elif defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 ) | ||||
|  | ||||
| #  include <boost/detail/atomic_count_sync.hpp> | ||||
|  | ||||
| #elif defined(__GLIBCPP__) || defined(__GLIBCXX__) | ||||
|  | ||||
| #  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(BOOST_HAS_PTHREADS) | ||||
| #  include <boost/detail/lwm_pthreads.hpp> | ||||
| #elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) | ||||
| #  include <boost/detail/lwm_win32_cs.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,81 +0,0 @@ | ||||
| #ifndef BOOST_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED | ||||
| #define BOOST_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED | ||||
|  | ||||
| // MS compatible compilers support #pragma once | ||||
|  | ||||
| #if defined(_MSC_VER) && (_MSC_VER >= 1020) | ||||
| # pragma once | ||||
| #endif | ||||
|  | ||||
| // | ||||
| //  detail/sp_counted_base.hpp | ||||
| // | ||||
| //  Copyright 2005, 2006 Peter Dimov | ||||
| // | ||||
| // Distributed under the Boost Software License, Version 1.0. (See | ||||
| // accompanying file LICENSE_1_0.txt or copy at | ||||
| // http://www.boost.org/LICENSE_1_0.txt) | ||||
| // | ||||
|  | ||||
| #include <boost/config.hpp> | ||||
|  | ||||
| #if defined( BOOST_SP_DISABLE_THREADS ) | ||||
|  | ||||
| # include <boost/detail/sp_counted_base_nt.hpp> | ||||
|  | ||||
| #elif defined( BOOST_SP_USE_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(__HP_aCC) && defined(__ia64) | ||||
|  | ||||
| # include <boost/detail/sp_counted_base_acc_ia64.hpp> | ||||
|  | ||||
| #elif defined( __MWERKS__ ) && defined( __POWERPC__ ) | ||||
|  | ||||
| # include <boost/detail/sp_counted_base_cw_ppc.hpp> | ||||
|  | ||||
| #elif defined( __GNUC__ ) && ( defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc ) ) | ||||
|  | ||||
| # include <boost/detail/sp_counted_base_gcc_ppc.hpp> | ||||
|  | ||||
| #elif defined(__GNUC__) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 ) | ||||
|  | ||||
| # include <boost/detail/sp_counted_base_sync.hpp> | ||||
|  | ||||
| #elif defined(__GNUC__) && ( defined( __sparcv8 ) || defined( __sparcv9 ) ) | ||||
|  | ||||
| # include <boost/detail/sp_counted_base_gcc_sparc.hpp> | ||||
|  | ||||
| #elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) | ||||
|  | ||||
| # include <boost/detail/sp_counted_base_w32.hpp> | ||||
|  | ||||
| #elif !defined( BOOST_HAS_THREADS ) | ||||
|  | ||||
| # include <boost/detail/sp_counted_base_nt.hpp> | ||||
|  | ||||
| #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 | ||||
| @@ -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,279 +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; | ||||
|     } | ||||
|  | ||||
|     void reset( T * rhs ) | ||||
|     { | ||||
|         this_type( rhs ).swap( *this ); | ||||
|     } | ||||
|  | ||||
|     T * get() const | ||||
|     { | ||||
|         return p_; | ||||
|     } | ||||
|  | ||||
|     T & operator*() const | ||||
|     { | ||||
|         BOOST_ASSERT( p_ != 0 ); | ||||
|         return *p_; | ||||
|     } | ||||
|  | ||||
|     T * operator->() const | ||||
|     { | ||||
|         BOOST_ASSERT( p_ != 0 ); | ||||
|         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 | ||||
							
								
								
									
										35
									
								
								include/boost/memory_order.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								include/boost/memory_order.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | ||||
| #ifndef BOOST_MEMORY_ORDER_HPP_INCLUDED | ||||
| #define BOOST_MEMORY_ORDER_HPP_INCLUDED | ||||
|  | ||||
| // MS compatible compilers support #pragma once | ||||
|  | ||||
| #if defined(_MSC_VER) && (_MSC_VER >= 1020) | ||||
| # pragma once | ||||
| #endif | ||||
|  | ||||
| //  boost/memory_order.hpp | ||||
| // | ||||
| //  Defines enum boost::memory_order per the C++0x working draft | ||||
| // | ||||
| //  Copyright (c) 2008 Peter Dimov | ||||
| // | ||||
| //  Distributed under the Boost Software License, Version 1.0. | ||||
| //  See accompanying file LICENSE_1_0.txt or copy at | ||||
| //  http://www.boost.org/LICENSE_1_0.txt) | ||||
|  | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| enum memory_order | ||||
| { | ||||
|     memory_order_relaxed = 0, | ||||
|     memory_order_acquire = 1, | ||||
|     memory_order_release = 2, | ||||
|     memory_order_acq_rel = 3, // acquire | release | ||||
|     memory_order_seq_cst = 7  // acq_rel | 4 | ||||
| }; | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #endif // #ifndef BOOST_MEMORY_ORDER_HPP_INCLUDED | ||||
| @@ -1,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,180 +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( _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 | ||||
|  | ||||
|     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-2007 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,606 +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 _MANAGED | ||||
|  | ||||
| // Avoid C4793, ... causes native code generation | ||||
|  | ||||
| struct sp_any_pointer | ||||
| { | ||||
|     template<class T> sp_any_pointer( T* ) {} | ||||
| }; | ||||
|  | ||||
| inline void sp_enable_shared_from_this( shared_count const & /*pn*/, sp_any_pointer, sp_any_pointer ) | ||||
| { | ||||
| } | ||||
|  | ||||
| #else // _MANAGED | ||||
|  | ||||
| #ifdef sgi | ||||
| // Turn off: the last argument of the varargs function "sp_enable_shared_from_this" is unnamed | ||||
| # pragma set woff 3506 | ||||
| #endif | ||||
|  | ||||
| inline void sp_enable_shared_from_this( shared_count const & /*pn*/, ... ) | ||||
| { | ||||
| } | ||||
|  | ||||
| #ifdef sgi | ||||
| # pragma reset woff 3506 | ||||
| #endif | ||||
|  | ||||
| #endif // _MANAGED | ||||
|  | ||||
| #if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) && !defined( BOOST_NO_AUTO_PTR ) | ||||
|  | ||||
| // rvalue auto_ptr support based on a technique by Dave Abrahams | ||||
|  | ||||
| template< class T, class R > struct sp_enable_if_auto_ptr | ||||
| { | ||||
| }; | ||||
|  | ||||
| template< class T, class R > struct sp_enable_if_auto_ptr< std::auto_ptr< T >, R > | ||||
| { | ||||
|     typedef R type; | ||||
| };  | ||||
|  | ||||
| #endif | ||||
|  | ||||
| } // namespace detail | ||||
|  | ||||
|  | ||||
| // | ||||
| //  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 | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     // 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( pn, tmp, tmp ); | ||||
|     } | ||||
|  | ||||
| #if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) | ||||
|  | ||||
|     template<class Ap> | ||||
|     shared_ptr( Ap r, typename boost::detail::sp_enable_if_auto_ptr<Ap, int>::type = 0 ): px( r.get() ), pn() | ||||
|     { | ||||
|         typename Ap::element_type * tmp = r.get(); | ||||
|         pn = boost::detail::shared_count( r ); | ||||
|         boost::detail::sp_enable_shared_from_this( pn, tmp, tmp ); | ||||
|     } | ||||
|  | ||||
|  | ||||
| #endif // BOOST_NO_SFINAE, BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION | ||||
|  | ||||
| #endif // BOOST_NO_AUTO_PTR | ||||
|  | ||||
| #if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300) | ||||
|  | ||||
|     template<class Y> | ||||
|     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 | ||||
|  | ||||
| // Move support | ||||
|  | ||||
| #if defined( BOOST_HAS_RVALUE_REFS ) | ||||
|  | ||||
|     shared_ptr( shared_ptr && r ): px( r.px ), pn() // never throws | ||||
|     { | ||||
|         pn.swap( r.pn ); | ||||
|         r.px = 0; | ||||
|     } | ||||
|  | ||||
|     template<class Y> | ||||
|     shared_ptr( shared_ptr<Y> && r ): px( r.px ), pn() // never throws | ||||
|     { | ||||
|         pn.swap( r.pn ); | ||||
|         r.px = 0; | ||||
|     } | ||||
|  | ||||
|     shared_ptr & operator=( shared_ptr && r ) // never throws | ||||
|     { | ||||
|         this_type( static_cast< shared_ptr && >( r ) ).swap( *this ); | ||||
|         return *this; | ||||
|     } | ||||
|  | ||||
|     template<class Y> | ||||
|     shared_ptr & operator=( shared_ptr<Y> && r ) // never throws | ||||
|     { | ||||
|         this_type( static_cast< shared_ptr<Y> && >( r ) ).swap( *this ); | ||||
|         return *this; | ||||
|     } | ||||
|  | ||||
| #endif | ||||
|  | ||||
|     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" | ||||
|  | ||||
| #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; | ||||
|     } | ||||
|  | ||||
|     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( detail::sp_typeinfo 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 | ||||
|  | ||||
| #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 | ||||
|  | ||||
| } // 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,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,7 +17,11 @@ | ||||
| //  http://www.boost.org/LICENSE_1_0.txt)
 | ||||
| //
 | ||||
| 
 | ||||
| #include <bits/atomicity.h> | ||||
| #if __GNUC__ * 100 + __GNUC_MINOR__ >= 402 | ||||
| # include <ext/atomicity.h>  | ||||
| #else  | ||||
| # include <bits/atomicity.h> | ||||
| #endif | ||||
| 
 | ||||
| namespace boost | ||||
| { | ||||
| @@ -36,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: | ||||
| @@ -65,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
 | ||||
| @@ -1,5 +1,5 @@ | ||||
| #ifndef BOOST_DETAIL_ATOMIC_COUNT_GCC_X86_HPP_INCLUDED | ||||
| #define BOOST_DETAIL_ATOMIC_COUNT_GCC_X86_HPP_INCLUDED | ||||
| #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
 | ||||
| @@ -25,16 +25,9 @@ public: | ||||
| 
 | ||||
|     explicit atomic_count( long v ) : value_( static_cast< int >( v ) ) {} | ||||
| 
 | ||||
|     void operator++() | ||||
|     long operator++() | ||||
|     { | ||||
|         __asm__ | ||||
|         ( | ||||
|             "lock\n\t" | ||||
|             "incl %0": | ||||
|             "+m"( value_ ): // output (%0)
 | ||||
|             : // inputs
 | ||||
|             "cc" // clobbers
 | ||||
|         ); | ||||
|         return atomic_exchange_and_add( &value_, +1 ) + 1; | ||||
|     } | ||||
| 
 | ||||
|     long operator--() | ||||
| @@ -81,4 +74,4 @@ private: | ||||
| 
 | ||||
| } // namespace boost
 | ||||
| 
 | ||||
| #endif // #ifndef BOOST_DETAIL_ATOMIC_COUNT_SYNC_HPP_INCLUDED
 | ||||
| #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
 | ||||
| @@ -1,5 +1,5 @@ | ||||
| #ifndef BOOST_DETAIL_ATOMIC_COUNT_SOLARIS_HPP_INCLUDED | ||||
| #define BOOST_DETAIL_ATOMIC_COUNT_SOLARIS_HPP_INCLUDED | ||||
| #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
 | ||||
| @@ -56,4 +56,4 @@ private: | ||||
| 
 | ||||
| } // namespace boost
 | ||||
| 
 | ||||
| #endif // #ifndef BOOST_DETAIL_ATOMIC_COUNT_SOLARIS_HPP_INCLUDED
 | ||||
| #endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SOLARIS_HPP_INCLUDED
 | ||||
| @@ -1,5 +1,5 @@ | ||||
| #ifndef BOOST_DETAIL_ATOMIC_COUNT_SYNC_HPP_INCLUDED | ||||
| #define BOOST_DETAIL_ATOMIC_COUNT_SYNC_HPP_INCLUDED | ||||
| #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
 | ||||
| @@ -15,6 +15,10 @@ | ||||
| //  http://www.boost.org/LICENSE_1_0.txt)
 | ||||
| //
 | ||||
| 
 | ||||
| #if defined( __ia64__ ) && defined( __INTEL_COMPILER ) | ||||
| # include <ia64intrin.h> | ||||
| #endif | ||||
| 
 | ||||
| namespace boost | ||||
| { | ||||
| 
 | ||||
| @@ -27,9 +31,9 @@ public: | ||||
| 
 | ||||
|     explicit atomic_count( long v ) : value_( v ) {} | ||||
| 
 | ||||
|     void operator++() | ||||
|     long operator++() | ||||
|     { | ||||
|         __sync_add_and_fetch( &value_, 1 ); | ||||
|         return __sync_add_and_fetch( &value_, 1 ); | ||||
|     } | ||||
| 
 | ||||
|     long operator--() | ||||
| @@ -54,4 +58,4 @@ private: | ||||
| 
 | ||||
| } // namespace boost
 | ||||
| 
 | ||||
| #endif // #ifndef BOOST_DETAIL_ATOMIC_COUNT_SYNC_HPP_INCLUDED
 | ||||
| #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
 | ||||
| 
 | ||||
| @@ -83,4 +83,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; | ||||
|     } | ||||
							
								
								
									
										198
									
								
								include/boost/smart_ptr/detail/quick_allocator.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										198
									
								
								include/boost/smart_ptr/detail/quick_allocator.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,198 @@ | ||||
| #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 lightweight_mutex m; | ||||
|         return m; | ||||
|     } | ||||
|  | ||||
|     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,11 +25,15 @@ | ||||
| #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
 | ||||
| 
 | ||||
| @@ -46,6 +50,8 @@ int const   weak_count_id = 0x298C38A4; | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
| struct sp_nothrow_tag {}; | ||||
| 
 | ||||
| class weak_count; | ||||
| 
 | ||||
| class shared_count | ||||
| @@ -99,11 +105,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 | ||||
| @@ -215,7 +228,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
 | ||||
|     { | ||||
| @@ -248,6 +274,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_; | ||||
| @@ -288,7 +319,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(); | ||||
| @@ -296,12 +327,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(); | ||||
| @@ -313,9 +358,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; | ||||
|     } | ||||
| @@ -323,9 +372,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; | ||||
|     } | ||||
| @@ -342,6 +395,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_; | ||||
| @@ -364,6 +422,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
 | ||||
| @@ -372,4 +441,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__ <= 0x610 ) | ||||
| # 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 | ||||
							
								
								
									
										70
									
								
								include/boost/smart_ptr/detail/sp_counted_base.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								include/boost/smart_ptr/detail/sp_counted_base.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,70 @@ | ||||
| #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( 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 | ||||
| @@ -1,5 +1,5 @@ | ||||
| #ifndef BOOST_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED | ||||
| #define BOOST_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED | ||||
| #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
 | ||||
| @@ -15,7 +15,7 @@ | ||||
| //  Lock-free algorithm by Alexander Terekhov
 | ||||
| //
 | ||||
| 
 | ||||
| #include "sp_typeinfo.hpp" | ||||
| #include <boost/detail/sp_typeinfo.hpp> | ||||
| #include <machine/sys/inline.h> | ||||
| 
 | ||||
| namespace boost | ||||
| @@ -147,4 +147,4 @@ public: | ||||
| 
 | ||||
| } // namespace boost
 | ||||
| 
 | ||||
| #endif  // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED
 | ||||
| #endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_ACC_IA64_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 "sp_typeinfo.hpp" | ||||
| #include <boost/detail/sp_typeinfo.hpp> | ||||
| 
 | ||||
| namespace boost | ||||
| { | ||||
| @@ -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 "sp_typeinfo.hpp" | ||||
| #include <boost/detail/sp_typeinfo.hpp> | ||||
| 
 | ||||
| namespace boost | ||||
| { | ||||
| @@ -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 "sp_typeinfo.hpp" | ||||
| #include <boost/detail/sp_typeinfo.hpp> | ||||
| 
 | ||||
| namespace boost | ||||
| { | ||||
| @@ -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
 | ||||
							
								
								
									
										172
									
								
								include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										172
									
								
								include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,172 @@ | ||||
| #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" | ||||
|         "ll %0, %1\n\t" | ||||
|         "addiu %0, 1\n\t" | ||||
|         "sc %0, %1\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" | ||||
|         "ll %1, %2\n\t" | ||||
|         "addiu %0, %1, -1\n\t" | ||||
|         "sc %0, %2\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" | ||||
|         "ll %0, %2\n\t" | ||||
|         "beqz %0, 1f\n\t" | ||||
|         "addiu %1, %0, 1\n\t" | ||||
|         "sc %1, %2\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 "sp_typeinfo.hpp" | ||||
| #include <boost/detail/sp_typeinfo.hpp> | ||||
| 
 | ||||
| namespace boost | ||||
| { | ||||
| @@ -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
 | ||||
| @@ -1,5 +1,5 @@ | ||||
| #ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED | ||||
| #define BOOST_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED | ||||
| #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
 | ||||
| 
 | ||||
| @@ -19,7 +19,7 @@ | ||||
| //
 | ||||
| //  Thanks to Michael van der Westhuizen
 | ||||
| 
 | ||||
| #include "sp_typeinfo.hpp" | ||||
| #include <boost/detail/sp_typeinfo.hpp> | ||||
| #include <inttypes.h> // int32_t
 | ||||
| 
 | ||||
| namespace boost | ||||
| @@ -163,4 +163,4 @@ public: | ||||
| 
 | ||||
| } // namespace boost
 | ||||
| 
 | ||||
| #endif  // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED
 | ||||
| #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 "sp_typeinfo.hpp" | ||||
| #include <boost/detail/sp_typeinfo.hpp> | ||||
| 
 | ||||
| namespace boost | ||||
| { | ||||
| @@ -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 "sp_typeinfo.hpp" | ||||
| #include <boost/detail/sp_typeinfo.hpp> | ||||
| 
 | ||||
| namespace boost | ||||
| { | ||||
| @@ -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 "sp_typeinfo.hpp" | ||||
| #include <boost/detail/sp_typeinfo.hpp> | ||||
| #include <pthread.h> | ||||
| 
 | ||||
| namespace boost | ||||
| @@ -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
 | ||||
| @@ -1,5 +1,5 @@ | ||||
| #ifndef BOOST_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED | ||||
| #define BOOST_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED | ||||
| #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
 | ||||
| @@ -20,7 +20,7 @@ | ||||
| //  formulation
 | ||||
| //
 | ||||
| 
 | ||||
| #include "sp_typeinfo.hpp" | ||||
| #include <boost/detail/sp_typeinfo.hpp> | ||||
| #include <atomic.h> | ||||
| 
 | ||||
| namespace boost | ||||
| @@ -110,4 +110,4 @@ public: | ||||
| 
 | ||||
| } // namespace boost
 | ||||
| 
 | ||||
| #endif  // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED
 | ||||
| #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 | ||||
| @@ -1,5 +1,5 @@ | ||||
| #ifndef BOOST_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED | ||||
| #define BOOST_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED | ||||
| #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
 | ||||
| 
 | ||||
| @@ -15,9 +15,13 @@ | ||||
| //  See accompanying file LICENSE_1_0.txt or copy at
 | ||||
| //  http://www.boost.org/LICENSE_1_0.txt
 | ||||
| 
 | ||||
| #include "sp_typeinfo.hpp" | ||||
| #include <boost/detail/sp_typeinfo.hpp> | ||||
| #include <limits.h> | ||||
| 
 | ||||
| #if defined( __ia64__ ) && defined( __INTEL_COMPILER ) | ||||
| # include <ia64intrin.h> | ||||
| #endif | ||||
| 
 | ||||
| namespace boost | ||||
| { | ||||
| 
 | ||||
| @@ -148,4 +152,4 @@ public: | ||||
| 
 | ||||
| } // namespace boost
 | ||||
| 
 | ||||
| #endif  // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED
 | ||||
| #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 "sp_typeinfo.hpp" | ||||
| #include <boost/detail/sp_typeinfo.hpp> | ||||
| 
 | ||||
| namespace boost | ||||
| { | ||||
| @@ -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,10 +25,10 @@ | ||||
| #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) | ||||
| @@ -228,4 +228,4 @@ public: | ||||
| 
 | ||||
| } // namespace boost
 | ||||
| 
 | ||||
| #endif  // #ifndef BOOST_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
 | ||||
| #endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
 | ||||
							
								
								
									
										49
									
								
								include/boost/smart_ptr/detail/sp_has_sync.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								include/boost/smart_ptr/detail/sp_has_sync.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,49 @@ | ||||
| #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 ) | ||||
|  | ||||
| #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( __sparc__ ) | ||||
| #undef BOOST_SP_HAS_SYNC | ||||
| #endif | ||||
|  | ||||
| #if defined( __INTEL_COMPILER ) && !defined( __ia64__ ) | ||||
| #undef BOOST_SP_HAS_SYNC | ||||
| #endif | ||||
|  | ||||
| #endif // __GNUC__ * 100 + __GNUC_MINOR__ >= 401 | ||||
|  | ||||
| #endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_HPP_INCLUDED | ||||
							
								
								
									
										53
									
								
								include/boost/smart_ptr/detail/spinlock.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								include/boost/smart_ptr/detail/spinlock.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,53 @@ | ||||
| #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(__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 | ||||
							
								
								
									
										85
									
								
								include/boost/smart_ptr/detail/spinlock_gcc_arm.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								include/boost/smart_ptr/detail/spinlock_gcc_arm.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,85 @@ | ||||
| #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED | ||||
| #define BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED | ||||
|  | ||||
| // | ||||
| //  Copyright (c) 2008 Peter Dimov | ||||
| // | ||||
| //  Distributed under the Boost Software License, Version 1.0. | ||||
| //  See accompanying file LICENSE_1_0.txt or copy at | ||||
| //  http://www.boost.org/LICENSE_1_0.txt) | ||||
| // | ||||
|  | ||||
| #include <boost/smart_ptr/detail/yield_k.hpp> | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| class spinlock | ||||
| { | ||||
| public: | ||||
|  | ||||
|     int v_; | ||||
|  | ||||
| public: | ||||
|  | ||||
|     bool try_lock() | ||||
|     { | ||||
|         int r; | ||||
|  | ||||
|         __asm__ __volatile__( | ||||
|             "swp %0, %1, [%2]": | ||||
|             "=&r"( r ): // outputs | ||||
|             "r"( 1 ), "r"( &v_ ): // inputs | ||||
|             "memory", "cc" ); | ||||
|  | ||||
|         return r == 0; | ||||
|     } | ||||
|  | ||||
|     void lock() | ||||
|     { | ||||
|         for( unsigned k = 0; !try_lock(); ++k ) | ||||
|         { | ||||
|             boost::detail::yield( k ); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     void unlock() | ||||
|     { | ||||
|         __asm__ __volatile__( "" ::: "memory" ); | ||||
|         *const_cast< int volatile* >( &v_ ) = 0; | ||||
|     } | ||||
|  | ||||
| public: | ||||
|  | ||||
|     class scoped_lock | ||||
|     { | ||||
|     private: | ||||
|  | ||||
|         spinlock & sp_; | ||||
|  | ||||
|         scoped_lock( scoped_lock const & ); | ||||
|         scoped_lock & operator=( scoped_lock const & ); | ||||
|  | ||||
|     public: | ||||
|  | ||||
|         explicit scoped_lock( spinlock & sp ): sp_( sp ) | ||||
|         { | ||||
|             sp.lock(); | ||||
|         } | ||||
|  | ||||
|         ~scoped_lock() | ||||
|         { | ||||
|             sp_.unlock(); | ||||
|         } | ||||
|     }; | ||||
| }; | ||||
|  | ||||
| } // namespace detail | ||||
| } // namespace boost | ||||
|  | ||||
| #define BOOST_DETAIL_SPINLOCK_INIT {0} | ||||
|  | ||||
| #endif // #ifndef BOOST_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 | ||||
							
								
								
									
										87
									
								
								include/boost/smart_ptr/detail/spinlock_pool.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								include/boost/smart_ptr/detail/spinlock_pool.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,87 @@ | ||||
| #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 ) | ||||
|     { | ||||
|         std::size_t i = reinterpret_cast< std::size_t >( pv ) % 41; | ||||
|         return pool_[ i ]; | ||||
|     } | ||||
|  | ||||
|     class scoped_lock | ||||
|     { | ||||
|     private: | ||||
|  | ||||
|         spinlock & sp_; | ||||
|  | ||||
|         scoped_lock( scoped_lock const & ); | ||||
|         scoped_lock & operator=( scoped_lock const & ); | ||||
|  | ||||
|     public: | ||||
|  | ||||
|         explicit scoped_lock( void const * pv ): sp_( spinlock_for( pv ) ) | ||||
|         { | ||||
|             sp_.lock(); | ||||
|         } | ||||
|  | ||||
|         ~scoped_lock() | ||||
|         { | ||||
|             sp_.unlock(); | ||||
|         } | ||||
|     }; | ||||
| }; | ||||
|  | ||||
| template< int I > spinlock spinlock_pool< I >::pool_[ 41 ] = | ||||
| { | ||||
|     BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,  | ||||
|     BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,  | ||||
|     BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,  | ||||
|     BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,  | ||||
|     BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,  | ||||
|     BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,  | ||||
|     BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,  | ||||
|     BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,  | ||||
|     BOOST_DETAIL_SPINLOCK_INIT | ||||
| }; | ||||
|  | ||||
| } // namespace detail | ||||
| } // namespace boost | ||||
|  | ||||
| #endif // #ifndef BOOST_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 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> | ||||
|  | ||||
| #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 <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 detail::sp_enable_if_convertible<U,T>::type = 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(std::move(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) | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #ifdef BOOST_MSVC | ||||
| # pragma warning(pop) | ||||
| #endif     | ||||
|  | ||||
| #endif  // #ifndef BOOST_SMART_PTR_INTRUSIVE_PTR_HPP_INCLUDED | ||||
							
								
								
									
										504
									
								
								include/boost/smart_ptr/make_shared.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										504
									
								
								include/boost/smart_ptr/make_shared.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,504 @@ | ||||
| #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_ ) | ||||
|         { | ||||
|             reinterpret_cast< T* >( storage_.data_ )->~T(); | ||||
|             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; | ||||
|     } | ||||
| }; | ||||
|  | ||||
| template< class T > T forward( T t ) | ||||
| { | ||||
|     return t; | ||||
| } | ||||
|  | ||||
| } // namespace detail | ||||
|  | ||||
| // Zero-argument versions | ||||
| // | ||||
| // Used even when variadic templates are available because of the new T() vs new T issue | ||||
|  | ||||
| template< class T > boost::shared_ptr< T > make_shared() | ||||
| { | ||||
|     boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() ); | ||||
|  | ||||
|     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt ); | ||||
|  | ||||
|     void * pv = pd->address(); | ||||
|  | ||||
|     ::new( pv ) T(); | ||||
|     pd->set_initialized(); | ||||
|  | ||||
|     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 ), detail::sp_ms_deleter< T >(), a ); | ||||
|  | ||||
|     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt ); | ||||
|  | ||||
|     void * pv = pd->address(); | ||||
|  | ||||
|     ::new( pv ) T(); | ||||
|     pd->set_initialized(); | ||||
|  | ||||
|     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... Args > boost::shared_ptr< T > make_shared( Args && ... args ) | ||||
| { | ||||
|     boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() ); | ||||
|  | ||||
|     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt ); | ||||
|  | ||||
|     void * pv = pd->address(); | ||||
|  | ||||
|     ::new( pv ) T( detail::forward<Args>( args )... ); | ||||
|     pd->set_initialized(); | ||||
|  | ||||
|     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... Args > boost::shared_ptr< T > allocate_shared( A const & a, Args && ... args ) | ||||
| { | ||||
|     boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a ); | ||||
|  | ||||
|     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt ); | ||||
|  | ||||
|     void * pv = pd->address(); | ||||
|  | ||||
|     ::new( pv ) T( detail::forward<Args>( args )... ); | ||||
|     pd->set_initialized(); | ||||
|  | ||||
|     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 ), detail::sp_ms_deleter< T >() ); | ||||
|  | ||||
|     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt ); | ||||
|  | ||||
|     void * pv = pd->address(); | ||||
|  | ||||
|     ::new( pv ) T( a1 ); | ||||
|     pd->set_initialized(); | ||||
|  | ||||
|     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 ), detail::sp_ms_deleter< T >(), a ); | ||||
|  | ||||
|     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt ); | ||||
|  | ||||
|     void * pv = pd->address(); | ||||
|  | ||||
|     ::new( pv ) T( a1 ); | ||||
|     pd->set_initialized(); | ||||
|  | ||||
|     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 ), detail::sp_ms_deleter< T >() ); | ||||
|  | ||||
|     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt ); | ||||
|  | ||||
|     void * pv = pd->address(); | ||||
|  | ||||
|     ::new( pv ) T( a1, a2 ); | ||||
|     pd->set_initialized(); | ||||
|  | ||||
|     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 ), detail::sp_ms_deleter< T >(), a ); | ||||
|  | ||||
|     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt ); | ||||
|  | ||||
|     void * pv = pd->address(); | ||||
|  | ||||
|     ::new( pv ) T( a1, a2 ); | ||||
|     pd->set_initialized(); | ||||
|  | ||||
|     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 ), detail::sp_ms_deleter< T >() ); | ||||
|  | ||||
|     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt ); | ||||
|  | ||||
|     void * pv = pd->address(); | ||||
|  | ||||
|     ::new( pv ) T( a1, a2, a3 ); | ||||
|     pd->set_initialized(); | ||||
|  | ||||
|     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 ), detail::sp_ms_deleter< T >(), a ); | ||||
|  | ||||
|     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt ); | ||||
|  | ||||
|     void * pv = pd->address(); | ||||
|  | ||||
|     ::new( pv ) T( a1, a2, a3 ); | ||||
|     pd->set_initialized(); | ||||
|  | ||||
|     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 ), detail::sp_ms_deleter< T >() ); | ||||
|  | ||||
|     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt ); | ||||
|  | ||||
|     void * pv = pd->address(); | ||||
|  | ||||
|     ::new( pv ) T( a1, a2, a3, a4 ); | ||||
|     pd->set_initialized(); | ||||
|  | ||||
|     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 ), detail::sp_ms_deleter< T >(), a ); | ||||
|  | ||||
|     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt ); | ||||
|  | ||||
|     void * pv = pd->address(); | ||||
|  | ||||
|     ::new( pv ) T( a1, a2, a3, a4 ); | ||||
|     pd->set_initialized(); | ||||
|  | ||||
|     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 ), detail::sp_ms_deleter< T >() ); | ||||
|  | ||||
|     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt ); | ||||
|  | ||||
|     void * pv = pd->address(); | ||||
|  | ||||
|     ::new( pv ) T( a1, a2, a3, a4, a5 ); | ||||
|     pd->set_initialized(); | ||||
|  | ||||
|     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 ), detail::sp_ms_deleter< T >(), a ); | ||||
|  | ||||
|     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt ); | ||||
|  | ||||
|     void * pv = pd->address(); | ||||
|  | ||||
|     ::new( pv ) T( a1, a2, a3, a4, a5 ); | ||||
|     pd->set_initialized(); | ||||
|  | ||||
|     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 ), detail::sp_ms_deleter< T >() ); | ||||
|  | ||||
|     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt ); | ||||
|  | ||||
|     void * pv = pd->address(); | ||||
|  | ||||
|     ::new( pv ) T( a1, a2, a3, a4, a5, a6 ); | ||||
|     pd->set_initialized(); | ||||
|  | ||||
|     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 ), detail::sp_ms_deleter< T >(), a ); | ||||
|  | ||||
|     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt ); | ||||
|  | ||||
|     void * pv = pd->address(); | ||||
|  | ||||
|     ::new( pv ) T( a1, a2, a3, a4, a5, a6 ); | ||||
|     pd->set_initialized(); | ||||
|  | ||||
|     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 ), detail::sp_ms_deleter< T >() ); | ||||
|  | ||||
|     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt ); | ||||
|  | ||||
|     void * pv = pd->address(); | ||||
|  | ||||
|     ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7 ); | ||||
|     pd->set_initialized(); | ||||
|  | ||||
|     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 ), detail::sp_ms_deleter< T >(), a ); | ||||
|  | ||||
|     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt ); | ||||
|  | ||||
|     void * pv = pd->address(); | ||||
|  | ||||
|     ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7 ); | ||||
|     pd->set_initialized(); | ||||
|  | ||||
|     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 ), detail::sp_ms_deleter< T >() ); | ||||
|  | ||||
|     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt ); | ||||
|  | ||||
|     void * pv = pd->address(); | ||||
|  | ||||
|     ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8 ); | ||||
|     pd->set_initialized(); | ||||
|  | ||||
|     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 ), detail::sp_ms_deleter< T >(), a ); | ||||
|  | ||||
|     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt ); | ||||
|  | ||||
|     void * pv = pd->address(); | ||||
|  | ||||
|     ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8 ); | ||||
|     pd->set_initialized(); | ||||
|  | ||||
|     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 ), detail::sp_ms_deleter< T >() ); | ||||
|  | ||||
|     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt ); | ||||
|  | ||||
|     void * pv = pd->address(); | ||||
|  | ||||
|     ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8, a9 ); | ||||
|     pd->set_initialized(); | ||||
|  | ||||
|     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 ), detail::sp_ms_deleter< T >(), a ); | ||||
|  | ||||
|     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt ); | ||||
|  | ||||
|     void * pv = pd->address(); | ||||
|  | ||||
|     ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8, a9 ); | ||||
|     pd->set_initialized(); | ||||
|  | ||||
|     T * pt2 = static_cast< T* >( pv ); | ||||
|  | ||||
|     boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); | ||||
|     return boost::shared_ptr< T >( pt, pt2 ); | ||||
| } | ||||
|  | ||||
| #endif | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #endif // #ifndef BOOST_SMART_PTR_MAKE_SHARED_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 | ||||
							
								
								
									
										147
									
								
								include/boost/smart_ptr/shared_array.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										147
									
								
								include/boost/smart_ptr/shared_array.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,147 @@ | ||||
| #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, 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" | ||||
| #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); | ||||
|     } | ||||
|  | ||||
| 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) | ||||
|  | ||||
| #endif  // #ifndef BOOST_SMART_PTR_SHARED_ARRAY_HPP_INCLUDED | ||||
							
								
								
									
										701
									
								
								include/boost/smart_ptr/shared_ptr.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										701
									
								
								include/boost/smart_ptr/shared_ptr.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,701 @@ | ||||
| #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 | ||||
|  | ||||
| #if !defined(BOOST_NO_IOSTREAM) | ||||
| #if !defined(BOOST_NO_IOSFWD) | ||||
| #include <iosfwd>               // for std::basic_ostream | ||||
| #else | ||||
| #include <ostream> | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
| #ifdef BOOST_MSVC  // moved here to work around VC++ compiler crash | ||||
| # pragma warning(push) | ||||
| # pragma warning(disable:4284) // odd return type for operator-> | ||||
| #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 | ||||
|  | ||||
|     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 detail::sp_enable_if_convertible<Y,T>::type = detail::sp_empty() ) | ||||
|  | ||||
| #else | ||||
|  | ||||
|     shared_ptr( shared_ptr<Y> const & r ) | ||||
|  | ||||
| #endif | ||||
|     : px( r.px ), pn( r.pn ) // never throws | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     // aliasing | ||||
|     template< class Y > | ||||
|     shared_ptr( shared_ptr<Y> const & r, T * p ): px( p ), pn( r.pn ) // never throws | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     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 detail::sp_enable_if_convertible<Y,T>::type = detail::sp_empty() ) | ||||
|  | ||||
| #else | ||||
|  | ||||
|     shared_ptr( shared_ptr<Y> && r ) | ||||
|  | ||||
| #endif | ||||
|     : px( r.px ), pn() // never throws | ||||
|     { | ||||
|         pn.swap( r.pn ); | ||||
|         r.px = 0; | ||||
|     } | ||||
|  | ||||
|     shared_ptr & operator=( shared_ptr && r ) // never throws | ||||
|     { | ||||
|         this_type( std::move( r ) ).swap( *this ); | ||||
|         return *this; | ||||
|     } | ||||
|  | ||||
|     template<class Y> | ||||
|     shared_ptr & operator=( shared_ptr<Y> && r ) // never throws | ||||
|     { | ||||
|         this_type( std::move( 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 _internal_less(shared_ptr<Y> const & rhs) const | ||||
|     { | ||||
|         return pn < rhs.pn; | ||||
|     } | ||||
|  | ||||
|     void * _internal_get_deleter( 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._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(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 | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #ifdef BOOST_MSVC | ||||
| # pragma warning(pop) | ||||
| #endif | ||||
|  | ||||
| #endif  // #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES) | ||||
|  | ||||
| #endif  // #ifndef BOOST_SMART_PTR_SHARED_PTR_HPP_INCLUDED | ||||
							
								
								
									
										230
									
								
								include/boost/smart_ptr/weak_ptr.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										230
									
								
								include/boost/smart_ptr/weak_ptr.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,230 @@ | ||||
| #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> | ||||
|  | ||||
| #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> | ||||
| #if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) | ||||
|  | ||||
|     weak_ptr( weak_ptr<Y> const & r, typename detail::sp_enable_if_convertible<Y,T>::type = detail::sp_empty() ) | ||||
|  | ||||
| #else | ||||
|  | ||||
|     weak_ptr( weak_ptr<Y> const & r ) | ||||
|  | ||||
| #endif | ||||
|     : 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 detail::sp_enable_if_convertible<Y,T>::type = detail::sp_empty() ) | ||||
|  | ||||
| #else | ||||
|  | ||||
|     weak_ptr( weak_ptr<Y> && r ) | ||||
|  | ||||
| #endif | ||||
|     : px(r.lock().get()), pn(std::move(r.pn)) // never throws | ||||
|     { | ||||
|         r.px = 0; | ||||
|     } | ||||
|  | ||||
|     // for better efficiency in the T == Y case | ||||
|     weak_ptr( weak_ptr && r ): px( r.px ), pn(std::move(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( std::move( r ) ).swap( *this ); | ||||
|         return *this; | ||||
|     } | ||||
|  | ||||
|  | ||||
| #endif | ||||
|  | ||||
|     template<class Y> | ||||
| #if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) | ||||
|  | ||||
|     weak_ptr( shared_ptr<Y> const & r, typename detail::sp_enable_if_convertible<Y,T>::type = detail::sp_empty() ) | ||||
|  | ||||
| #else | ||||
|  | ||||
|     weak_ptr( shared_ptr<Y> const & r ) | ||||
|  | ||||
| #endif | ||||
|     : px( r.px ), pn( r.pn ) // never throws | ||||
|     { | ||||
|     } | ||||
|  | ||||
| #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( std::move( 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 _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); | ||||
| } | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #ifdef BOOST_MSVC | ||||
| # pragma warning(pop) | ||||
| #endif     | ||||
|  | ||||
| #endif  // #ifndef BOOST_SMART_PTR_WEAK_PTR_HPP_INCLUDED | ||||
| @@ -6,183 +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); | ||||
| } | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #ifdef BOOST_MSVC | ||||
| # pragma warning(pop) | ||||
| #endif     | ||||
| #include <boost/smart_ptr/weak_ptr.hpp> | ||||
|  | ||||
| #endif  // #ifndef BOOST_WEAK_PTR_HPP_INCLUDED | ||||
|   | ||||
| @@ -62,6 +62,8 @@ | ||||
|       intrusive_ptr & <A href="#assignment" >operator=</A>(intrusive_ptr const & r); | ||||
|       template<class Y> intrusive_ptr & <A href="#assignment" >operator=</A>(intrusive_ptr<Y> const & r); | ||||
|       intrusive_ptr & <A href="#assignment" >operator=</A>(T * r); | ||||
|  | ||||
|       void <a href="#reset" >reset</a>(); | ||||
|       void <a href="#reset" >reset</a>(T * r); | ||||
|  | ||||
|       T & <A href="#indirection" >operator*</A>() const; // never throws | ||||
| @@ -148,6 +150,10 @@ intrusive_ptr & operator=(T * r);</pre> | ||||
| 			<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> | ||||
|   | ||||
							
								
								
									
										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> | ||||
| @@ -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 | ||||
|   | ||||
							
								
								
									
										318
									
								
								shared_ptr.htm
									
									
									
									
									
								
							
							
						
						
									
										318
									
								
								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 { | ||||
|  | ||||
| @@ -115,7 +120,7 @@ void bad() | ||||
|       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); | ||||
|  | ||||
| @@ -178,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> | ||||
| @@ -212,46 +217,46 @@ 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> | ||||
| @@ -268,21 +273,21 @@ template<class Y> shared_ptr(shared_ptr<Y> const & r); // never | ||||
| 				<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> | ||||
| @@ -290,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> | ||||
| @@ -309,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); | ||||
| @@ -365,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> | ||||
| @@ -422,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> | ||||
| @@ -443,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> | ||||
| @@ -464,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> | ||||
| @@ -479,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> | ||||
| @@ -498,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> | ||||
| @@ -520,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> | ||||
| @@ -600,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> | ||||
| @@ -613,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); | ||||
| @@ -691,26 +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. Distributed under the Boost Software License, Version  | ||||
| 			1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or  | ||||
| 			copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p> | ||||
| 		<p><small>Copyright 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> | ||||
|   | ||||
							
								
								
									
										159
									
								
								smart_ptr.htm
									
									
									
									
									
								
							
							
						
						
									
										159
									
								
								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,126 +58,137 @@ | ||||
| 			</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="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><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.  | ||||
| 		<p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. | ||||
| 			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> | ||||
|   | ||||
| @@ -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) | ||||
|         { | ||||
|   | ||||
| @@ -16,9 +16,11 @@ 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 ] | ||||
| @@ -33,5 +35,31 @@ import testing ; | ||||
|           [ run shared_ptr_move_test.cpp ] | ||||
|           [ compile-fail shared_ptr_pv_fail.cpp ] | ||||
|           [ run sp_unary_addr_test.cpp ] | ||||
|           [ compile-fail scoped_ptr_eq_fail.cpp ] | ||||
|           [ compile-fail scoped_array_eq_fail.cpp ] | ||||
|           [ run esft_regtest.cpp ] | ||||
|           [ run yield_k_test.cpp ] | ||||
|           [ run yield_k_test.cpp : : : <threading>multi : yield_k_test.mt ] | ||||
|           [ run spinlock_test.cpp ] | ||||
|           [ run spinlock_try_test.cpp ] | ||||
|           [ run spinlock_try_test.cpp : : : <threading>multi : spinlock_try_test.mt ] | ||||
|           [ run spinlock_pool_test.cpp ] | ||||
|           [ run make_shared_test.cpp ] | ||||
|           [ run sp_convertible_test.cpp ] | ||||
|           [ run wp_convertible_test.cpp ] | ||||
|           [ run ip_convertible_test.cpp ] | ||||
|           [ run allocate_shared_test.cpp ] | ||||
|           [ run sp_atomic_test.cpp ] | ||||
|           [ 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 ] | ||||
|         ; | ||||
| } | ||||
|   | ||||
							
								
								
									
										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(); | ||||
| } | ||||
							
								
								
									
										184
									
								
								test/intrusive_ptr_move_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										184
									
								
								test/intrusive_ptr_move_test.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,184 @@ | ||||
| #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 <algorithm> | ||||
| #include <functional> | ||||
|  | ||||
| #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(); | ||||
| } | ||||
							
								
								
									
										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(); | ||||
| } | ||||
							
								
								
									
										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(); | ||||
| } | ||||
| @@ -1,7 +1,7 @@ | ||||
| // | ||||
| //  pointer_cast_test.cpp - a test for boost/pointer_cast.hpp | ||||
| // | ||||
| //  Copyright (c) 2005 Ion Gazta<EFBFBD>aga | ||||
| //  Copyright (c) 2005 Ion Gaztanaga | ||||
| //  Copyright (c) 2005 Peter Dimov | ||||
| // | ||||
| // Distributed under the Boost Software License, Version 1.0. (See | ||||
|   | ||||
							
								
								
									
										27
									
								
								test/scoped_array_eq_fail.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								test/scoped_array_eq_fail.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | ||||
| #include <boost/config.hpp> | ||||
|  | ||||
| #if defined(BOOST_MSVC) | ||||
| #pragma warning(disable: 4786)  // identifier truncated in debug info | ||||
| #pragma warning(disable: 4710)  // function not inlined | ||||
| #pragma warning(disable: 4711)  // function selected for automatic inline expansion | ||||
| #pragma warning(disable: 4514)  // unreferenced inline removed | ||||
| #endif | ||||
|  | ||||
| // | ||||
| // scoped_array_eq_fail.cpp - a negative test for "p == q" | ||||
| // | ||||
| // Copyright (c) 2008 Peter Dimov | ||||
| // | ||||
| // Distributed under the Boost Software License, Version 1.0. (See | ||||
| // accompanying file LICENSE_1_0.txt or copy at | ||||
| // http://www.boost.org/LICENSE_1_0.txt) | ||||
| // | ||||
|  | ||||
| #include <boost/scoped_array.hpp> | ||||
|  | ||||
| int main() | ||||
| { | ||||
|     boost::scoped_array<int> p, q; | ||||
|     p == q; // must fail | ||||
|     return 0; | ||||
| } | ||||
							
								
								
									
										27
									
								
								test/scoped_ptr_eq_fail.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								test/scoped_ptr_eq_fail.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | ||||
| #include <boost/config.hpp> | ||||
|  | ||||
| #if defined(BOOST_MSVC) | ||||
| #pragma warning(disable: 4786)  // identifier truncated in debug info | ||||
| #pragma warning(disable: 4710)  // function not inlined | ||||
| #pragma warning(disable: 4711)  // function selected for automatic inline expansion | ||||
| #pragma warning(disable: 4514)  // unreferenced inline removed | ||||
| #endif | ||||
|  | ||||
| // | ||||
| // scoped_ptr_eq_fail.cpp - a negative test for "p == q" | ||||
| // | ||||
| // Copyright (c) 2008 Peter Dimov | ||||
| // | ||||
| // Distributed under the Boost Software License, Version 1.0. (See | ||||
| // accompanying file LICENSE_1_0.txt or copy at | ||||
| // http://www.boost.org/LICENSE_1_0.txt) | ||||
| // | ||||
|  | ||||
| #include <boost/scoped_ptr.hpp> | ||||
|  | ||||
| int main() | ||||
| { | ||||
|     boost::scoped_ptr<int> p, q; | ||||
|     p == q; // must fail | ||||
|     return 0; | ||||
| } | ||||
| @@ -55,16 +55,23 @@ void test() | ||||
|     BOOST_TEST(py.get() != 0); | ||||
|     BOOST_TEST(py.use_count() == 1); | ||||
|  | ||||
|     boost::shared_ptr<X> px = py->getX(); | ||||
|     BOOST_TEST(px.get() != 0); | ||||
|     BOOST_TEST(py.use_count() == 2); | ||||
|     try | ||||
|     { | ||||
|         boost::shared_ptr<X> px = py->getX(); | ||||
|         BOOST_TEST(px.get() != 0); | ||||
|         BOOST_TEST(py.use_count() == 2); | ||||
|  | ||||
|     px->f(); | ||||
|         px->f(); | ||||
|  | ||||
|     boost::shared_ptr<Y> py2 = boost::dynamic_pointer_cast<Y>(px); | ||||
|     BOOST_TEST(py.get() == py2.get()); | ||||
|     BOOST_TEST(!(py < py2 || py2 < py)); | ||||
|     BOOST_TEST(py.use_count() == 3); | ||||
|         boost::shared_ptr<Y> py2 = boost::dynamic_pointer_cast<Y>(px); | ||||
|         BOOST_TEST(py.get() == py2.get()); | ||||
|         BOOST_TEST(!(py < py2 || py2 < py)); | ||||
|         BOOST_TEST(py.use_count() == 3); | ||||
|     } | ||||
|     catch( boost::bad_weak_ptr const& ) | ||||
|     { | ||||
|         BOOST_ERROR( "py->getX() failed" ); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void test2(); | ||||
| @@ -124,9 +131,16 @@ void test3() | ||||
| { | ||||
|     boost::shared_ptr<V> p(new V); | ||||
|  | ||||
|     boost::shared_ptr<V> q = p->shared_from_this(); | ||||
|     BOOST_TEST(p == q); | ||||
|     BOOST_TEST(!(p < q) && !(q < p)); | ||||
|     try | ||||
|     { | ||||
|         boost::shared_ptr<V> q = p->shared_from_this(); | ||||
|         BOOST_TEST(p == q); | ||||
|         BOOST_TEST(!(p < q) && !(q < p)); | ||||
|     } | ||||
|     catch( boost::bad_weak_ptr const & ) | ||||
|     { | ||||
|         BOOST_ERROR( "p->shared_from_this() failed" ); | ||||
|     } | ||||
|  | ||||
|     V v2(*p); | ||||
|  | ||||
| @@ -135,7 +149,7 @@ void test3() | ||||
|         boost::shared_ptr<V> r = v2.shared_from_this(); | ||||
|         BOOST_ERROR("v2.shared_from_this() failed to throw"); | ||||
|     } | ||||
|     catch(boost::bad_weak_ptr const &) | ||||
|     catch( boost::bad_weak_ptr const & ) | ||||
|     { | ||||
|     } | ||||
|  | ||||
| @@ -146,7 +160,7 @@ void test3() | ||||
|         BOOST_TEST(p == r); | ||||
|         BOOST_TEST(!(p < r) && !(r < p)); | ||||
|     } | ||||
|     catch(boost::bad_weak_ptr const &) | ||||
|     catch( boost::bad_weak_ptr const & ) | ||||
|     { | ||||
|         BOOST_ERROR("p->shared_from_this() threw bad_weak_ptr after *p = V()"); | ||||
|     } | ||||
|   | ||||
| @@ -11,6 +11,8 @@ | ||||
| #include <boost/shared_ptr.hpp> | ||||
| #include <boost/detail/lightweight_test.hpp> | ||||
|  | ||||
| #if defined( BOOST_HAS_RVALUE_REFS ) | ||||
|  | ||||
| struct X | ||||
| { | ||||
|     static long instances; | ||||
| @@ -41,11 +43,11 @@ int main() | ||||
|         boost::shared_ptr<X> p( new X ); | ||||
|         BOOST_TEST( X::instances == 1 ); | ||||
|  | ||||
|         boost::shared_ptr<X> p2( static_cast< boost::shared_ptr<X> && >( p ) ); | ||||
|         boost::shared_ptr<X> p2( std::move( p ) ); | ||||
|         BOOST_TEST( X::instances == 1 ); | ||||
|         BOOST_TEST( p.get() == 0 ); | ||||
|  | ||||
|         boost::shared_ptr<void> p3( static_cast< boost::shared_ptr<X> && >( p2 ) ); | ||||
|         boost::shared_ptr<void> p3( std::move( p2 ) ); | ||||
|         BOOST_TEST( X::instances == 1 ); | ||||
|         BOOST_TEST( p2.get() == 0 ); | ||||
|  | ||||
| @@ -58,12 +60,12 @@ int main() | ||||
|         BOOST_TEST( X::instances == 1 ); | ||||
|  | ||||
|         boost::shared_ptr<X> p2; | ||||
|         p2 = static_cast< boost::shared_ptr<X> && >( p ); | ||||
|         p2 = std::move( p ); | ||||
|         BOOST_TEST( X::instances == 1 ); | ||||
|         BOOST_TEST( p.get() == 0 ); | ||||
|  | ||||
|         boost::shared_ptr<void> p3; | ||||
|         p3 = static_cast< boost::shared_ptr<X> && >( p2 ); | ||||
|         p3 = std::move( p2 ); | ||||
|         BOOST_TEST( X::instances == 1 ); | ||||
|         BOOST_TEST( p2.get() == 0 ); | ||||
|  | ||||
| @@ -77,13 +79,13 @@ int main() | ||||
|  | ||||
|         boost::shared_ptr<X> p2( new X ); | ||||
|         BOOST_TEST( X::instances == 2 ); | ||||
|         p2 = static_cast< boost::shared_ptr<X> && >( p ); | ||||
|         p2 = std::move( p ); | ||||
|         BOOST_TEST( X::instances == 1 ); | ||||
|         BOOST_TEST( p.get() == 0 ); | ||||
|  | ||||
|         boost::shared_ptr<void> p3( new X ); | ||||
|         BOOST_TEST( X::instances == 2 ); | ||||
|         p3 = static_cast< boost::shared_ptr<X> && >( p2 ); | ||||
|         p3 = std::move( p2 ); | ||||
|         BOOST_TEST( X::instances == 1 ); | ||||
|         BOOST_TEST( p2.get() == 0 ); | ||||
|  | ||||
| @@ -93,3 +95,12 @@ int main() | ||||
|  | ||||
|     return boost::report_errors(); | ||||
| } | ||||
|  | ||||
| #else // !defined( BOOST_HAS_RVALUE_REFS ) | ||||
|  | ||||
| int main() | ||||
| { | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -7,167 +7,76 @@ | ||||
| #pragma warning(disable: 4514)  // unreferenced inline removed | ||||
| #endif | ||||
|  | ||||
| // | ||||
| //  shared_ptr_mt_test.cpp - tests shared_ptr with multiple threads | ||||
| // | ||||
| //  Copyright (c) 2002 Peter Dimov and Multi Media Ltd. | ||||
| //  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) | ||||
| // | ||||
| //  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/bind.hpp> | ||||
|  | ||||
| #include <vector> | ||||
| #include <memory> | ||||
| #include <stdexcept> | ||||
|  | ||||
| #include <cstdio> | ||||
| #include <ctime> | ||||
|  | ||||
| // 'portable' thread framework | ||||
|  | ||||
| class abstract_thread | ||||
| { | ||||
| public: | ||||
|  | ||||
|     virtual ~abstract_thread() {} | ||||
|     virtual void run() = 0; | ||||
| }; | ||||
|  | ||||
| #if !defined(BOOST_HAS_PTHREADS) && defined(BOOST_HAS_WINTHREADS) | ||||
|  | ||||
| char const * title = "Using Windows threads"; | ||||
|  | ||||
| #include <windows.h> | ||||
| #include <process.h> | ||||
|  | ||||
| typedef HANDLE pthread_t; | ||||
|  | ||||
| unsigned __stdcall common_thread_routine(void * pv) | ||||
| { | ||||
|     abstract_thread * pt = static_cast<abstract_thread *>(pv); | ||||
|     pt->run(); | ||||
|     delete pt; | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| int pthread_create(pthread_t * thread, void const *, unsigned (__stdcall * start_routine) (void*), void* arg) | ||||
| { | ||||
|     HANDLE h = (HANDLE)_beginthreadex(0, 0, start_routine, arg, 0, 0); | ||||
|  | ||||
|     if(h != 0) | ||||
|     { | ||||
|         *thread = h; | ||||
|         return 0; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         return 1; // return errno; | ||||
|     } | ||||
| } | ||||
|  | ||||
| int pthread_join(pthread_t thread, void ** /*value_ptr*/) | ||||
| { | ||||
|     ::WaitForSingleObject(thread, INFINITE); | ||||
|     ::CloseHandle(thread); | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| #else | ||||
|  | ||||
| char const * title = "Using POSIX threads"; | ||||
|  | ||||
| #include <pthread.h> | ||||
|  | ||||
| extern "C" void * common_thread_routine(void * pv) | ||||
| { | ||||
|     abstract_thread * pt = static_cast<abstract_thread *>(pv); | ||||
|     pt->run(); | ||||
|     delete pt; | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| #endif | ||||
|  | ||||
| // | ||||
|  | ||||
| template<class F> class thread: public abstract_thread | ||||
| { | ||||
| public: | ||||
|  | ||||
|     explicit thread(F f): f_(f) | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     void run() | ||||
|     { | ||||
|         f_(); | ||||
|     } | ||||
|  | ||||
| private: | ||||
|  | ||||
|     F f_; | ||||
| }; | ||||
|  | ||||
| template<class F> pthread_t createThread(F f) | ||||
| { | ||||
|     std::auto_ptr<abstract_thread> p(new thread<F>(f)); | ||||
|  | ||||
|     pthread_t r; | ||||
|  | ||||
|     if(pthread_create(&r, 0, common_thread_routine, p.get()) == 0) | ||||
|     { | ||||
|         p.release(); | ||||
|         return r; | ||||
|     } | ||||
|  | ||||
|     throw std::runtime_error("createThread failed."); | ||||
| } | ||||
| #include <boost/detail/lightweight_thread.hpp> | ||||
|  | ||||
| // | ||||
|  | ||||
| int const n = 1024 * 1024; | ||||
|  | ||||
| void test(boost::shared_ptr<int> const & pi) | ||||
| void test( boost::shared_ptr<int> const & pi ) | ||||
| { | ||||
|     std::vector< boost::shared_ptr<int> > v; | ||||
|  | ||||
|     for(int i = 0; i < n; ++i) | ||||
|     for( int i = 0; i < n; ++i ) | ||||
|     { | ||||
|         v.push_back(pi); | ||||
|         v.push_back( pi ); | ||||
|     } | ||||
| } | ||||
|  | ||||
| int const m = 16; // threads | ||||
|  | ||||
| #if defined( BOOST_HAS_PTHREADS ) | ||||
|  | ||||
| char const * thmodel = "POSIX"; | ||||
|  | ||||
| #else | ||||
|  | ||||
| char const * thmodel = "Windows"; | ||||
|  | ||||
| #endif | ||||
|  | ||||
| int main() | ||||
| { | ||||
|     using namespace std; // printf, clock_t, clock | ||||
|  | ||||
|     printf("%s: %d threads, %d iterations: ", title, m, n); | ||||
|     printf( "Using %s threads: %d threads, %d iterations: ", thmodel, m, n ); | ||||
|  | ||||
|     boost::shared_ptr<int> pi(new int(42)); | ||||
|     boost::shared_ptr<int> pi( new int(42) ); | ||||
|  | ||||
|     clock_t t = clock(); | ||||
|  | ||||
|     pthread_t a[m]; | ||||
|     pthread_t a[ m ]; | ||||
|  | ||||
|     for(int i = 0; i < m; ++i) | ||||
|     for( int i = 0; i < m; ++i ) | ||||
|     { | ||||
|         a[i] = createThread( boost::bind(test, pi) ); | ||||
|         boost::detail::lw_thread_create( a[ i ], boost::bind( test, pi ) ); | ||||
|     } | ||||
|  | ||||
|     for(int j = 0; j < m; ++j) | ||||
|     for( int j = 0; j < m; ++j ) | ||||
|     { | ||||
|         pthread_join(a[j], 0); | ||||
|         pthread_join( a[j], 0 ); | ||||
|     } | ||||
|  | ||||
|     t = clock() - t; | ||||
|  | ||||
|     printf("\n\n%.3f seconds.\n", static_cast<double>(t) / CLOCKS_PER_SEC); | ||||
|     printf( "\n\n%.3f seconds.\n", static_cast<double>(t) / CLOCKS_PER_SEC ); | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|   | ||||
| @@ -62,6 +62,7 @@ void default_constructor() | ||||
|         BOOST_TEST(pi? false: true); | ||||
|         BOOST_TEST(!pi); | ||||
|         BOOST_TEST(pi.get() == 0); | ||||
|         BOOST_TEST(pi.use_count() == 0); | ||||
|     } | ||||
|  | ||||
|     { | ||||
| @@ -69,6 +70,7 @@ void default_constructor() | ||||
|         BOOST_TEST(pv? false: true); | ||||
|         BOOST_TEST(!pv); | ||||
|         BOOST_TEST(pv.get() == 0); | ||||
|         BOOST_TEST(pv.use_count() == 0); | ||||
|     } | ||||
|  | ||||
|     { | ||||
| @@ -76,6 +78,7 @@ void default_constructor() | ||||
|         BOOST_TEST(px? false: true); | ||||
|         BOOST_TEST(!px); | ||||
|         BOOST_TEST(px.get() == 0); | ||||
|         BOOST_TEST(px.use_count() == 0); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -1565,6 +1568,7 @@ void plain_reset() | ||||
|         BOOST_TEST(pi? false: true); | ||||
|         BOOST_TEST(!pi); | ||||
|         BOOST_TEST(pi.get() == 0); | ||||
|         BOOST_TEST(pi.use_count() == 0); | ||||
|     } | ||||
|  | ||||
|     { | ||||
| @@ -1573,6 +1577,7 @@ void plain_reset() | ||||
|         BOOST_TEST(pi? false: true); | ||||
|         BOOST_TEST(!pi); | ||||
|         BOOST_TEST(pi.get() == 0); | ||||
|         BOOST_TEST(pi.use_count() == 0); | ||||
|     } | ||||
|  | ||||
|     { | ||||
| @@ -1581,6 +1586,7 @@ void plain_reset() | ||||
|         BOOST_TEST(pi? false: true); | ||||
|         BOOST_TEST(!pi); | ||||
|         BOOST_TEST(pi.get() == 0); | ||||
|         BOOST_TEST(pi.use_count() == 0); | ||||
|     } | ||||
|  | ||||
|     { | ||||
| @@ -1589,6 +1595,7 @@ void plain_reset() | ||||
|         BOOST_TEST(px? false: true); | ||||
|         BOOST_TEST(!px); | ||||
|         BOOST_TEST(px.get() == 0); | ||||
|         BOOST_TEST(px.use_count() == 0); | ||||
|     } | ||||
|  | ||||
|     { | ||||
| @@ -1597,6 +1604,7 @@ void plain_reset() | ||||
|         BOOST_TEST(px? false: true); | ||||
|         BOOST_TEST(!px); | ||||
|         BOOST_TEST(px.get() == 0); | ||||
|         BOOST_TEST(px.use_count() == 0); | ||||
|     } | ||||
|  | ||||
|     { | ||||
| @@ -1605,6 +1613,7 @@ void plain_reset() | ||||
|         BOOST_TEST(px? false: true); | ||||
|         BOOST_TEST(!px); | ||||
|         BOOST_TEST(px.get() == 0); | ||||
|         BOOST_TEST(px.use_count() == 0); | ||||
|     } | ||||
|  | ||||
|     { | ||||
| @@ -1615,6 +1624,7 @@ void plain_reset() | ||||
|         BOOST_TEST(px? false: true); | ||||
|         BOOST_TEST(!px); | ||||
|         BOOST_TEST(px.get() == 0); | ||||
|         BOOST_TEST(px.use_count() == 0); | ||||
|         BOOST_TEST(X::instances == 0); | ||||
|     } | ||||
|  | ||||
| @@ -1624,6 +1634,7 @@ void plain_reset() | ||||
|         BOOST_TEST(pv? false: true); | ||||
|         BOOST_TEST(!pv); | ||||
|         BOOST_TEST(pv.get() == 0); | ||||
|         BOOST_TEST(pv.use_count() == 0); | ||||
|     } | ||||
|  | ||||
|     { | ||||
| @@ -1634,6 +1645,7 @@ void plain_reset() | ||||
|         BOOST_TEST(pv? false: true); | ||||
|         BOOST_TEST(!pv); | ||||
|         BOOST_TEST(pv.get() == 0); | ||||
|         BOOST_TEST(pv.use_count() == 0); | ||||
|         BOOST_TEST(X::instances == 0); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -196,6 +196,10 @@ void test() | ||||
|     BOOST_TEST( cp.use_count() == 3 ); | ||||
|     BOOST_TEST( *cp == 87654 ); | ||||
|  | ||||
| #if defined( BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP ) | ||||
|     using boost::swap; | ||||
| #endif | ||||
|  | ||||
|     boost::shared_ptr<int> cp4; | ||||
|     swap( cp2, cp4 ); | ||||
|     BOOST_TEST( cp4.use_count() == 3 ); | ||||
|   | ||||
							
								
								
									
										247
									
								
								test/sp_atomic_mt2_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										247
									
								
								test/sp_atomic_mt2_test.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,247 @@ | ||||
|  | ||||
| // 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/config.hpp> | ||||
|  | ||||
| #include <boost/shared_ptr.hpp> | ||||
| #include <boost/bind.hpp> | ||||
|  | ||||
| #include <boost/thread/shared_mutex.hpp> | ||||
| #include <boost/thread/locks.hpp> | ||||
|  | ||||
| #include <boost/detail/lightweight_mutex.hpp> | ||||
| #include <boost/detail/lightweight_thread.hpp> | ||||
|  | ||||
| #include <vector> | ||||
| #include <numeric> | ||||
| #include <cstdio> | ||||
| #include <cstdlib> | ||||
| #include <cstddef> | ||||
| #include <ctime> | ||||
|  | ||||
| // | ||||
|  | ||||
| static void next_value( unsigned & v ) | ||||
| { | ||||
|     v = v % 2? 3 * v + 1: v / 2; | ||||
| } | ||||
|  | ||||
| struct X | ||||
| { | ||||
|     std::vector<unsigned> v_; | ||||
|  | ||||
|     explicit X( std::size_t n ): v_( n ) | ||||
|     { | ||||
|         for( std::size_t i = 0; i < n; ++i ) | ||||
|         { | ||||
|             v_[ i ] = i; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     unsigned get() const | ||||
|     { | ||||
|         return std::accumulate( v_.begin(), v_.end(), 0 ); | ||||
|     } | ||||
|  | ||||
|     void set() | ||||
|     { | ||||
|         std::for_each( v_.begin(), v_.end(), next_value ); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| static boost::shared_ptr<X> ps; | ||||
|  | ||||
| static boost::detail::lightweight_mutex lm; | ||||
| static boost::shared_mutex rw; | ||||
|  | ||||
| enum prim_type | ||||
| { | ||||
|     pt_mutex, | ||||
|     pt_rwlock, | ||||
|     pt_atomics | ||||
| }; | ||||
|  | ||||
| int read_access( prim_type pt ) | ||||
| { | ||||
|     switch( pt ) | ||||
|     { | ||||
|     case pt_mutex: | ||||
|         { | ||||
|             boost::detail::lightweight_mutex::scoped_lock lock( lm ); | ||||
|             return ps->get(); | ||||
|         } | ||||
|  | ||||
|     case pt_rwlock: | ||||
|         { | ||||
|             boost::shared_lock<boost::shared_mutex> lock( rw ); | ||||
|             return ps->get(); | ||||
|         } | ||||
|  | ||||
|     case pt_atomics: | ||||
|         { | ||||
|             boost::shared_ptr<X> p2 = boost::atomic_load( &ps ); | ||||
|             return p2->get(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| void write_access( prim_type pt ) | ||||
| { | ||||
|     switch( pt ) | ||||
|     { | ||||
|     case pt_mutex: | ||||
|         { | ||||
|             boost::detail::lightweight_mutex::scoped_lock lock( lm ); | ||||
|             ps->set(); | ||||
|         } | ||||
|         break; | ||||
|  | ||||
|     case pt_rwlock: | ||||
|         { | ||||
|             boost::unique_lock<boost::shared_mutex> lock( rw ); | ||||
|             ps->set(); | ||||
|         } | ||||
|         break; | ||||
|  | ||||
|     case pt_atomics: | ||||
|         { | ||||
|             boost::shared_ptr<X> p1 = boost::atomic_load( &ps ); | ||||
|  | ||||
|             for( ;; ) | ||||
|             { | ||||
|                 boost::shared_ptr<X> p2( new X( *p1 ) ); | ||||
|                 p2->set(); | ||||
|  | ||||
|                 if( boost::atomic_compare_exchange( &ps, &p1, p2 ) ) break; | ||||
|             } | ||||
|         } | ||||
|         break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| void worker( int k, prim_type pt, int n, int r ) | ||||
| { | ||||
|     ++r; | ||||
|  | ||||
|     unsigned s = 0, nr = 0, nw = 0; | ||||
|  | ||||
|     for( int i = 0; i < n; ++i ) | ||||
|     { | ||||
|         if( i % r ) | ||||
|         { | ||||
|             s += read_access( pt ); | ||||
|             ++nr; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             write_access( pt ); | ||||
|             ++s; | ||||
|             ++nw; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     printf( "Worker %2d: %u:%u, %10u\n", k, nr, nw, s ); | ||||
| } | ||||
|  | ||||
| #if defined( BOOST_HAS_PTHREADS ) | ||||
|   char const * thmodel = "POSIX"; | ||||
| #else | ||||
|   char const * thmodel = "Windows"; | ||||
| #endif | ||||
|  | ||||
| char const * pt_to_string( prim_type pt ) | ||||
| { | ||||
|     switch( pt ) | ||||
|     { | ||||
|     case pt_mutex: | ||||
|  | ||||
|         return "mutex"; | ||||
|  | ||||
|     case pt_rwlock: | ||||
|  | ||||
|         return "rwlock"; | ||||
|  | ||||
|     case pt_atomics: | ||||
|  | ||||
|         return "atomics"; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void handle_pt_option( std::string const & opt, prim_type & pt, prim_type pt2 ) | ||||
| { | ||||
|     if( opt == pt_to_string( pt2 ) ) | ||||
|     { | ||||
|         pt = pt2; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void handle_int_option( std::string const & opt, std::string const & prefix, int & k, int kmin, int kmax ) | ||||
| { | ||||
|     if( opt.substr( 0, prefix.size() ) == prefix ) | ||||
|     { | ||||
|         int v = atoi( opt.substr( prefix.size() ).c_str() ); | ||||
|  | ||||
|         if( v >= kmin && v <= kmax ) | ||||
|         { | ||||
|             k = v; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| int main( int ac, char const * av[] ) | ||||
| { | ||||
|     using namespace std; // printf, clock_t, clock | ||||
|  | ||||
|     int m = 4;          // threads | ||||
|     int n = 10000;      // vector size | ||||
|     int k = 1000000;    // iterations | ||||
|     int r = 100;        // read/write ratio, r:1 | ||||
|  | ||||
|     prim_type pt = pt_atomics; | ||||
|  | ||||
|     for( int i = 1; i < ac; ++i ) | ||||
|     { | ||||
|         handle_pt_option( av[i], pt, pt_mutex ); | ||||
|         handle_pt_option( av[i], pt, pt_rwlock ); | ||||
|         handle_pt_option( av[i], pt, pt_atomics ); | ||||
|  | ||||
|         handle_int_option( av[i], "n=", n, 1, INT_MAX ); | ||||
|         handle_int_option( av[i], "size=", n, 1, INT_MAX ); | ||||
|  | ||||
|         handle_int_option( av[i], "k=", k, 1, INT_MAX ); | ||||
|         handle_int_option( av[i], "iterations=", k, 1, INT_MAX ); | ||||
|  | ||||
|         handle_int_option( av[i], "m=", m, 1, INT_MAX ); | ||||
|         handle_int_option( av[i], "threads=", m, 1, INT_MAX ); | ||||
|  | ||||
|         handle_int_option( av[i], "r=", r, 1, INT_MAX ); | ||||
|         handle_int_option( av[i], "ratio=", r, 1, INT_MAX ); | ||||
|     } | ||||
|  | ||||
|     printf( "%s: threads=%d size=%d iterations=%d ratio=%d %s\n\n", thmodel, m, n, k, r, pt_to_string( pt ) ); | ||||
|  | ||||
|     ps.reset( new X( n ) ); | ||||
|  | ||||
|     clock_t t = clock(); | ||||
|  | ||||
|     std::vector<pthread_t> a( m ); | ||||
|  | ||||
|     for( int i = 0; i < m; ++i ) | ||||
|     { | ||||
|         boost::detail::lw_thread_create( a[ i ], boost::bind( worker, i, pt, k, r ) ); | ||||
|     } | ||||
|  | ||||
|     for( int j = 0; j < m; ++j ) | ||||
|     { | ||||
|         pthread_join( a[ j ], 0 ); | ||||
|     } | ||||
|  | ||||
|     t = clock() - t; | ||||
|  | ||||
|     double ts = static_cast<double>( t ) / CLOCKS_PER_SEC; | ||||
|     printf( "%.3f seconds, %.3f accesses per microsecond.\n", ts, m * k / ts / 1e+6 ); | ||||
| } | ||||
							
								
								
									
										191
									
								
								test/sp_atomic_mt_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										191
									
								
								test/sp_atomic_mt_test.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,191 @@ | ||||
|  | ||||
| // 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 | ||||
|  | ||||
| //#define USE_MUTEX | ||||
| //#define USE_RWLOCK | ||||
|  | ||||
| #include <boost/config.hpp> | ||||
|  | ||||
| #include <boost/shared_ptr.hpp> | ||||
| #include <boost/bind.hpp> | ||||
|  | ||||
| #if defined( USE_RWLOCK ) | ||||
| #include <boost/thread/shared_mutex.hpp> | ||||
| #include <boost/thread/locks.hpp> | ||||
| #endif | ||||
|  | ||||
| #include <boost/detail/lightweight_mutex.hpp> | ||||
| #include <boost/detail/lightweight_test.hpp> | ||||
| #include <boost/detail/lightweight_thread.hpp> | ||||
|  | ||||
| #include <cstdio> | ||||
| #include <ctime> | ||||
|  | ||||
| // | ||||
|  | ||||
| int const n = 1024 * 1024; | ||||
|  | ||||
| struct X | ||||
| { | ||||
|     int v_; // version | ||||
|  | ||||
|     unsigned a_; | ||||
|     unsigned b_; | ||||
|  | ||||
|     X(): v_( 0 ), a_( 1 ), b_( 1 ) | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     int get() const | ||||
|     { | ||||
|         return a_ * 7 + b_ * 11; | ||||
|     } | ||||
|  | ||||
|     void set() | ||||
|     { | ||||
|         int tmp = get(); | ||||
|  | ||||
|         b_ = a_; | ||||
|         a_ = tmp; | ||||
|  | ||||
|         ++v_; | ||||
|     } | ||||
| }; | ||||
|  | ||||
| static boost::shared_ptr<X> ps( new X ); | ||||
|  | ||||
| static boost::detail::lightweight_mutex lm; | ||||
|  | ||||
| #if defined( USE_RWLOCK ) | ||||
| static boost::shared_mutex rw; | ||||
| #endif | ||||
|  | ||||
| static int tr = 0; | ||||
|  | ||||
| void reader( int r ) | ||||
| { | ||||
|     int k = 0; | ||||
|     unsigned s = 0; | ||||
|  | ||||
|     for( int i = 0; i < n; ++k ) | ||||
|     { | ||||
| #if defined( USE_MUTEX ) | ||||
|  | ||||
|         boost::detail::lightweight_mutex::scoped_lock lock( lm ); | ||||
|  | ||||
|         s += ps->get(); | ||||
|  | ||||
|         BOOST_TEST( ps->v_ >= i ); | ||||
|         i = ps->v_; | ||||
|  | ||||
| #elif defined( USE_RWLOCK ) | ||||
|  | ||||
|         boost::shared_lock<boost::shared_mutex> lock( rw ); | ||||
|  | ||||
|         s += ps->get(); | ||||
|  | ||||
|         BOOST_TEST( ps->v_ >= i ); | ||||
|         i = ps->v_; | ||||
|  | ||||
| #else | ||||
|  | ||||
|         boost::shared_ptr<X> p2 = boost::atomic_load( &ps ); | ||||
|  | ||||
|         s += p2->get(); | ||||
|  | ||||
|         BOOST_TEST( p2->v_ >= i ); | ||||
|         i = p2->v_; | ||||
|  | ||||
| #endif | ||||
|     } | ||||
|  | ||||
|     printf( "Reader %d: %9d iterations (%6.3fx), %u\n", r, k, (double)k / n, s ); | ||||
|  | ||||
|     boost::detail::lightweight_mutex::scoped_lock lock( lm ); | ||||
|     tr += k; | ||||
| } | ||||
|  | ||||
| void writer() | ||||
| { | ||||
|     for( int i = 0; i < n; ++i ) | ||||
|     { | ||||
| #if defined( USE_MUTEX ) | ||||
|  | ||||
|         boost::detail::lightweight_mutex::scoped_lock lock( lm ); | ||||
|  | ||||
|         BOOST_TEST( ps->v_ == i ); | ||||
|         ps->set(); | ||||
|  | ||||
| #elif defined( USE_RWLOCK ) | ||||
|  | ||||
|         boost::unique_lock<boost::shared_mutex> lock( rw ); | ||||
|  | ||||
|         BOOST_TEST( ps->v_ == i ); | ||||
|         ps->set(); | ||||
|  | ||||
| #else | ||||
|  | ||||
|         boost::shared_ptr<X> p2( new X( *ps ) ); | ||||
|  | ||||
|         BOOST_TEST( p2->v_ == i ); | ||||
|         p2->set(); | ||||
|  | ||||
|         boost::atomic_store( &ps, p2 ); | ||||
|  | ||||
| #endif | ||||
|     } | ||||
| } | ||||
|  | ||||
| #if defined( BOOST_HAS_PTHREADS ) | ||||
|   char const * thmodel = "POSIX"; | ||||
| #else | ||||
|   char const * thmodel = "Windows"; | ||||
| #endif | ||||
|  | ||||
| int const mr = 8; // reader threads | ||||
| int const mw = 1; // writer thread | ||||
|  | ||||
| #if defined( USE_MUTEX ) | ||||
|   char const * prim = "mutex"; | ||||
| #elif defined( USE_RWLOCK ) | ||||
|   char const * prim = "rwlock"; | ||||
| #else | ||||
|   char const * prim = "atomics"; | ||||
| #endif | ||||
|  | ||||
| int main() | ||||
| { | ||||
|     using namespace std; // printf, clock_t, clock | ||||
|  | ||||
|     printf( "Using %s threads: %dR + %dW threads, %d iterations, %s\n\n", thmodel, mr, mw, n, prim ); | ||||
|  | ||||
|     clock_t t = clock(); | ||||
|  | ||||
|     pthread_t a[ mr+mw ]; | ||||
|  | ||||
|     for( int i = 0; i < mr; ++i ) | ||||
|     { | ||||
|         boost::detail::lw_thread_create( a[ i ], boost::bind( reader, i ) ); | ||||
|     } | ||||
|  | ||||
|     for( int i = mr; i < mr+mw; ++i ) | ||||
|     { | ||||
|         boost::detail::lw_thread_create( a[ i ], writer ); | ||||
|     } | ||||
|  | ||||
|     for( int j = 0; j < mr+mw; ++j ) | ||||
|     { | ||||
|         pthread_join( a[ j ], 0 ); | ||||
|     } | ||||
|  | ||||
|     t = clock() - t; | ||||
|  | ||||
|     double ts = static_cast<double>( t ) / CLOCKS_PER_SEC; | ||||
|     printf( "%.3f seconds, %.3f reads per microsecond.\n", ts, tr / ts / 1e+6 ); | ||||
|  | ||||
|     return boost::report_errors(); | ||||
| } | ||||
							
								
								
									
										87
									
								
								test/sp_atomic_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								test/sp_atomic_test.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,87 @@ | ||||
| #include <boost/config.hpp> | ||||
|  | ||||
| //  sp_atomic_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/shared_ptr.hpp> | ||||
|  | ||||
| // | ||||
|  | ||||
| struct X | ||||
| { | ||||
| }; | ||||
|  | ||||
| #define BOOST_TEST_SP_EQ( p, q ) BOOST_TEST( p == q && !( p < q ) && !( q < p ) ) | ||||
|  | ||||
| int main() | ||||
| { | ||||
|     boost::shared_ptr<X> px( new X ); | ||||
|  | ||||
|     { | ||||
|         boost::shared_ptr<X> p2 = boost::atomic_load( &px ); | ||||
|         BOOST_TEST_SP_EQ( p2, px ); | ||||
|  | ||||
|         boost::shared_ptr<X> px2( new X ); | ||||
|         boost::atomic_store( &px, px2 ); | ||||
|         BOOST_TEST_SP_EQ( px, px2 ); | ||||
|  | ||||
|         p2 = boost::atomic_load( &px ); | ||||
|         BOOST_TEST_SP_EQ( p2, px ); | ||||
|         BOOST_TEST_SP_EQ( p2, px2 ); | ||||
|  | ||||
|         boost::shared_ptr<X> px3( new X ); | ||||
|         boost::shared_ptr<X> p3 = boost::atomic_exchange( &px, px3 ); | ||||
|         BOOST_TEST_SP_EQ( p3, px2 ); | ||||
|         BOOST_TEST_SP_EQ( px, px3 ); | ||||
|  | ||||
|         boost::shared_ptr<X> px4( new X ); | ||||
|         boost::shared_ptr<X> cmp; | ||||
|  | ||||
|         bool r = boost::atomic_compare_exchange( &px, &cmp, px4 ); | ||||
|         BOOST_TEST( !r ); | ||||
|         BOOST_TEST_SP_EQ( px, px3 ); | ||||
|         BOOST_TEST_SP_EQ( cmp, px3 ); | ||||
|  | ||||
|         r = boost::atomic_compare_exchange( &px, &cmp, px4 ); | ||||
|         BOOST_TEST( r ); | ||||
|         BOOST_TEST_SP_EQ( px, px4 ); | ||||
|     } | ||||
|  | ||||
|     // | ||||
|  | ||||
|     px.reset(); | ||||
|  | ||||
|     { | ||||
|         boost::shared_ptr<X> p2 = boost::atomic_load_explicit( &px, boost::memory_order_acquire ); | ||||
|         BOOST_TEST_SP_EQ( p2, px ); | ||||
|  | ||||
|         boost::shared_ptr<X> px2( new X ); | ||||
|         boost::atomic_store_explicit( &px, px2, boost::memory_order_release ); | ||||
|         BOOST_TEST_SP_EQ( px, px2 ); | ||||
|  | ||||
|         boost::shared_ptr<X> p3 = boost::atomic_exchange_explicit( &px, boost::shared_ptr<X>(), boost::memory_order_acq_rel ); | ||||
|         BOOST_TEST_SP_EQ( p3, px2 ); | ||||
|         BOOST_TEST_SP_EQ( px, p2 ); | ||||
|  | ||||
|         boost::shared_ptr<X> px4( new X ); | ||||
|         boost::shared_ptr<X> cmp( px2 ); | ||||
|  | ||||
|         bool r = boost::atomic_compare_exchange_explicit( &px, &cmp, px4, boost::memory_order_acquire, boost::memory_order_relaxed ); | ||||
|         BOOST_TEST( !r ); | ||||
|         BOOST_TEST_SP_EQ( px, p2 ); | ||||
|         BOOST_TEST_SP_EQ( cmp, p2 ); | ||||
|  | ||||
|         r = boost::atomic_compare_exchange_explicit( &px, &cmp, px4, boost::memory_order_release, boost::memory_order_acquire ); | ||||
|         BOOST_TEST( r ); | ||||
|         BOOST_TEST_SP_EQ( px, px4 ); | ||||
|     } | ||||
|  | ||||
|     return boost::report_errors(); | ||||
| } | ||||
							
								
								
									
										71
									
								
								test/sp_convertible_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								test/sp_convertible_test.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,71 @@ | ||||
| #include <boost/config.hpp> | ||||
|  | ||||
| //  sp_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/shared_ptr.hpp> | ||||
|  | ||||
| // | ||||
|  | ||||
| class incomplete; | ||||
|  | ||||
| struct X | ||||
| { | ||||
| }; | ||||
|  | ||||
| struct Y | ||||
| { | ||||
| }; | ||||
|  | ||||
| struct Z: public X | ||||
| { | ||||
| }; | ||||
|  | ||||
| int f( boost::shared_ptr<void const> ) | ||||
| { | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| int f( boost::shared_ptr<int> ) | ||||
| { | ||||
|     return 2; | ||||
| } | ||||
|  | ||||
| int f( boost::shared_ptr<incomplete> ) | ||||
| { | ||||
|     return 3; | ||||
| } | ||||
|  | ||||
| int g( boost::shared_ptr<X> ) | ||||
| { | ||||
|     return 4; | ||||
| } | ||||
|  | ||||
| int g( boost::shared_ptr<Y> ) | ||||
| { | ||||
|     return 5; | ||||
| } | ||||
|  | ||||
| int g( boost::shared_ptr<incomplete> ) | ||||
| { | ||||
|     return 6; | ||||
| } | ||||
|  | ||||
| int main() | ||||
| { | ||||
|     boost::shared_ptr<double> p1; | ||||
|     BOOST_TEST( 1 == f( p1 ) ); | ||||
|     BOOST_TEST( 1 == f( boost::shared_ptr<double>() ) ); | ||||
|  | ||||
|     boost::shared_ptr<Z> p2; | ||||
|     BOOST_TEST( 4 == g( p2 ) ); | ||||
|     BOOST_TEST( 4 == g( boost::shared_ptr<Z>() ) ); | ||||
|  | ||||
|     return boost::report_errors(); | ||||
| } | ||||
							
								
								
									
										114
									
								
								test/sp_recursive_assign2_rv_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								test/sp_recursive_assign2_rv_test.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,114 @@ | ||||
| // | ||||
| //  sp_recursive_assign2_rv_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/shared_ptr.hpp> | ||||
| #include <boost/detail/lightweight_test.hpp> | ||||
|  | ||||
| // | ||||
|  | ||||
| class X | ||||
| { | ||||
| public: | ||||
|  | ||||
|     static int instances; | ||||
|  | ||||
|     X() | ||||
|     { | ||||
|         ++instances; | ||||
|     } | ||||
|  | ||||
|     ~X() | ||||
|     { | ||||
|         --instances; | ||||
|     } | ||||
|  | ||||
| private: | ||||
|  | ||||
|     X( X const& ); | ||||
| }; | ||||
|  | ||||
| int X::instances = 0; | ||||
|  | ||||
| class Y | ||||
| { | ||||
| public: | ||||
|  | ||||
|     static int instances; | ||||
|  | ||||
|     Y() | ||||
|     { | ||||
|         ++instances; | ||||
|     } | ||||
|  | ||||
|     ~Y() | ||||
|     { | ||||
|         --instances; | ||||
|     } | ||||
|  | ||||
| private: | ||||
|  | ||||
|     Y( Y const& ); | ||||
| }; | ||||
|  | ||||
| int Y::instances = 0; | ||||
|  | ||||
| static boost::shared_ptr<void> s_pv; | ||||
|  | ||||
| class Z | ||||
| { | ||||
| public: | ||||
|  | ||||
|     static int instances; | ||||
|  | ||||
|     Z() | ||||
|     { | ||||
|         ++instances; | ||||
|     } | ||||
|  | ||||
|     ~Z() | ||||
|     { | ||||
|         --instances; | ||||
|         s_pv = boost::shared_ptr<Y>( new Y ); | ||||
|     } | ||||
|  | ||||
| private: | ||||
|  | ||||
|     Z( Z const& ); | ||||
| }; | ||||
|  | ||||
| int Z::instances = 0; | ||||
|  | ||||
| int main() | ||||
| { | ||||
|     BOOST_TEST( X::instances == 0 ); | ||||
|     BOOST_TEST( Y::instances == 0 ); | ||||
|     BOOST_TEST( Z::instances == 0 ); | ||||
|  | ||||
|     s_pv = boost::shared_ptr<Z>( new Z ); | ||||
|  | ||||
|     BOOST_TEST( X::instances == 0 ); | ||||
|     BOOST_TEST( Y::instances == 0 ); | ||||
|     BOOST_TEST( Z::instances == 1 ); | ||||
|  | ||||
|     s_pv = boost::shared_ptr<X>( new X ); | ||||
|  | ||||
|     BOOST_TEST( X::instances == 0 ); | ||||
|     BOOST_TEST( Y::instances == 1 ); | ||||
|     BOOST_TEST( Z::instances == 0 ); | ||||
|  | ||||
|     s_pv = boost::shared_ptr<Y>(); | ||||
|  | ||||
|     BOOST_TEST( X::instances == 0 ); | ||||
|     BOOST_TEST( Y::instances == 0 ); | ||||
|     BOOST_TEST( Z::instances == 0 ); | ||||
|  | ||||
|     return boost::report_errors(); | ||||
| } | ||||
							
								
								
									
										122
									
								
								test/sp_recursive_assign2_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										122
									
								
								test/sp_recursive_assign2_test.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,122 @@ | ||||
| // | ||||
| //  sp_recursive_assign2_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/shared_ptr.hpp> | ||||
| #include <boost/detail/lightweight_test.hpp> | ||||
|  | ||||
| // | ||||
|  | ||||
| class X | ||||
| { | ||||
| public: | ||||
|  | ||||
|     static int instances; | ||||
|  | ||||
|     X() | ||||
|     { | ||||
|         ++instances; | ||||
|     } | ||||
|  | ||||
|     ~X() | ||||
|     { | ||||
|         --instances; | ||||
|     } | ||||
|  | ||||
| private: | ||||
|  | ||||
|     X( X const& ); | ||||
| }; | ||||
|  | ||||
| int X::instances = 0; | ||||
|  | ||||
| class Y | ||||
| { | ||||
| public: | ||||
|  | ||||
|     static int instances; | ||||
|  | ||||
|     Y() | ||||
|     { | ||||
|         ++instances; | ||||
|     } | ||||
|  | ||||
|     ~Y() | ||||
|     { | ||||
|         --instances; | ||||
|     } | ||||
|  | ||||
| private: | ||||
|  | ||||
|     Y( Y const& ); | ||||
| }; | ||||
|  | ||||
| int Y::instances = 0; | ||||
|  | ||||
| static boost::shared_ptr<void> s_pv; | ||||
|  | ||||
| class Z | ||||
| { | ||||
| public: | ||||
|  | ||||
|     static int instances; | ||||
|  | ||||
|     Z() | ||||
|     { | ||||
|         ++instances; | ||||
|     } | ||||
|  | ||||
|     ~Z() | ||||
|     { | ||||
|         --instances; | ||||
|  | ||||
|         boost::shared_ptr<Y> pv( new Y ); | ||||
|         s_pv = pv; | ||||
|     } | ||||
|  | ||||
| private: | ||||
|  | ||||
|     Z( Z const& ); | ||||
| }; | ||||
|  | ||||
| int Z::instances = 0; | ||||
|  | ||||
| int main() | ||||
| { | ||||
|     BOOST_TEST( X::instances == 0 ); | ||||
|     BOOST_TEST( Y::instances == 0 ); | ||||
|     BOOST_TEST( Z::instances == 0 ); | ||||
|  | ||||
|     { | ||||
|         boost::shared_ptr<Z> pv( new Z ); | ||||
|         s_pv = pv; | ||||
|     } | ||||
|  | ||||
|     BOOST_TEST( X::instances == 0 ); | ||||
|     BOOST_TEST( Y::instances == 0 ); | ||||
|     BOOST_TEST( Z::instances == 1 ); | ||||
|  | ||||
|     { | ||||
|         boost::shared_ptr<X> pv( new X ); | ||||
|         s_pv = pv; | ||||
|     } | ||||
|  | ||||
|     BOOST_TEST( X::instances == 0 ); | ||||
|     BOOST_TEST( Y::instances == 1 ); | ||||
|     BOOST_TEST( Z::instances == 0 ); | ||||
|  | ||||
|     s_pv.reset(); | ||||
|  | ||||
|     BOOST_TEST( X::instances == 0 ); | ||||
|     BOOST_TEST( Y::instances == 0 ); | ||||
|     BOOST_TEST( Z::instances == 0 ); | ||||
|  | ||||
|     return boost::report_errors(); | ||||
| } | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user