mirror of
https://github.com/boostorg/smart_ptr.git
synced 2025-07-30 12:47:28 +02:00
@ -12,108 +12,10 @@
|
|||||||
//
|
//
|
||||||
// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
|
// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
// accompanying file LICENSE_1_0.txt or copy at
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
// 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...
|
|
||||||
//
|
|
||||||
|
|
||||||
#include <boost/config.hpp>
|
#include <boost/smart_ptr/detail/atomic_count.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 ) && !defined( __arm__ ) && !defined( __hppa ) && ( !defined( __INTEL_COMPILER ) || defined( __ia64__ ) )
|
|
||||||
# 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
|
|
||||||
|
|
||||||
#endif // #ifndef BOOST_DETAIL_ATOMIC_COUNT_HPP_INCLUDED
|
#endif // #ifndef BOOST_DETAIL_ATOMIC_COUNT_HPP_INCLUDED
|
||||||
|
@ -12,31 +12,11 @@
|
|||||||
//
|
//
|
||||||
// Copyright (c) 2002, 2003 Peter Dimov and Multi Media Ltd.
|
// Copyright (c) 2002, 2003 Peter Dimov and Multi Media Ltd.
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
// accompanying file LICENSE_1_0.txt or copy at
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
// 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>
|
#include <boost/smart_ptr/detail/lightweight_mutex.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
|
|
||||||
|
|
||||||
#endif // #ifndef BOOST_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED
|
#endif // #ifndef BOOST_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED
|
||||||
|
@ -6,68 +6,13 @@
|
|||||||
//
|
//
|
||||||
// Copyright (c) 2002 Peter Dimov
|
// Copyright (c) 2002 Peter Dimov
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
// accompanying file LICENSE_1_0.txt or copy at
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
//
|
//
|
||||||
// http://www.boost.org/libs/smart_ptr/enable_shared_from_this.html
|
// http://www.boost.org/libs/smart_ptr/enable_shared_from_this.html
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <boost/weak_ptr.hpp>
|
#include <boost/smart_ptr/enable_shared_from_this.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
|
|
||||||
|
|
||||||
#endif // #ifndef BOOST_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED
|
#endif // #ifndef BOOST_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED
|
||||||
|
@ -6,306 +6,13 @@
|
|||||||
//
|
//
|
||||||
// Copyright (c) 2001, 2002 Peter Dimov
|
// Copyright (c) 2001, 2002 Peter Dimov
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
// accompanying file LICENSE_1_0.txt or copy at
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
//
|
//
|
||||||
// See http://www.boost.org/libs/smart_ptr/intrusive_ptr.html for documentation.
|
// See http://www.boost.org/libs/smart_ptr/intrusive_ptr.html for documentation.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <boost/config.hpp>
|
#include <boost/smart_ptr/intrusive_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
|
|
||||||
|
|
||||||
#include <boost/assert.hpp>
|
|
||||||
#include <boost/detail/workaround.hpp>
|
|
||||||
#include <boost/detail/sp_convertible.hpp>
|
|
||||||
|
|
||||||
#include <boost/config/no_tr1/functional.hpp> // for std::less
|
|
||||||
|
|
||||||
#if !defined(BOOST_NO_IOSTREAM)
|
|
||||||
#if !defined(BOOST_NO_IOSFWD)
|
|
||||||
#include <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(): 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>
|
|
||||||
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
|
|
||||||
|
|
||||||
intrusive_ptr( intrusive_ptr<U> const & rhs, typename detail::sp_enable_if_convertible<U,T>::type = detail::sp_empty() )
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
intrusive_ptr( intrusive_ptr<U> const & rhs )
|
|
||||||
|
|
||||||
#endif
|
|
||||||
: p_( rhs.get() )
|
|
||||||
{
|
|
||||||
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()
|
|
||||||
{
|
|
||||||
this_type().swap( *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(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_INTRUSIVE_PTR_HPP_INCLUDED
|
#endif // #ifndef BOOST_INTRUSIVE_PTR_HPP_INCLUDED
|
||||||
|
@ -12,422 +12,6 @@
|
|||||||
// See http://www.boost.org/libs/smart_ptr/make_shared.html
|
// See http://www.boost.org/libs/smart_ptr/make_shared.html
|
||||||
// for documentation.
|
// for documentation.
|
||||||
|
|
||||||
#include <boost/config.hpp>
|
#include <boost/smart_ptr/make_shared.hpp>
|
||||||
#include <boost/shared_ptr.hpp>
|
|
||||||
#include <boost/type_traits/type_with_alignment.hpp>
|
|
||||||
#include <boost/type_traits/alignment_of.hpp>
|
|
||||||
#include <cstddef>
|
|
||||||
#include <new>
|
|
||||||
|
|
||||||
namespace boost
|
|
||||||
{
|
|
||||||
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
|
|
||||||
template< std::size_t N, std::size_t A > struct sp_aligned_storage
|
|
||||||
{
|
|
||||||
union type
|
|
||||||
{
|
|
||||||
char data_[ N ];
|
|
||||||
typename boost::type_with_alignment< A >::type align_;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template< class T > class sp_ms_deleter
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
|
|
||||||
typedef typename sp_aligned_storage< sizeof( T ), ::boost::alignment_of< T >::value >::type storage_type;
|
|
||||||
|
|
||||||
bool initialized_;
|
|
||||||
storage_type storage_;
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
void destroy()
|
|
||||||
{
|
|
||||||
if( initialized_ )
|
|
||||||
{
|
|
||||||
reinterpret_cast< T* >( storage_.data_ )->~T();
|
|
||||||
initialized_ = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
sp_ms_deleter(): initialized_( false )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
~sp_ms_deleter()
|
|
||||||
{
|
|
||||||
destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
void operator()( T * )
|
|
||||||
{
|
|
||||||
destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
void * address()
|
|
||||||
{
|
|
||||||
return storage_.data_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_initialized()
|
|
||||||
{
|
|
||||||
initialized_ = true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template< class T > T forward( T t )
|
|
||||||
{
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
// Zero-argument versions
|
|
||||||
//
|
|
||||||
// Used even when variadic templates are available because of the new T() vs new T issue
|
|
||||||
|
|
||||||
template< class T > boost::shared_ptr< T > make_shared()
|
|
||||||
{
|
|
||||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
|
|
||||||
|
|
||||||
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
|
||||||
|
|
||||||
void * pv = pd->address();
|
|
||||||
|
|
||||||
new( pv ) T();
|
|
||||||
pd->set_initialized();
|
|
||||||
|
|
||||||
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
template< class T, class A > boost::shared_ptr< T > allocate_shared( A const & a )
|
|
||||||
{
|
|
||||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
|
|
||||||
|
|
||||||
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
|
||||||
|
|
||||||
void * pv = pd->address();
|
|
||||||
|
|
||||||
new( pv ) T();
|
|
||||||
pd->set_initialized();
|
|
||||||
|
|
||||||
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined( BOOST_HAS_VARIADIC_TMPL ) && defined( BOOST_HAS_RVALUE_REFS )
|
|
||||||
|
|
||||||
// Variadic templates, rvalue reference
|
|
||||||
|
|
||||||
template< class T, class... Args > boost::shared_ptr< T > make_shared( Args && ... args )
|
|
||||||
{
|
|
||||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
|
|
||||||
|
|
||||||
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
|
||||||
|
|
||||||
void * pv = pd->address();
|
|
||||||
|
|
||||||
new( pv ) T( detail::forward<Args>( args )... );
|
|
||||||
pd->set_initialized();
|
|
||||||
|
|
||||||
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
template< class T, class A, class... Args > boost::shared_ptr< T > allocate_shared( A const & a, Args && ... args )
|
|
||||||
{
|
|
||||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
|
|
||||||
|
|
||||||
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
|
||||||
|
|
||||||
void * pv = pd->address();
|
|
||||||
|
|
||||||
new( pv ) T( detail::forward<Args>( args )... );
|
|
||||||
pd->set_initialized();
|
|
||||||
|
|
||||||
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
// C++03 version
|
|
||||||
|
|
||||||
template< class T, class A1 >
|
|
||||||
boost::shared_ptr< T > make_shared( A1 const & a1 )
|
|
||||||
{
|
|
||||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
|
|
||||||
|
|
||||||
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
|
||||||
|
|
||||||
void * pv = pd->address();
|
|
||||||
|
|
||||||
new( pv ) T( a1 );
|
|
||||||
pd->set_initialized();
|
|
||||||
|
|
||||||
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
template< class T, class A, class A1 >
|
|
||||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1 )
|
|
||||||
{
|
|
||||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
|
|
||||||
|
|
||||||
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
|
||||||
|
|
||||||
void * pv = pd->address();
|
|
||||||
|
|
||||||
new( pv ) T( a1 );
|
|
||||||
pd->set_initialized();
|
|
||||||
|
|
||||||
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
template< class T, class A1, class A2 >
|
|
||||||
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2 )
|
|
||||||
{
|
|
||||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
|
|
||||||
|
|
||||||
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
|
||||||
|
|
||||||
void * pv = pd->address();
|
|
||||||
|
|
||||||
new( pv ) T( a1, a2 );
|
|
||||||
pd->set_initialized();
|
|
||||||
|
|
||||||
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
template< class T, class A, class A1, class A2 >
|
|
||||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2 )
|
|
||||||
{
|
|
||||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
|
|
||||||
|
|
||||||
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
|
||||||
|
|
||||||
void * pv = pd->address();
|
|
||||||
|
|
||||||
new( pv ) T( a1, a2 );
|
|
||||||
pd->set_initialized();
|
|
||||||
|
|
||||||
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
template< class T, class A1, class A2, class A3 >
|
|
||||||
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3 )
|
|
||||||
{
|
|
||||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
|
|
||||||
|
|
||||||
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
|
||||||
|
|
||||||
void * pv = pd->address();
|
|
||||||
|
|
||||||
new( pv ) T( a1, a2, a3 );
|
|
||||||
pd->set_initialized();
|
|
||||||
|
|
||||||
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
template< class T, class A, class A1, class A2, class A3 >
|
|
||||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3 )
|
|
||||||
{
|
|
||||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
|
|
||||||
|
|
||||||
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
|
||||||
|
|
||||||
void * pv = pd->address();
|
|
||||||
|
|
||||||
new( pv ) T( a1, a2, a3 );
|
|
||||||
pd->set_initialized();
|
|
||||||
|
|
||||||
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
template< class T, class A1, class A2, class A3, class A4 >
|
|
||||||
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4 )
|
|
||||||
{
|
|
||||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
|
|
||||||
|
|
||||||
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
|
||||||
|
|
||||||
void * pv = pd->address();
|
|
||||||
|
|
||||||
new( pv ) T( a1, a2, a3, a4 );
|
|
||||||
pd->set_initialized();
|
|
||||||
|
|
||||||
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
template< class T, class A, class A1, class A2, class A3, class A4 >
|
|
||||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4 )
|
|
||||||
{
|
|
||||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
|
|
||||||
|
|
||||||
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
|
||||||
|
|
||||||
void * pv = pd->address();
|
|
||||||
|
|
||||||
new( pv ) T( a1, a2, a3, a4 );
|
|
||||||
pd->set_initialized();
|
|
||||||
|
|
||||||
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
template< class T, class A1, class A2, class A3, class A4, class A5 >
|
|
||||||
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5 )
|
|
||||||
{
|
|
||||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
|
|
||||||
|
|
||||||
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
|
||||||
|
|
||||||
void * pv = pd->address();
|
|
||||||
|
|
||||||
new( pv ) T( a1, a2, a3, a4, a5 );
|
|
||||||
pd->set_initialized();
|
|
||||||
|
|
||||||
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
template< class T, class A, class A1, class A2, class A3, class A4, class A5 >
|
|
||||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5 )
|
|
||||||
{
|
|
||||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
|
|
||||||
|
|
||||||
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
|
||||||
|
|
||||||
void * pv = pd->address();
|
|
||||||
|
|
||||||
new( pv ) T( a1, a2, a3, a4, a5 );
|
|
||||||
pd->set_initialized();
|
|
||||||
|
|
||||||
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
template< class T, class A1, class A2, class A3, class A4, class A5, class A6 >
|
|
||||||
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6 )
|
|
||||||
{
|
|
||||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
|
|
||||||
|
|
||||||
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
|
||||||
|
|
||||||
void * pv = pd->address();
|
|
||||||
|
|
||||||
new( pv ) T( a1, a2, a3, a4, a5, a6 );
|
|
||||||
pd->set_initialized();
|
|
||||||
|
|
||||||
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6 >
|
|
||||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6 )
|
|
||||||
{
|
|
||||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
|
|
||||||
|
|
||||||
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
|
||||||
|
|
||||||
void * pv = pd->address();
|
|
||||||
|
|
||||||
new( pv ) T( a1, a2, a3, a4, a5, a6 );
|
|
||||||
pd->set_initialized();
|
|
||||||
|
|
||||||
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7 >
|
|
||||||
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7 )
|
|
||||||
{
|
|
||||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
|
|
||||||
|
|
||||||
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
|
||||||
|
|
||||||
void * pv = pd->address();
|
|
||||||
|
|
||||||
new( pv ) T( a1, a2, a3, a4, a5, a6, a7 );
|
|
||||||
pd->set_initialized();
|
|
||||||
|
|
||||||
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7 >
|
|
||||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7 )
|
|
||||||
{
|
|
||||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
|
|
||||||
|
|
||||||
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
|
||||||
|
|
||||||
void * pv = pd->address();
|
|
||||||
|
|
||||||
new( pv ) T( a1, a2, a3, a4, a5, a6, a7 );
|
|
||||||
pd->set_initialized();
|
|
||||||
|
|
||||||
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 >
|
|
||||||
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8 )
|
|
||||||
{
|
|
||||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
|
|
||||||
|
|
||||||
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
|
||||||
|
|
||||||
void * pv = pd->address();
|
|
||||||
|
|
||||||
new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8 );
|
|
||||||
pd->set_initialized();
|
|
||||||
|
|
||||||
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 >
|
|
||||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8 )
|
|
||||||
{
|
|
||||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
|
|
||||||
|
|
||||||
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
|
||||||
|
|
||||||
void * pv = pd->address();
|
|
||||||
|
|
||||||
new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8 );
|
|
||||||
pd->set_initialized();
|
|
||||||
|
|
||||||
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 >
|
|
||||||
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8, A9 const & a9 )
|
|
||||||
{
|
|
||||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
|
|
||||||
|
|
||||||
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
|
||||||
|
|
||||||
void * pv = pd->address();
|
|
||||||
|
|
||||||
new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8, a9 );
|
|
||||||
pd->set_initialized();
|
|
||||||
|
|
||||||
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 >
|
|
||||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8, A9 const & a9 )
|
|
||||||
{
|
|
||||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
|
|
||||||
|
|
||||||
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
|
||||||
|
|
||||||
void * pv = pd->address();
|
|
||||||
|
|
||||||
new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8, a9 );
|
|
||||||
pd->set_initialized();
|
|
||||||
|
|
||||||
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // namespace boost
|
|
||||||
|
|
||||||
#endif // #ifndef BOOST_MAKE_SHARED_HPP_INCLUDED
|
#endif // #ifndef BOOST_MAKE_SHARED_HPP_INCLUDED
|
||||||
|
@ -11,128 +11,6 @@
|
|||||||
// http://www.boost.org/libs/smart_ptr/scoped_array.htm
|
// http://www.boost.org/libs/smart_ptr/scoped_array.htm
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <boost/assert.hpp>
|
#include <boost/smart_ptr/scoped_array.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;
|
|
||||||
|
|
||||||
void operator==( scoped_array const& ) const;
|
|
||||||
void operator!=( scoped_array const& ) const;
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
#endif // #ifndef BOOST_SCOPED_ARRAY_HPP_INCLUDED
|
#endif // #ifndef BOOST_SCOPED_ARRAY_HPP_INCLUDED
|
||||||
|
@ -11,150 +11,6 @@
|
|||||||
// http://www.boost.org/libs/smart_ptr/scoped_ptr.htm
|
// http://www.boost.org/libs/smart_ptr/scoped_ptr.htm
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <boost/assert.hpp>
|
#include <boost/smart_ptr/scoped_ptr.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;
|
|
||||||
|
|
||||||
void operator==( scoped_ptr const& ) const;
|
|
||||||
void operator!=( scoped_ptr const& ) const;
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
#endif // #ifndef BOOST_SCOPED_PTR_HPP_INCLUDED
|
#endif // #ifndef BOOST_SCOPED_PTR_HPP_INCLUDED
|
||||||
|
@ -14,180 +14,6 @@
|
|||||||
// See http://www.boost.org/libs/smart_ptr/shared_array.htm for documentation.
|
// See http://www.boost.org/libs/smart_ptr/shared_array.htm for documentation.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <boost/config.hpp> // for broken compiler workarounds
|
#include <boost/smart_ptr/shared_array.hpp>
|
||||||
|
|
||||||
#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)
|
|
||||||
|
|
||||||
#endif // #ifndef BOOST_SHARED_ARRAY_HPP_INCLUDED
|
#endif // #ifndef BOOST_SHARED_ARRAY_HPP_INCLUDED
|
||||||
|
@ -14,738 +14,6 @@
|
|||||||
// See http://www.boost.org/libs/smart_ptr/shared_ptr.htm for documentation.
|
// See http://www.boost.org/libs/smart_ptr/shared_ptr.htm for documentation.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <boost/config.hpp> // for broken compiler workarounds
|
#include <boost/smart_ptr/shared_ptr.hpp>
|
||||||
|
|
||||||
#if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
|
|
||||||
#include <boost/detail/shared_ptr_nmt.hpp>
|
|
||||||
#else
|
|
||||||
|
|
||||||
// In order to avoid circular dependencies with Boost.TR1
|
|
||||||
// we make sure that our include of <memory> doesn't try to
|
|
||||||
// pull in the TR1 headers: that's why we use this header
|
|
||||||
// rather than including <memory> directly:
|
|
||||||
#include <boost/config/no_tr1/memory.hpp> // std::auto_ptr
|
|
||||||
|
|
||||||
#include <boost/assert.hpp>
|
|
||||||
#include <boost/checked_delete.hpp>
|
|
||||||
#include <boost/throw_exception.hpp>
|
|
||||||
#include <boost/detail/shared_count.hpp>
|
|
||||||
#include <boost/detail/workaround.hpp>
|
|
||||||
#include <boost/detail/sp_convertible.hpp>
|
|
||||||
|
|
||||||
#if !defined(BOOST_SP_NO_ATOMIC_ACCESS)
|
|
||||||
#include <boost/detail/spinlock_pool.hpp>
|
|
||||||
#include <boost/memory_order.hpp>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <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 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( 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( 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>
|
|
||||||
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
|
|
||||||
|
|
||||||
shared_ptr( shared_ptr<Y> && r, typename detail::sp_enable_if_convertible<Y,T>::type = detail::sp_empty() )
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
shared_ptr( shared_ptr<Y> && r )
|
|
||||||
|
|
||||||
#endif
|
|
||||||
: px( r.px ), pn() // never throws
|
|
||||||
{
|
|
||||||
pn.swap( r.pn );
|
|
||||||
r.px = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
shared_ptr & operator=( shared_ptr && r ) // never throws
|
|
||||||
{
|
|
||||||
this_type( static_cast< shared_ptr && >( r ) ).swap( *this );
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Y>
|
|
||||||
shared_ptr & operator=( shared_ptr<Y> && r ) // never throws
|
|
||||||
{
|
|
||||||
this_type( static_cast< shared_ptr<Y> && >( r ) ).swap( *this );
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void reset() // never throws in 1.30+
|
|
||||||
{
|
|
||||||
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 );
|
|
||||||
}
|
|
||||||
|
|
||||||
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_SHARED_PTR_HPP_INCLUDED
|
#endif // #ifndef BOOST_SHARED_PTR_HPP_INCLUDED
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#ifndef BOOST_BAD_WEAK_PTR_HPP_INCLUDED
|
#ifndef BOOST_SMART_PTR_BAD_WEAK_PTR_HPP_INCLUDED
|
||||||
#define BOOST_BAD_WEAK_PTR_HPP_INCLUDED
|
#define BOOST_SMART_PTR_BAD_WEAK_PTR_HPP_INCLUDED
|
||||||
|
|
||||||
// MS compatible compilers support #pragma once
|
// MS compatible compilers support #pragma once
|
||||||
|
|
||||||
@ -8,7 +8,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// detail/bad_weak_ptr.hpp
|
// boost/smart_ptr/bad_weak_ptr.hpp
|
||||||
//
|
//
|
||||||
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
|
// 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
|
# pragma warn .8026 // Functions with excep. spec. are not expanded inline
|
||||||
#endif
|
#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: 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...
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/config.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__)
|
||||||
|
# include <boost/smart_ptr/detail/atomic_count_win32.hpp>
|
||||||
|
|
||||||
|
#elif defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 ) && !defined( __arm__ ) && !defined( __hppa ) && ( !defined( __INTEL_COMPILER ) || defined( __ia64__ ) )
|
||||||
|
# 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
|
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_HPP_INCLUDED
|
||||||
#define BOOST_DETAIL_ATOMIC_COUNT_GCC_HPP_INCLUDED
|
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_HPP_INCLUDED
|
||||||
|
|
||||||
//
|
//
|
||||||
// boost/detail/atomic_count_gcc.hpp
|
// boost/detail/atomic_count_gcc.hpp
|
||||||
@ -65,4 +65,4 @@ private:
|
|||||||
|
|
||||||
} // namespace boost
|
} // 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
|
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_X86_HPP_INCLUDED
|
||||||
#define BOOST_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
|
// boost/detail/atomic_count_gcc_x86.hpp
|
||||||
@ -81,4 +81,4 @@ private:
|
|||||||
|
|
||||||
} // namespace boost
|
} // 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
|
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_PTHREADS_HPP_INCLUDED
|
||||||
#define BOOST_DETAIL_ATOMIC_COUNT_PTHREADS_HPP_INCLUDED
|
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_PTHREADS_HPP_INCLUDED
|
||||||
|
|
||||||
//
|
//
|
||||||
// boost/detail/atomic_count_pthreads.hpp
|
// boost/detail/atomic_count_pthreads.hpp
|
||||||
@ -93,4 +93,4 @@ private:
|
|||||||
|
|
||||||
} // namespace boost
|
} // 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
|
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SOLARIS_HPP_INCLUDED
|
||||||
#define BOOST_DETAIL_ATOMIC_COUNT_SOLARIS_HPP_INCLUDED
|
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SOLARIS_HPP_INCLUDED
|
||||||
|
|
||||||
//
|
//
|
||||||
// boost/detail/atomic_count_solaris.hpp
|
// boost/detail/atomic_count_solaris.hpp
|
||||||
@ -56,4 +56,4 @@ private:
|
|||||||
|
|
||||||
} // namespace boost
|
} // 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
|
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SYNC_HPP_INCLUDED
|
||||||
#define BOOST_DETAIL_ATOMIC_COUNT_SYNC_HPP_INCLUDED
|
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SYNC_HPP_INCLUDED
|
||||||
|
|
||||||
//
|
//
|
||||||
// boost/detail/atomic_count_sync.hpp
|
// boost/detail/atomic_count_sync.hpp
|
||||||
@ -58,4 +58,4 @@ private:
|
|||||||
|
|
||||||
} // namespace boost
|
} // 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
|
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_WIN32_HPP_INCLUDED
|
||||||
#define BOOST_DETAIL_ATOMIC_COUNT_WIN32_HPP_INCLUDED
|
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_WIN32_HPP_INCLUDED
|
||||||
|
|
||||||
// MS compatible compilers support #pragma once
|
// MS compatible compilers support #pragma once
|
||||||
|
|
||||||
@ -60,4 +60,4 @@ private:
|
|||||||
|
|
||||||
} // namespace boost
|
} // 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(WIN32) || defined(_WIN32) || defined(__WIN32__)
|
||||||
|
# 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
|
#ifndef BOOST_SMART_PTR_DETAIL_LWM_NOP_HPP_INCLUDED
|
||||||
#define BOOST_DETAIL_LWM_NOP_HPP_INCLUDED
|
#define BOOST_SMART_PTR_DETAIL_LWM_NOP_HPP_INCLUDED
|
||||||
|
|
||||||
// MS compatible compilers support #pragma once
|
// MS compatible compilers support #pragma once
|
||||||
|
|
||||||
@ -34,4 +34,4 @@ public:
|
|||||||
|
|
||||||
} // namespace boost
|
} // 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
|
#ifndef BOOST_SMART_PTR_DETAIL_LWM_PTHREADS_HPP_INCLUDED
|
||||||
#define BOOST_DETAIL_LWM_PTHREADS_HPP_INCLUDED
|
#define BOOST_SMART_PTR_DETAIL_LWM_PTHREADS_HPP_INCLUDED
|
||||||
|
|
||||||
// MS compatible compilers support #pragma once
|
// MS compatible compilers support #pragma once
|
||||||
|
|
||||||
@ -83,4 +83,4 @@ public:
|
|||||||
|
|
||||||
} // namespace boost
|
} // 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
|
#ifndef BOOST_SMART_PTR_DETAIL_LWM_WIN32_CS_HPP_INCLUDED
|
||||||
#define BOOST_DETAIL_LWM_WIN32_CS_HPP_INCLUDED
|
#define BOOST_SMART_PTR_DETAIL_LWM_WIN32_CS_HPP_INCLUDED
|
||||||
|
|
||||||
// MS compatible compilers support #pragma once
|
// MS compatible compilers support #pragma once
|
||||||
|
|
||||||
@ -105,4 +105,4 @@ public:
|
|||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
#endif // #ifndef BOOST_DETAIL_LWM_WIN32_CS_HPP_INCLUDED
|
#endif // #ifndef BOOST_SMART_PTR_DETAIL_LWM_WIN32_CS_HPP_INCLUDED
|
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
|
#ifndef BOOST_SMART_PTR_DETAIL_SHARED_ARRAY_NMT_HPP_INCLUDED
|
||||||
#define BOOST_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
|
// detail/shared_array_nmt.hpp - shared_array.hpp without member templates
|
||||||
@ -17,7 +17,7 @@
|
|||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
#include <boost/checked_delete.hpp>
|
#include <boost/checked_delete.hpp>
|
||||||
#include <boost/throw_exception.hpp>
|
#include <boost/throw_exception.hpp>
|
||||||
#include <boost/detail/atomic_count.hpp>
|
#include <boost/smart_ptr/detail/atomic_count.hpp>
|
||||||
|
|
||||||
#include <cstddef> // for std::ptrdiff_t
|
#include <cstddef> // for std::ptrdiff_t
|
||||||
#include <algorithm> // for std::swap
|
#include <algorithm> // for std::swap
|
||||||
@ -148,4 +148,4 @@ template<class T> void swap(shared_array<T> & a, shared_array<T> & b)
|
|||||||
|
|
||||||
} // namespace boost
|
} // 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
|
#ifndef BOOST_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED
|
||||||
#define BOOST_DETAIL_SHARED_COUNT_HPP_INCLUDED
|
#define BOOST_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED
|
||||||
|
|
||||||
// MS compatible compilers support #pragma once
|
// MS compatible compilers support #pragma once
|
||||||
|
|
||||||
@ -25,9 +25,9 @@
|
|||||||
#include <boost/config.hpp>
|
#include <boost/config.hpp>
|
||||||
#include <boost/checked_delete.hpp>
|
#include <boost/checked_delete.hpp>
|
||||||
#include <boost/throw_exception.hpp>
|
#include <boost/throw_exception.hpp>
|
||||||
#include <boost/detail/bad_weak_ptr.hpp>
|
#include <boost/smart_ptr/bad_weak_ptr.hpp>
|
||||||
#include <boost/detail/sp_counted_base.hpp>
|
#include <boost/smart_ptr/detail/sp_counted_base.hpp>
|
||||||
#include <boost/detail/sp_counted_impl.hpp>
|
#include <boost/smart_ptr/detail/sp_counted_impl.hpp>
|
||||||
#include <boost/detail/workaround.hpp>
|
#include <boost/detail/workaround.hpp>
|
||||||
// In order to avoid circular dependencies with Boost.TR1
|
// In order to avoid circular dependencies with Boost.TR1
|
||||||
// we make sure that our include of <memory> doesn't try to
|
// we make sure that our include of <memory> doesn't try to
|
||||||
@ -427,4 +427,4 @@ inline shared_count::shared_count( weak_count const & r, sp_nothrow_tag ): pi_(
|
|||||||
# pragma warn .8027 // Functions containing try are not expanded inline
|
# pragma warn .8027 // Functions containing try are not expanded inline
|
||||||
#endif
|
#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
|
#ifndef BOOST_SMART_PTR_DETAIL_SHARED_PTR_NMT_HPP_INCLUDED
|
||||||
#define BOOST_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
|
// detail/shared_ptr_nmt.hpp - shared_ptr.hpp without member templates
|
||||||
@ -17,7 +17,7 @@
|
|||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
#include <boost/checked_delete.hpp>
|
#include <boost/checked_delete.hpp>
|
||||||
#include <boost/throw_exception.hpp>
|
#include <boost/throw_exception.hpp>
|
||||||
#include <boost/detail/atomic_count.hpp>
|
#include <boost/smart_ptr/detail/atomic_count.hpp>
|
||||||
|
|
||||||
#ifndef BOOST_NO_AUTO_PTR
|
#ifndef BOOST_NO_AUTO_PTR
|
||||||
# include <memory> // for std::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
|
} // namespace boost
|
||||||
|
|
||||||
#endif // #ifndef BOOST_DETAIL_SHARED_PTR_NMT_HPP_INCLUDED
|
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SHARED_PTR_NMT_HPP_INCLUDED
|
@ -1,5 +1,5 @@
|
|||||||
#ifndef BOOST_DETAIL_SP_CONVERTIBLE_HPP_INCLUDED
|
#ifndef BOOST_SMART_PTR_DETAIL_SP_CONVERTIBLE_HPP_INCLUDED
|
||||||
#define BOOST_DETAIL_SP_CONVERTIBLE_HPP_INCLUDED
|
#define BOOST_SMART_PTR_DETAIL_SP_CONVERTIBLE_HPP_INCLUDED
|
||||||
|
|
||||||
// MS compatible compilers support #pragma once
|
// MS compatible compilers support #pragma once
|
||||||
|
|
||||||
@ -73,4 +73,4 @@ template< class Y, class T > struct sp_enable_if_convertible: public sp_enable_i
|
|||||||
|
|
||||||
#endif // !defined( BOOST_SP_NO_SP_CONVERTIBLE )
|
#endif // !defined( BOOST_SP_NO_SP_CONVERTIBLE )
|
||||||
|
|
||||||
#endif // #ifndef BOOST_DETAIL_SP_TYPEINFO_HPP_INCLUDED
|
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_CONVERTIBLE_HPP_INCLUDED
|
@ -1,5 +1,5 @@
|
|||||||
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED
|
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED
|
||||||
#define BOOST_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED
|
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED
|
||||||
|
|
||||||
// MS compatible compilers support #pragma once
|
// MS compatible compilers support #pragma once
|
||||||
|
|
||||||
@ -20,47 +20,47 @@
|
|||||||
#include <boost/config.hpp>
|
#include <boost/config.hpp>
|
||||||
|
|
||||||
#if defined( BOOST_SP_DISABLE_THREADS )
|
#if defined( BOOST_SP_DISABLE_THREADS )
|
||||||
# include <boost/detail/sp_counted_base_nt.hpp>
|
# include <boost/smart_ptr/detail/sp_counted_base_nt.hpp>
|
||||||
|
|
||||||
#elif defined( BOOST_SP_USE_SPINLOCK )
|
#elif defined( BOOST_SP_USE_SPINLOCK )
|
||||||
# include <boost/detail/sp_counted_base_spin.hpp>
|
# include <boost/smart_ptr/detail/sp_counted_base_spin.hpp>
|
||||||
|
|
||||||
#elif defined( BOOST_SP_USE_PTHREADS )
|
#elif defined( BOOST_SP_USE_PTHREADS )
|
||||||
# include <boost/detail/sp_counted_base_pt.hpp>
|
# include <boost/smart_ptr/detail/sp_counted_base_pt.hpp>
|
||||||
|
|
||||||
#elif defined( BOOST_DISABLE_THREADS ) && !defined( BOOST_SP_ENABLE_THREADS ) && !defined( BOOST_DISABLE_WIN32 )
|
#elif defined( BOOST_DISABLE_THREADS ) && !defined( BOOST_SP_ENABLE_THREADS ) && !defined( BOOST_DISABLE_WIN32 )
|
||||||
# include <boost/detail/sp_counted_base_nt.hpp>
|
# include <boost/smart_ptr/detail/sp_counted_base_nt.hpp>
|
||||||
|
|
||||||
#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) )
|
#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) )
|
||||||
# include <boost/detail/sp_counted_base_gcc_x86.hpp>
|
# include <boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp>
|
||||||
|
|
||||||
#elif defined( __GNUC__ ) && defined( __ia64__ ) && !defined( __INTEL_COMPILER )
|
#elif defined( __GNUC__ ) && defined( __ia64__ ) && !defined( __INTEL_COMPILER )
|
||||||
# include <boost/detail/sp_counted_base_gcc_ia64.hpp>
|
# include <boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp>
|
||||||
|
|
||||||
#elif defined(__HP_aCC) && defined(__ia64)
|
#elif defined(__HP_aCC) && defined(__ia64)
|
||||||
# include <boost/detail/sp_counted_base_acc_ia64.hpp>
|
# include <boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp>
|
||||||
|
|
||||||
#elif defined( __MWERKS__ ) && defined( __POWERPC__ )
|
#elif defined( __MWERKS__ ) && defined( __POWERPC__ )
|
||||||
# include <boost/detail/sp_counted_base_cw_ppc.hpp>
|
# include <boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp>
|
||||||
|
|
||||||
#elif defined( __GNUC__ ) && ( defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc ) )
|
#elif defined( __GNUC__ ) && ( defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc ) )
|
||||||
# include <boost/detail/sp_counted_base_gcc_ppc.hpp>
|
# include <boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp>
|
||||||
|
|
||||||
#elif defined(__GNUC__) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 ) && !defined( __arm__ ) && !defined( __hppa ) && ( !defined( __INTEL_COMPILER ) || defined( __ia64__ ) )
|
#elif defined(__GNUC__) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 ) && !defined( __arm__ ) && !defined( __hppa ) && ( !defined( __INTEL_COMPILER ) || defined( __ia64__ ) )
|
||||||
# include <boost/detail/sp_counted_base_sync.hpp>
|
# include <boost/smart_ptr/detail/sp_counted_base_sync.hpp>
|
||||||
|
|
||||||
#elif defined(__GNUC__) && ( defined( __sparcv9 ) || ( defined( __sparcv8 ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 402 ) ) )
|
#elif defined(__GNUC__) && ( defined( __sparcv9 ) || ( defined( __sparcv8 ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 402 ) ) )
|
||||||
# include <boost/detail/sp_counted_base_gcc_sparc.hpp>
|
# include <boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp>
|
||||||
|
|
||||||
#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ )
|
#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ )
|
||||||
# include <boost/detail/sp_counted_base_w32.hpp>
|
# include <boost/smart_ptr/detail/sp_counted_base_w32.hpp>
|
||||||
|
|
||||||
#elif !defined( BOOST_HAS_THREADS )
|
#elif !defined( BOOST_HAS_THREADS )
|
||||||
# include <boost/detail/sp_counted_base_nt.hpp>
|
# include <boost/smart_ptr/detail/sp_counted_base_nt.hpp>
|
||||||
|
|
||||||
#else
|
#else
|
||||||
# include <boost/detail/sp_counted_base_spin.hpp>
|
# include <boost/smart_ptr/detail/sp_counted_base_spin.hpp>
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED
|
#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
|
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED
|
||||||
#define BOOST_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
|
// detail/sp_counted_base_acc_ia64.hpp - aC++ on HP-UX IA64
|
||||||
@ -147,4 +147,4 @@ public:
|
|||||||
|
|
||||||
} // namespace boost
|
} // 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
|
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED
|
||||||
#define BOOST_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
|
// MS compatible compilers support #pragma once
|
||||||
|
|
||||||
@ -167,4 +167,4 @@ public:
|
|||||||
|
|
||||||
} // namespace boost
|
} // 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
|
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_X86_HPP_INCLUDED
|
||||||
#define BOOST_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
|
// MS compatible compilers support #pragma once
|
||||||
|
|
||||||
@ -155,4 +155,4 @@ public:
|
|||||||
|
|
||||||
} // namespace boost
|
} // 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
|
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED
|
||||||
#define BOOST_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
|
// detail/sp_counted_base_gcc_ia64.hpp - g++ on IA64
|
||||||
@ -154,4 +154,4 @@ public:
|
|||||||
|
|
||||||
} // namespace boost
|
} // 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
|
@ -1,5 +1,5 @@
|
|||||||
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED
|
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED
|
||||||
#define BOOST_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
|
// MS compatible compilers support #pragma once
|
||||||
|
|
||||||
@ -178,4 +178,4 @@ public:
|
|||||||
|
|
||||||
} // namespace boost
|
} // 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
|
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED
|
||||||
#define BOOST_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
|
// MS compatible compilers support #pragma once
|
||||||
|
|
||||||
@ -163,4 +163,4 @@ public:
|
|||||||
|
|
||||||
} // namespace boost
|
} // 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
|
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED
|
||||||
#define BOOST_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
|
// MS compatible compilers support #pragma once
|
||||||
|
|
||||||
@ -170,4 +170,4 @@ public:
|
|||||||
|
|
||||||
} // namespace boost
|
} // 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
|
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_NT_HPP_INCLUDED
|
||||||
#define BOOST_DETAIL_SP_COUNTED_BASE_NT_HPP_INCLUDED
|
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_NT_HPP_INCLUDED
|
||||||
|
|
||||||
// MS compatible compilers support #pragma once
|
// MS compatible compilers support #pragma once
|
||||||
|
|
||||||
@ -104,4 +104,4 @@ public:
|
|||||||
|
|
||||||
} // namespace boost
|
} // 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
|
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED
|
||||||
#define BOOST_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED
|
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED
|
||||||
|
|
||||||
// MS compatible compilers support #pragma once
|
// MS compatible compilers support #pragma once
|
||||||
|
|
||||||
@ -132,4 +132,4 @@ public:
|
|||||||
|
|
||||||
} // namespace boost
|
} // 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
|
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED
|
||||||
#define BOOST_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED
|
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED
|
||||||
|
|
||||||
//
|
//
|
||||||
// detail/sp_counted_base_solaris.hpp
|
// detail/sp_counted_base_solaris.hpp
|
||||||
@ -110,4 +110,4 @@ public:
|
|||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED
|
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED
|
@ -1,5 +1,5 @@
|
|||||||
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED
|
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED
|
||||||
#define BOOST_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED
|
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED
|
||||||
|
|
||||||
// MS compatible compilers support #pragma once
|
// MS compatible compilers support #pragma once
|
||||||
|
|
||||||
@ -19,7 +19,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include <boost/detail/sp_typeinfo.hpp>
|
#include <boost/detail/sp_typeinfo.hpp>
|
||||||
#include <boost/detail/spinlock_pool.hpp>
|
#include <boost/smart_ptr/detail/spinlock_pool.hpp>
|
||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
@ -128,4 +128,4 @@ public:
|
|||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED
|
#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
|
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED
|
||||||
#define BOOST_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED
|
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED
|
||||||
|
|
||||||
// MS compatible compilers support #pragma once
|
// MS compatible compilers support #pragma once
|
||||||
|
|
||||||
@ -152,4 +152,4 @@ public:
|
|||||||
|
|
||||||
} // namespace boost
|
} // 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
|
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED
|
||||||
#define BOOST_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED
|
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED
|
||||||
|
|
||||||
// MS compatible compilers support #pragma once
|
// MS compatible compilers support #pragma once
|
||||||
|
|
||||||
@ -127,4 +127,4 @@ public:
|
|||||||
|
|
||||||
} // namespace boost
|
} // 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
|
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
|
||||||
#define BOOST_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
|
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
|
||||||
|
|
||||||
// MS compatible compilers support #pragma once
|
// MS compatible compilers support #pragma once
|
||||||
|
|
||||||
@ -25,10 +25,10 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <boost/checked_delete.hpp>
|
#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)
|
#if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
|
||||||
#include <boost/detail/quick_allocator.hpp>
|
#include <boost/smart_ptr/detail/quick_allocator.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(BOOST_SP_USE_STD_ALLOCATOR)
|
#if defined(BOOST_SP_USE_STD_ALLOCATOR)
|
||||||
@ -228,4 +228,4 @@ public:
|
|||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
#endif // #ifndef BOOST_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
|
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
|
@ -1,5 +1,5 @@
|
|||||||
#ifndef BOOST_DETAIL_SPINLOCK_HPP_INCLUDED
|
#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_HPP_INCLUDED
|
||||||
#define BOOST_DETAIL_SPINLOCK_HPP_INCLUDED
|
#define BOOST_SMART_PTR_DETAIL_SPINLOCK_HPP_INCLUDED
|
||||||
|
|
||||||
// MS compatible compilers support #pragma once
|
// MS compatible compilers support #pragma once
|
||||||
|
|
||||||
@ -31,17 +31,17 @@
|
|||||||
#include <boost/config.hpp>
|
#include <boost/config.hpp>
|
||||||
|
|
||||||
#if defined(__GNUC__) && defined( __arm__ ) && !defined( __thumb__ )
|
#if defined(__GNUC__) && defined( __arm__ ) && !defined( __thumb__ )
|
||||||
# include <boost/detail/spinlock_gcc_arm.hpp>
|
# include <boost/smart_ptr/detail/spinlock_gcc_arm.hpp>
|
||||||
#elif defined(__GNUC__) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 ) && !defined( __arm__ ) && !defined( __hppa ) && ( !defined( __INTEL_COMPILER ) || defined( __ia64__ ) )
|
#elif defined(__GNUC__) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 ) && !defined( __arm__ ) && !defined( __hppa ) && ( !defined( __INTEL_COMPILER ) || defined( __ia64__ ) )
|
||||||
# include <boost/detail/spinlock_sync.hpp>
|
# include <boost/smart_ptr/detail/spinlock_sync.hpp>
|
||||||
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
|
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
|
||||||
# include <boost/detail/spinlock_w32.hpp>
|
# include <boost/smart_ptr/detail/spinlock_w32.hpp>
|
||||||
#elif defined(BOOST_HAS_PTHREADS)
|
#elif defined(BOOST_HAS_PTHREADS)
|
||||||
# include <boost/detail/spinlock_pt.hpp>
|
# include <boost/smart_ptr/detail/spinlock_pt.hpp>
|
||||||
#elif !defined(BOOST_HAS_THREADS)
|
#elif !defined(BOOST_HAS_THREADS)
|
||||||
# include <boost/detail/spinlock_nt.hpp>
|
# include <boost/smart_ptr/detail/spinlock_nt.hpp>
|
||||||
#else
|
#else
|
||||||
# error Unrecognized threading platform
|
# error Unrecognized threading platform
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // #ifndef BOOST_DETAIL_SPINLOCK_HPP_INCLUDED
|
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_HPP_INCLUDED
|
@ -1,5 +1,5 @@
|
|||||||
#ifndef BOOST_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
|
#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
|
||||||
#define BOOST_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
|
#define BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
|
||||||
|
|
||||||
//
|
//
|
||||||
// Copyright (c) 2008 Peter Dimov
|
// Copyright (c) 2008 Peter Dimov
|
||||||
@ -9,7 +9,7 @@
|
|||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <boost/detail/yield_k.hpp>
|
#include <boost/smart_ptr/detail/yield_k.hpp>
|
||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
@ -82,4 +82,4 @@ public:
|
|||||||
|
|
||||||
#define BOOST_DETAIL_SPINLOCK_INIT {0}
|
#define BOOST_DETAIL_SPINLOCK_INIT {0}
|
||||||
|
|
||||||
#endif // #ifndef BOOST_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
|
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
|
@ -1,5 +1,5 @@
|
|||||||
#ifndef BOOST_DETAIL_SPINLOCK_NT_HPP_INCLUDED
|
#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_NT_HPP_INCLUDED
|
||||||
#define BOOST_DETAIL_SPINLOCK_NT_HPP_INCLUDED
|
#define BOOST_SMART_PTR_DETAIL_SPINLOCK_NT_HPP_INCLUDED
|
||||||
|
|
||||||
// MS compatible compilers support #pragma once
|
// MS compatible compilers support #pragma once
|
||||||
|
|
||||||
@ -86,4 +86,4 @@ public:
|
|||||||
|
|
||||||
#define BOOST_DETAIL_SPINLOCK_INIT { false }
|
#define BOOST_DETAIL_SPINLOCK_INIT { false }
|
||||||
|
|
||||||
#endif // #ifndef BOOST_DETAIL_SPINLOCK_NT_HPP_INCLUDED
|
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_NT_HPP_INCLUDED
|
@ -1,5 +1,5 @@
|
|||||||
#ifndef BOOST_DETAIL_SPINLOCK_POOL_HPP_INCLUDED
|
#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_POOL_HPP_INCLUDED
|
||||||
#define BOOST_DETAIL_SPINLOCK_POOL_HPP_INCLUDED
|
#define BOOST_SMART_PTR_DETAIL_SPINLOCK_POOL_HPP_INCLUDED
|
||||||
|
|
||||||
// MS compatible compilers support #pragma once
|
// MS compatible compilers support #pragma once
|
||||||
|
|
||||||
@ -22,7 +22,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include <boost/config.hpp>
|
#include <boost/config.hpp>
|
||||||
#include <boost/detail/spinlock.hpp>
|
#include <boost/smart_ptr/detail/spinlock.hpp>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
@ -84,4 +84,4 @@ template< int I > spinlock spinlock_pool< I >::pool_[ 41 ] =
|
|||||||
} // namespace detail
|
} // namespace detail
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
#endif // #ifndef BOOST_DETAIL_SPINLOCK_POOL_HPP_INCLUDED
|
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_POOL_HPP_INCLUDED
|
@ -1,5 +1,5 @@
|
|||||||
#ifndef BOOST_DETAIL_SPINLOCK_PT_HPP_INCLUDED
|
#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_PT_HPP_INCLUDED
|
||||||
#define BOOST_DETAIL_SPINLOCK_PT_HPP_INCLUDED
|
#define BOOST_SMART_PTR_DETAIL_SPINLOCK_PT_HPP_INCLUDED
|
||||||
|
|
||||||
// MS compatible compilers support #pragma once
|
// MS compatible compilers support #pragma once
|
||||||
|
|
||||||
@ -76,4 +76,4 @@ public:
|
|||||||
|
|
||||||
#define BOOST_DETAIL_SPINLOCK_INIT { PTHREAD_MUTEX_INITIALIZER }
|
#define BOOST_DETAIL_SPINLOCK_INIT { PTHREAD_MUTEX_INITIALIZER }
|
||||||
|
|
||||||
#endif // #ifndef BOOST_DETAIL_SPINLOCK_PT_HPP_INCLUDED
|
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_PT_HPP_INCLUDED
|
@ -1,5 +1,5 @@
|
|||||||
#ifndef BOOST_DETAIL_SPINLOCK_SYNC_HPP_INCLUDED
|
#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_SYNC_HPP_INCLUDED
|
||||||
#define BOOST_DETAIL_SPINLOCK_SYNC_HPP_INCLUDED
|
#define BOOST_SMART_PTR_DETAIL_SPINLOCK_SYNC_HPP_INCLUDED
|
||||||
|
|
||||||
// MS compatible compilers support #pragma once
|
// MS compatible compilers support #pragma once
|
||||||
|
|
||||||
@ -15,7 +15,7 @@
|
|||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <boost/detail/yield_k.hpp>
|
#include <boost/smart_ptr/detail/yield_k.hpp>
|
||||||
|
|
||||||
#if defined( __ia64__ ) && defined( __INTEL_COMPILER )
|
#if defined( __ia64__ ) && defined( __INTEL_COMPILER )
|
||||||
# include <ia64intrin.h>
|
# include <ia64intrin.h>
|
||||||
@ -84,4 +84,4 @@ public:
|
|||||||
|
|
||||||
#define BOOST_DETAIL_SPINLOCK_INIT {0}
|
#define BOOST_DETAIL_SPINLOCK_INIT {0}
|
||||||
|
|
||||||
#endif // #ifndef BOOST_DETAIL_SPINLOCK_SYNC_HPP_INCLUDED
|
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_SYNC_HPP_INCLUDED
|
@ -1,5 +1,5 @@
|
|||||||
#ifndef BOOST_DETAIL_SPINLOCK_W32_HPP_INCLUDED
|
#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_W32_HPP_INCLUDED
|
||||||
#define BOOST_DETAIL_SPINLOCK_W32_HPP_INCLUDED
|
#define BOOST_SMART_PTR_DETAIL_SPINLOCK_W32_HPP_INCLUDED
|
||||||
|
|
||||||
// MS compatible compilers support #pragma once
|
// MS compatible compilers support #pragma once
|
||||||
|
|
||||||
@ -16,7 +16,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include <boost/detail/interlocked.hpp>
|
#include <boost/detail/interlocked.hpp>
|
||||||
#include <boost/detail/yield_k.hpp>
|
#include <boost/smart_ptr/detail/yield_k.hpp>
|
||||||
|
|
||||||
// BOOST_COMPILER_FENCE
|
// BOOST_COMPILER_FENCE
|
||||||
|
|
||||||
@ -110,4 +110,4 @@ public:
|
|||||||
|
|
||||||
#define BOOST_DETAIL_SPINLOCK_INIT {0}
|
#define BOOST_DETAIL_SPINLOCK_INIT {0}
|
||||||
|
|
||||||
#endif // #ifndef BOOST_DETAIL_SPINLOCK_W32_HPP_INCLUDED
|
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_W32_HPP_INCLUDED
|
@ -1,5 +1,5 @@
|
|||||||
#ifndef BOOST_DETAIL_YIELD_K_HPP_INCLUDED
|
#ifndef BOOST_SMART_PTR_DETAIL_YIELD_K_HPP_INCLUDED
|
||||||
#define BOOST_DETAIL_YIELD_K_HPP_INCLUDED
|
#define BOOST_SMART_PTR_DETAIL_YIELD_K_HPP_INCLUDED
|
||||||
|
|
||||||
// MS compatible compilers support #pragma once
|
// MS compatible compilers support #pragma once
|
||||||
|
|
||||||
@ -8,7 +8,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// boost/detail/yield_k.hpp
|
// yield_k.hpp
|
||||||
//
|
//
|
||||||
// Copyright (c) 2008 Peter Dimov
|
// Copyright (c) 2008 Peter Dimov
|
||||||
//
|
//
|
||||||
@ -146,4 +146,4 @@ inline void yield( unsigned )
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // #ifndef BOOST_DETAIL_YIELD_K_HPP_INCLUDED
|
#endif // #ifndef BOOST_SMART_PTR_DETAIL_YIELD_K_HPP_INCLUDED
|
73
include/boost/smart_ptr/enable_shared_from_this.hpp
Normal file
73
include/boost/smart_ptr/enable_shared_from_this.hpp
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
#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 (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)
|
||||||
|
//
|
||||||
|
// 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(_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
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_SMART_PTR_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED
|
311
include/boost/smart_ptr/intrusive_ptr.hpp
Normal file
311
include/boost/smart_ptr/intrusive_ptr.hpp
Normal file
@ -0,0 +1,311 @@
|
|||||||
|
#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(): 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>
|
||||||
|
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
|
||||||
|
|
||||||
|
intrusive_ptr( intrusive_ptr<U> const & rhs, typename detail::sp_enable_if_convertible<U,T>::type = detail::sp_empty() )
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
intrusive_ptr( intrusive_ptr<U> const & rhs )
|
||||||
|
|
||||||
|
#endif
|
||||||
|
: p_( rhs.get() )
|
||||||
|
{
|
||||||
|
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()
|
||||||
|
{
|
||||||
|
this_type().swap( *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(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
|
433
include/boost/smart_ptr/make_shared.hpp
Normal file
433
include/boost/smart_ptr/make_shared.hpp
Normal file
@ -0,0 +1,433 @@
|
|||||||
|
#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 )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~sp_ms_deleter()
|
||||||
|
{
|
||||||
|
destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator()( T * )
|
||||||
|
{
|
||||||
|
destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
void * address()
|
||||||
|
{
|
||||||
|
return storage_.data_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_initialized()
|
||||||
|
{
|
||||||
|
initialized_ = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template< class T > T forward( T t )
|
||||||
|
{
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
// Zero-argument versions
|
||||||
|
//
|
||||||
|
// Used even when variadic templates are available because of the new T() vs new T issue
|
||||||
|
|
||||||
|
template< class T > boost::shared_ptr< T > make_shared()
|
||||||
|
{
|
||||||
|
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
|
||||||
|
|
||||||
|
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
||||||
|
|
||||||
|
void * pv = pd->address();
|
||||||
|
|
||||||
|
new( pv ) T();
|
||||||
|
pd->set_initialized();
|
||||||
|
|
||||||
|
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class T, class A > boost::shared_ptr< T > allocate_shared( A const & a )
|
||||||
|
{
|
||||||
|
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
|
||||||
|
|
||||||
|
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
||||||
|
|
||||||
|
void * pv = pd->address();
|
||||||
|
|
||||||
|
new( pv ) T();
|
||||||
|
pd->set_initialized();
|
||||||
|
|
||||||
|
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined( BOOST_HAS_VARIADIC_TMPL ) && defined( BOOST_HAS_RVALUE_REFS )
|
||||||
|
|
||||||
|
// Variadic templates, rvalue reference
|
||||||
|
|
||||||
|
template< class T, class... Args > boost::shared_ptr< T > make_shared( Args && ... args )
|
||||||
|
{
|
||||||
|
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
|
||||||
|
|
||||||
|
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
||||||
|
|
||||||
|
void * pv = pd->address();
|
||||||
|
|
||||||
|
new( pv ) T( detail::forward<Args>( args )... );
|
||||||
|
pd->set_initialized();
|
||||||
|
|
||||||
|
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class T, class A, class... Args > boost::shared_ptr< T > allocate_shared( A const & a, Args && ... args )
|
||||||
|
{
|
||||||
|
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
|
||||||
|
|
||||||
|
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
||||||
|
|
||||||
|
void * pv = pd->address();
|
||||||
|
|
||||||
|
new( pv ) T( detail::forward<Args>( args )... );
|
||||||
|
pd->set_initialized();
|
||||||
|
|
||||||
|
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
// C++03 version
|
||||||
|
|
||||||
|
template< class T, class A1 >
|
||||||
|
boost::shared_ptr< T > make_shared( A1 const & a1 )
|
||||||
|
{
|
||||||
|
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
|
||||||
|
|
||||||
|
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
||||||
|
|
||||||
|
void * pv = pd->address();
|
||||||
|
|
||||||
|
new( pv ) T( a1 );
|
||||||
|
pd->set_initialized();
|
||||||
|
|
||||||
|
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class T, class A, class A1 >
|
||||||
|
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1 )
|
||||||
|
{
|
||||||
|
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
|
||||||
|
|
||||||
|
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
||||||
|
|
||||||
|
void * pv = pd->address();
|
||||||
|
|
||||||
|
new( pv ) T( a1 );
|
||||||
|
pd->set_initialized();
|
||||||
|
|
||||||
|
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class T, class A1, class A2 >
|
||||||
|
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2 )
|
||||||
|
{
|
||||||
|
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
|
||||||
|
|
||||||
|
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
||||||
|
|
||||||
|
void * pv = pd->address();
|
||||||
|
|
||||||
|
new( pv ) T( a1, a2 );
|
||||||
|
pd->set_initialized();
|
||||||
|
|
||||||
|
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class T, class A, class A1, class A2 >
|
||||||
|
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2 )
|
||||||
|
{
|
||||||
|
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
|
||||||
|
|
||||||
|
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
||||||
|
|
||||||
|
void * pv = pd->address();
|
||||||
|
|
||||||
|
new( pv ) T( a1, a2 );
|
||||||
|
pd->set_initialized();
|
||||||
|
|
||||||
|
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class T, class A1, class A2, class A3 >
|
||||||
|
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3 )
|
||||||
|
{
|
||||||
|
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
|
||||||
|
|
||||||
|
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
||||||
|
|
||||||
|
void * pv = pd->address();
|
||||||
|
|
||||||
|
new( pv ) T( a1, a2, a3 );
|
||||||
|
pd->set_initialized();
|
||||||
|
|
||||||
|
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class T, class A, class A1, class A2, class A3 >
|
||||||
|
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3 )
|
||||||
|
{
|
||||||
|
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
|
||||||
|
|
||||||
|
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
||||||
|
|
||||||
|
void * pv = pd->address();
|
||||||
|
|
||||||
|
new( pv ) T( a1, a2, a3 );
|
||||||
|
pd->set_initialized();
|
||||||
|
|
||||||
|
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class T, class A1, class A2, class A3, class A4 >
|
||||||
|
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4 )
|
||||||
|
{
|
||||||
|
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
|
||||||
|
|
||||||
|
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
||||||
|
|
||||||
|
void * pv = pd->address();
|
||||||
|
|
||||||
|
new( pv ) T( a1, a2, a3, a4 );
|
||||||
|
pd->set_initialized();
|
||||||
|
|
||||||
|
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class T, class A, class A1, class A2, class A3, class A4 >
|
||||||
|
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4 )
|
||||||
|
{
|
||||||
|
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
|
||||||
|
|
||||||
|
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
||||||
|
|
||||||
|
void * pv = pd->address();
|
||||||
|
|
||||||
|
new( pv ) T( a1, a2, a3, a4 );
|
||||||
|
pd->set_initialized();
|
||||||
|
|
||||||
|
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class T, class A1, class A2, class A3, class A4, class A5 >
|
||||||
|
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5 )
|
||||||
|
{
|
||||||
|
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
|
||||||
|
|
||||||
|
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
||||||
|
|
||||||
|
void * pv = pd->address();
|
||||||
|
|
||||||
|
new( pv ) T( a1, a2, a3, a4, a5 );
|
||||||
|
pd->set_initialized();
|
||||||
|
|
||||||
|
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class T, class A, class A1, class A2, class A3, class A4, class A5 >
|
||||||
|
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5 )
|
||||||
|
{
|
||||||
|
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
|
||||||
|
|
||||||
|
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
||||||
|
|
||||||
|
void * pv = pd->address();
|
||||||
|
|
||||||
|
new( pv ) T( a1, a2, a3, a4, a5 );
|
||||||
|
pd->set_initialized();
|
||||||
|
|
||||||
|
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class T, class A1, class A2, class A3, class A4, class A5, class A6 >
|
||||||
|
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6 )
|
||||||
|
{
|
||||||
|
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
|
||||||
|
|
||||||
|
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
||||||
|
|
||||||
|
void * pv = pd->address();
|
||||||
|
|
||||||
|
new( pv ) T( a1, a2, a3, a4, a5, a6 );
|
||||||
|
pd->set_initialized();
|
||||||
|
|
||||||
|
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6 >
|
||||||
|
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6 )
|
||||||
|
{
|
||||||
|
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
|
||||||
|
|
||||||
|
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
||||||
|
|
||||||
|
void * pv = pd->address();
|
||||||
|
|
||||||
|
new( pv ) T( a1, a2, a3, a4, a5, a6 );
|
||||||
|
pd->set_initialized();
|
||||||
|
|
||||||
|
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7 >
|
||||||
|
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7 )
|
||||||
|
{
|
||||||
|
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
|
||||||
|
|
||||||
|
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
||||||
|
|
||||||
|
void * pv = pd->address();
|
||||||
|
|
||||||
|
new( pv ) T( a1, a2, a3, a4, a5, a6, a7 );
|
||||||
|
pd->set_initialized();
|
||||||
|
|
||||||
|
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7 >
|
||||||
|
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7 )
|
||||||
|
{
|
||||||
|
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
|
||||||
|
|
||||||
|
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
||||||
|
|
||||||
|
void * pv = pd->address();
|
||||||
|
|
||||||
|
new( pv ) T( a1, a2, a3, a4, a5, a6, a7 );
|
||||||
|
pd->set_initialized();
|
||||||
|
|
||||||
|
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 >
|
||||||
|
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8 )
|
||||||
|
{
|
||||||
|
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
|
||||||
|
|
||||||
|
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
||||||
|
|
||||||
|
void * pv = pd->address();
|
||||||
|
|
||||||
|
new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8 );
|
||||||
|
pd->set_initialized();
|
||||||
|
|
||||||
|
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 >
|
||||||
|
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8 )
|
||||||
|
{
|
||||||
|
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
|
||||||
|
|
||||||
|
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
||||||
|
|
||||||
|
void * pv = pd->address();
|
||||||
|
|
||||||
|
new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8 );
|
||||||
|
pd->set_initialized();
|
||||||
|
|
||||||
|
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 >
|
||||||
|
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8, A9 const & a9 )
|
||||||
|
{
|
||||||
|
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
|
||||||
|
|
||||||
|
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
||||||
|
|
||||||
|
void * pv = pd->address();
|
||||||
|
|
||||||
|
new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8, a9 );
|
||||||
|
pd->set_initialized();
|
||||||
|
|
||||||
|
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 >
|
||||||
|
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8, A9 const & a9 )
|
||||||
|
{
|
||||||
|
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
|
||||||
|
|
||||||
|
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
||||||
|
|
||||||
|
void * pv = pd->address();
|
||||||
|
|
||||||
|
new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8, a9 );
|
||||||
|
pd->set_initialized();
|
||||||
|
|
||||||
|
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_SMART_PTR_MAKE_SHARED_HPP_INCLUDED
|
138
include/boost/smart_ptr/scoped_array.hpp
Normal file
138
include/boost/smart_ptr/scoped_array.hpp
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
#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 * ptr;
|
||||||
|
|
||||||
|
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) : 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
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_SMART_PTR_SCOPED_ARRAY_HPP_INCLUDED
|
160
include/boost/smart_ptr/scoped_ptr.hpp
Normal file
160
include/boost/smart_ptr/scoped_ptr.hpp
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
#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 * ptr;
|
||||||
|
|
||||||
|
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): 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
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_SMART_PTR_SCOPED_PTR_HPP_INCLUDED
|
193
include/boost/smart_ptr/shared_array.hpp
Normal file
193
include/boost/smart_ptr/shared_array.hpp
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
#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"
|
||||||
|
|
||||||
|
#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)
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_SMART_PTR_SHARED_ARRAY_HPP_INCLUDED
|
751
include/boost/smart_ptr/shared_ptr.hpp
Normal file
751
include/boost/smart_ptr/shared_ptr.hpp
Normal file
@ -0,0 +1,751 @@
|
|||||||
|
#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 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( 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( 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>
|
||||||
|
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
|
||||||
|
|
||||||
|
shared_ptr( shared_ptr<Y> && r, typename detail::sp_enable_if_convertible<Y,T>::type = detail::sp_empty() )
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
shared_ptr( shared_ptr<Y> && r )
|
||||||
|
|
||||||
|
#endif
|
||||||
|
: px( r.px ), pn() // never throws
|
||||||
|
{
|
||||||
|
pn.swap( r.pn );
|
||||||
|
r.px = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
shared_ptr & operator=( shared_ptr && r ) // never throws
|
||||||
|
{
|
||||||
|
this_type( static_cast< shared_ptr && >( r ) ).swap( *this );
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Y>
|
||||||
|
shared_ptr & operator=( shared_ptr<Y> && r ) // never throws
|
||||||
|
{
|
||||||
|
this_type( static_cast< shared_ptr<Y> && >( r ) ).swap( *this );
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void reset() // never throws in 1.30+
|
||||||
|
{
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
182
include/boost/smart_ptr/weak_ptr.hpp
Normal file
182
include/boost/smart_ptr/weak_ptr.hpp
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
#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
|
||||||
|
: pn(r.pn) // never throws
|
||||||
|
{
|
||||||
|
px = r.lock().get();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Y>
|
||||||
|
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
|
||||||
|
|
||||||
|
weak_ptr( shared_ptr<Y> const & r, typename detail::sp_enable_if_convertible<Y,T>::type = detail::sp_empty() )
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
weak_ptr( shared_ptr<Y> const & r )
|
||||||
|
|
||||||
|
#endif
|
||||||
|
: px( r.px ), pn( r.pn ) // never throws
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#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
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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,177 +6,13 @@
|
|||||||
//
|
//
|
||||||
// Copyright (c) 2001, 2002, 2003 Peter Dimov
|
// Copyright (c) 2001, 2002, 2003 Peter Dimov
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
// accompanying file LICENSE_1_0.txt or copy at
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
//
|
//
|
||||||
// See http://www.boost.org/libs/smart_ptr/weak_ptr.htm for documentation.
|
// See http://www.boost.org/libs/smart_ptr/weak_ptr.htm for documentation.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <memory> // boost.TR1 include order fix
|
#include <boost/smart_ptr/weak_ptr.hpp>
|
||||||
#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>
|
|
||||||
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
|
|
||||||
|
|
||||||
weak_ptr( weak_ptr<Y> const & r, typename detail::sp_enable_if_convertible<Y,T>::type = detail::sp_empty() )
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
weak_ptr( weak_ptr<Y> const & r )
|
|
||||||
|
|
||||||
#endif
|
|
||||||
: pn(r.pn) // never throws
|
|
||||||
{
|
|
||||||
px = r.lock().get();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Y>
|
|
||||||
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
|
|
||||||
|
|
||||||
weak_ptr( shared_ptr<Y> const & r, typename detail::sp_enable_if_convertible<Y,T>::type = detail::sp_empty() )
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
weak_ptr( shared_ptr<Y> const & r )
|
|
||||||
|
|
||||||
#endif
|
|
||||||
: px( r.px ), pn( r.pn ) // never throws
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#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
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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_WEAK_PTR_HPP_INCLUDED
|
#endif // #ifndef BOOST_WEAK_PTR_HPP_INCLUDED
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
// http://www.boost.org/LICENSE_1_0.txt
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <boost/detail/spinlock_pool.hpp>
|
#include <boost/smart_ptr/detail/spinlock_pool.hpp>
|
||||||
|
|
||||||
// Sanity check only
|
// Sanity check only
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user