mirror of
https://github.com/boostorg/smart_ptr.git
synced 2025-10-18 02:15:26 +02:00
Compare commits
24 Commits
boost-1.34
...
boost-1.37
Author | SHA1 | Date | |
---|---|---|---|
|
28a0d328bf | ||
|
6f91ea87c3 | ||
|
6e804e64b8 | ||
|
6ba78f76f6 | ||
|
556b9fe563 | ||
|
991b02b03e | ||
|
31d0c48f18 | ||
|
1b49f08cb8 | ||
|
034c12d244 | ||
|
f884c53bd6 | ||
|
07b4c17980 | ||
|
1bc4f16ff8 | ||
|
774a8d330c | ||
|
0fd94d6d56 | ||
|
866590ee97 | ||
|
a9cd84f43d | ||
|
2fe899cdfe | ||
|
316d00c3fc | ||
|
4ba016d29e | ||
|
60ae24f4ae | ||
|
dba6ebbb01 | ||
|
d2194e3b24 | ||
|
5ab6b24856 | ||
|
87c6b6b403 |
@@ -81,9 +81,8 @@
|
||||
</ul>
|
||||
<hr>
|
||||
<p>Revised 1 February 2002</p>
|
||||
<p>Copyright 2002 Darin Adler. Permission to copy, use, modify, sell and distribute
|
||||
this document is granted provided this copyright notice appears in all copies.
|
||||
This document is provided "as is" without express or implied warranty, and with
|
||||
no claim as to its suitability for any purpose.</p>
|
||||
<p><small>Copyright 2002 Darin Adler. Distributed under the Boost Software License, Version
|
||||
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or
|
||||
copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
|
||||
</body>
|
||||
</html>
|
||||
|
@@ -91,13 +91,24 @@ 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
|
||||
|
@@ -17,11 +17,7 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 2))
|
||||
# include <ext/atomicity.h>
|
||||
#else
|
||||
# include <bits/atomicity.h>
|
||||
#endif
|
||||
#include <bits/atomicity.h>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
84
include/boost/detail/atomic_count_gcc_x86.hpp
Normal file
84
include/boost/detail/atomic_count_gcc_x86.hpp
Normal file
@@ -0,0 +1,84 @@
|
||||
#ifndef BOOST_DETAIL_ATOMIC_COUNT_GCC_X86_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_ATOMIC_COUNT_GCC_X86_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// boost/detail/atomic_count_gcc_x86.hpp
|
||||
//
|
||||
// atomic_count for g++ on 486+/AMD64
|
||||
//
|
||||
// Copyright 2007 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class atomic_count
|
||||
{
|
||||
public:
|
||||
|
||||
explicit atomic_count( long v ) : value_( static_cast< int >( v ) ) {}
|
||||
|
||||
void operator++()
|
||||
{
|
||||
__asm__
|
||||
(
|
||||
"lock\n\t"
|
||||
"incl %0":
|
||||
"+m"( value_ ): // output (%0)
|
||||
: // inputs
|
||||
"cc" // clobbers
|
||||
);
|
||||
}
|
||||
|
||||
long operator--()
|
||||
{
|
||||
return atomic_exchange_and_add( &value_, -1 ) - 1;
|
||||
}
|
||||
|
||||
operator long() const
|
||||
{
|
||||
return atomic_exchange_and_add( &value_, 0 );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
atomic_count(atomic_count const &);
|
||||
atomic_count & operator=(atomic_count const &);
|
||||
|
||||
mutable int value_;
|
||||
|
||||
private:
|
||||
|
||||
static int atomic_exchange_and_add( int * pw, int dv )
|
||||
{
|
||||
// int r = *pw;
|
||||
// *pw += dv;
|
||||
// return r;
|
||||
|
||||
int r;
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"lock\n\t"
|
||||
"xadd %1, %0":
|
||||
"+m"( *pw ), "=r"( r ): // outputs (%0, %1)
|
||||
"1"( dv ): // inputs (%2 == %1)
|
||||
"memory", "cc" // clobbers
|
||||
);
|
||||
|
||||
return r;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_ATOMIC_COUNT_SYNC_HPP_INCLUDED
|
59
include/boost/detail/atomic_count_solaris.hpp
Normal file
59
include/boost/detail/atomic_count_solaris.hpp
Normal file
@@ -0,0 +1,59 @@
|
||||
#ifndef BOOST_DETAIL_ATOMIC_COUNT_SOLARIS_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_ATOMIC_COUNT_SOLARIS_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// boost/detail/atomic_count_solaris.hpp
|
||||
// based on: boost/detail/atomic_count_win32.hpp
|
||||
//
|
||||
// Copyright (c) 2001-2005 Peter Dimov
|
||||
// Copyright (c) 2006 Michael van der Westhuizen
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <atomic.h>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class atomic_count
|
||||
{
|
||||
public:
|
||||
|
||||
explicit atomic_count( uint32_t v ): value_( v )
|
||||
{
|
||||
}
|
||||
|
||||
long operator++()
|
||||
{
|
||||
return atomic_inc_32_nv( &value_ );
|
||||
}
|
||||
|
||||
long operator--()
|
||||
{
|
||||
return atomic_dec_32_nv( &value_ );
|
||||
}
|
||||
|
||||
operator uint32_t() const
|
||||
{
|
||||
return static_cast<uint32_t const volatile &>( value_ );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
atomic_count( atomic_count const & );
|
||||
atomic_count & operator=( atomic_count const & );
|
||||
|
||||
uint32_t value_;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_ATOMIC_COUNT_SOLARIS_HPP_INCLUDED
|
61
include/boost/detail/atomic_count_sync.hpp
Normal file
61
include/boost/detail/atomic_count_sync.hpp
Normal file
@@ -0,0 +1,61 @@
|
||||
#ifndef BOOST_DETAIL_ATOMIC_COUNT_SYNC_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_ATOMIC_COUNT_SYNC_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// boost/detail/atomic_count_sync.hpp
|
||||
//
|
||||
// atomic_count for g++ 4.1+
|
||||
//
|
||||
// http://gcc.gnu.org/onlinedocs/gcc-4.1.1/gcc/Atomic-Builtins.html
|
||||
//
|
||||
// Copyright 2007 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#if defined( __ia64__ ) && defined( __INTEL_COMPILER )
|
||||
# include <ia64intrin.h>
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class atomic_count
|
||||
{
|
||||
public:
|
||||
|
||||
explicit atomic_count( long v ) : value_( v ) {}
|
||||
|
||||
void operator++()
|
||||
{
|
||||
__sync_add_and_fetch( &value_, 1 );
|
||||
}
|
||||
|
||||
long operator--()
|
||||
{
|
||||
return __sync_add_and_fetch( &value_, -1 );
|
||||
}
|
||||
|
||||
operator long() const
|
||||
{
|
||||
return __sync_fetch_and_add( &value_, 0 );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
atomic_count(atomic_count const &);
|
||||
atomic_count & operator=(atomic_count const &);
|
||||
|
||||
mutable long value_;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_ATOMIC_COUNT_SYNC_HPP_INCLUDED
|
@@ -30,10 +30,10 @@
|
||||
|
||||
#if !defined(BOOST_HAS_THREADS)
|
||||
# include <boost/detail/lwm_nop.hpp>
|
||||
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
|
||||
# include <boost/detail/lwm_win32_cs.hpp>
|
||||
#elif defined(BOOST_HAS_PTHREADS)
|
||||
# include <boost/detail/lwm_pthreads.hpp>
|
||||
#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
|
||||
|
@@ -29,7 +29,7 @@ namespace detail
|
||||
|
||||
#ifndef BOOST_USE_WINDOWS_H
|
||||
|
||||
struct CRITICAL_SECTION
|
||||
struct critical_section
|
||||
{
|
||||
struct critical_section_debug * DebugInfo;
|
||||
long LockCount;
|
||||
@@ -43,10 +43,14 @@ struct CRITICAL_SECTION
|
||||
#endif
|
||||
};
|
||||
|
||||
extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSection(CRITICAL_SECTION *);
|
||||
extern "C" __declspec(dllimport) void __stdcall EnterCriticalSection(CRITICAL_SECTION *);
|
||||
extern "C" __declspec(dllimport) void __stdcall LeaveCriticalSection(CRITICAL_SECTION *);
|
||||
extern "C" __declspec(dllimport) void __stdcall DeleteCriticalSection(CRITICAL_SECTION *);
|
||||
extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSection(critical_section *);
|
||||
extern "C" __declspec(dllimport) void __stdcall EnterCriticalSection(critical_section *);
|
||||
extern "C" __declspec(dllimport) void __stdcall LeaveCriticalSection(critical_section *);
|
||||
extern "C" __declspec(dllimport) void __stdcall DeleteCriticalSection(critical_section *);
|
||||
|
||||
#else
|
||||
|
||||
typedef ::CRITICAL_SECTION critical_section;
|
||||
|
||||
#endif // #ifndef BOOST_USE_WINDOWS_H
|
||||
|
||||
@@ -54,7 +58,7 @@ class lightweight_mutex
|
||||
{
|
||||
private:
|
||||
|
||||
CRITICAL_SECTION cs_;
|
||||
critical_section cs_;
|
||||
|
||||
lightweight_mutex(lightweight_mutex const &);
|
||||
lightweight_mutex & operator=(lightweight_mutex const &);
|
||||
|
@@ -28,11 +28,13 @@
|
||||
#include <boost/detail/bad_weak_ptr.hpp>
|
||||
#include <boost/detail/sp_counted_base.hpp>
|
||||
#include <boost/detail/sp_counted_impl.hpp>
|
||||
|
||||
#include <memory> // std::auto_ptr
|
||||
// In order to avoid circular dependencies with Boost.TR1
|
||||
// we make sure that our include of <memory> doesn't try to
|
||||
// pull in the TR1 headers: that's why we use this header
|
||||
// rather than including <memory> directly:
|
||||
#include <boost/config/no_tr1/memory.hpp> // std::auto_ptr
|
||||
#include <functional> // std::less
|
||||
#include <new> // std::bad_alloc
|
||||
#include <typeinfo> // std::type_info in get_deleter
|
||||
|
||||
namespace boost
|
||||
{
|
||||
@@ -47,6 +49,8 @@ int const weak_count_id = 0x298C38A4;
|
||||
|
||||
#endif
|
||||
|
||||
struct sp_nothrow_tag {};
|
||||
|
||||
class weak_count;
|
||||
|
||||
class shared_count
|
||||
@@ -100,11 +104,18 @@ public:
|
||||
#endif
|
||||
}
|
||||
|
||||
template<class P, class D> shared_count(P p, D d): pi_(0)
|
||||
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1200 )
|
||||
template<class Y, class D> shared_count( Y * p, D d ): pi_(0)
|
||||
#else
|
||||
template<class P, class D> shared_count( P p, D d ): pi_(0)
|
||||
#endif
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
, id_(shared_count_id)
|
||||
#endif
|
||||
{
|
||||
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1200 )
|
||||
typedef Y* P;
|
||||
#endif
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
|
||||
try
|
||||
@@ -217,6 +228,7 @@ public:
|
||||
}
|
||||
|
||||
explicit shared_count(weak_count const & r); // throws bad_weak_ptr when r.use_count() == 0
|
||||
shared_count( weak_count const & r, sp_nothrow_tag ); // constructs an empty *this when r.use_count() == 0
|
||||
|
||||
shared_count & operator= (shared_count const & r) // nothrow
|
||||
{
|
||||
@@ -249,6 +261,11 @@ public:
|
||||
return use_count() == 1;
|
||||
}
|
||||
|
||||
bool empty() const // nothrow
|
||||
{
|
||||
return pi_ == 0;
|
||||
}
|
||||
|
||||
friend inline bool operator==(shared_count const & a, shared_count const & b)
|
||||
{
|
||||
return a.pi_ == b.pi_;
|
||||
@@ -259,7 +276,7 @@ public:
|
||||
return std::less<sp_counted_base *>()( a.pi_, b.pi_ );
|
||||
}
|
||||
|
||||
void * get_deleter(std::type_info const & ti) const
|
||||
void * get_deleter( sp_typeinfo const & ti ) const
|
||||
{
|
||||
return pi_? pi_->get_deleter( ti ): 0;
|
||||
}
|
||||
@@ -314,9 +331,13 @@ public:
|
||||
weak_count & operator= (shared_count const & r) // nothrow
|
||||
{
|
||||
sp_counted_base * tmp = r.pi_;
|
||||
if(tmp != 0) tmp->weak_add_ref();
|
||||
if(pi_ != 0) pi_->weak_release();
|
||||
pi_ = tmp;
|
||||
|
||||
if( tmp != pi_ )
|
||||
{
|
||||
if(tmp != 0) tmp->weak_add_ref();
|
||||
if(pi_ != 0) pi_->weak_release();
|
||||
pi_ = tmp;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
@@ -324,9 +345,13 @@ public:
|
||||
weak_count & operator= (weak_count const & r) // nothrow
|
||||
{
|
||||
sp_counted_base * tmp = r.pi_;
|
||||
if(tmp != 0) tmp->weak_add_ref();
|
||||
if(pi_ != 0) pi_->weak_release();
|
||||
pi_ = tmp;
|
||||
|
||||
if( tmp != pi_ )
|
||||
{
|
||||
if(tmp != 0) tmp->weak_add_ref();
|
||||
if(pi_ != 0) pi_->weak_release();
|
||||
pi_ = tmp;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
@@ -365,6 +390,17 @@ inline shared_count::shared_count( weak_count const & r ): pi_( r.pi_ )
|
||||
}
|
||||
}
|
||||
|
||||
inline shared_count::shared_count( weak_count const & r, sp_nothrow_tag ): pi_( r.pi_ )
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
, id_(shared_count_id)
|
||||
#endif
|
||||
{
|
||||
if( pi_ != 0 && !pi_->add_ref_lock() )
|
||||
{
|
||||
pi_ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
76
include/boost/detail/sp_convertible.hpp
Normal file
76
include/boost/detail/sp_convertible.hpp
Normal file
@@ -0,0 +1,76 @@
|
||||
#ifndef BOOST_DETAIL_SP_CONVERTIBLE_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_SP_CONVERTIBLE_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// detail/sp_convertible.hpp
|
||||
//
|
||||
// Copyright 2008 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( BOOST_NO_SFINAE )
|
||||
# define BOOST_SP_NO_SP_CONVERTIBLE
|
||||
#endif
|
||||
|
||||
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ < 303 )
|
||||
# define BOOST_SP_NO_SP_CONVERTIBLE
|
||||
#endif
|
||||
|
||||
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( __BORLANDC__ ) && ( __BORLANDC__ <= 0x610 )
|
||||
# define BOOST_SP_NO_SP_CONVERTIBLE
|
||||
#endif
|
||||
|
||||
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template< class Y, class T > struct sp_convertible
|
||||
{
|
||||
typedef char (&yes) [1];
|
||||
typedef char (&no) [2];
|
||||
|
||||
static yes f( T* );
|
||||
static no f( ... );
|
||||
|
||||
enum _vt { value = sizeof( f( (Y*)0 ) ) == sizeof(yes) };
|
||||
};
|
||||
|
||||
struct sp_empty
|
||||
{
|
||||
};
|
||||
|
||||
template< bool > struct sp_enable_if_convertible_impl;
|
||||
|
||||
template<> struct sp_enable_if_convertible_impl<true>
|
||||
{
|
||||
typedef sp_empty type;
|
||||
};
|
||||
|
||||
template<> struct sp_enable_if_convertible_impl<false>
|
||||
{
|
||||
};
|
||||
|
||||
template< class Y, class T > struct sp_enable_if_convertible: public sp_enable_if_convertible_impl< sp_convertible< Y, T >::value >
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined( BOOST_SP_NO_SP_CONVERTIBLE )
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_SP_TYPEINFO_HPP_INCLUDED
|
@@ -10,7 +10,7 @@
|
||||
//
|
||||
// detail/sp_counted_base.hpp
|
||||
//
|
||||
// Copyright 2005 Peter Dimov
|
||||
// Copyright 2005, 2006 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -20,49 +20,46 @@
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#if defined( BOOST_SP_DISABLE_THREADS )
|
||||
|
||||
# include <boost/detail/sp_counted_base_nt.hpp>
|
||||
|
||||
#elif defined( BOOST_SP_USE_PTHREADS )
|
||||
#elif defined( BOOST_SP_USE_SPINLOCK )
|
||||
# include <boost/detail/sp_counted_base_spin.hpp>
|
||||
|
||||
#elif defined( BOOST_SP_USE_PTHREADS )
|
||||
# include <boost/detail/sp_counted_base_pt.hpp>
|
||||
|
||||
#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) )
|
||||
#elif defined( BOOST_DISABLE_THREADS ) && !defined( BOOST_SP_ENABLE_THREADS ) && !defined( BOOST_DISABLE_WIN32 )
|
||||
# include <boost/detail/sp_counted_base_nt.hpp>
|
||||
|
||||
#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) )
|
||||
# include <boost/detail/sp_counted_base_gcc_x86.hpp>
|
||||
|
||||
//~ #elif defined( __MWERKS__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) )
|
||||
|
||||
//~ # include <boost/detail/sp_counted_base_cw_x86.hpp>
|
||||
|
||||
#elif defined( __GNUC__ ) && defined( __ia64__ ) && !defined( __INTEL_COMPILER )
|
||||
|
||||
# include <boost/detail/sp_counted_base_gcc_ia64.hpp>
|
||||
|
||||
#elif defined( __MWERKS__ ) && defined( __POWERPC__ )
|
||||
#elif defined(__HP_aCC) && defined(__ia64)
|
||||
# include <boost/detail/sp_counted_base_acc_ia64.hpp>
|
||||
|
||||
#elif defined( __MWERKS__ ) && defined( __POWERPC__ )
|
||||
# include <boost/detail/sp_counted_base_cw_ppc.hpp>
|
||||
|
||||
#elif defined( __GNUC__ ) && ( defined( __powerpc__ ) || defined( __ppc__ ) )
|
||||
|
||||
#elif defined( __GNUC__ ) && ( defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc ) )
|
||||
# include <boost/detail/sp_counted_base_gcc_ppc.hpp>
|
||||
|
||||
#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ )
|
||||
#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>
|
||||
|
||||
#elif defined(__GNUC__) && ( defined( __sparcv9 ) || ( defined( __sparcv8 ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 402 ) ) )
|
||||
# include <boost/detail/sp_counted_base_gcc_sparc.hpp>
|
||||
|
||||
#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ )
|
||||
# include <boost/detail/sp_counted_base_w32.hpp>
|
||||
|
||||
#elif !defined( BOOST_HAS_THREADS )
|
||||
|
||||
# include <boost/detail/sp_counted_base_nt.hpp>
|
||||
|
||||
#elif defined( BOOST_HAS_PTHREADS )
|
||||
|
||||
# include <boost/detail/sp_counted_base_pt.hpp>
|
||||
|
||||
#else
|
||||
|
||||
// Use #define BOOST_DISABLE_THREADS to avoid the error
|
||||
# error Unrecognized threading platform
|
||||
# include <boost/detail/sp_counted_base_spin.hpp>
|
||||
|
||||
#endif
|
||||
|
||||
|
150
include/boost/detail/sp_counted_base_acc_ia64.hpp
Normal file
150
include/boost/detail/sp_counted_base_acc_ia64.hpp
Normal file
@@ -0,0 +1,150 @@
|
||||
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// detail/sp_counted_base_acc_ia64.hpp - aC++ on HP-UX IA64
|
||||
//
|
||||
// Copyright 2007 Baruch Zilber
|
||||
// Copyright 2007 Boris Gubenko
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
//
|
||||
// Lock-free algorithm by Alexander Terekhov
|
||||
//
|
||||
|
||||
#include <boost/detail/sp_typeinfo.hpp>
|
||||
#include <machine/sys/inline.h>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
inline void atomic_increment( int * pw )
|
||||
{
|
||||
// ++*pw;
|
||||
|
||||
_Asm_fetchadd(_FASZ_W, _SEM_REL, pw, +1, _LDHINT_NONE);
|
||||
}
|
||||
|
||||
inline int atomic_decrement( int * pw )
|
||||
{
|
||||
// return --*pw;
|
||||
|
||||
int r = static_cast<int>(_Asm_fetchadd(_FASZ_W, _SEM_REL, pw, -1, _LDHINT_NONE));
|
||||
if (1 == r)
|
||||
{
|
||||
_Asm_mf();
|
||||
}
|
||||
|
||||
return r - 1;
|
||||
}
|
||||
|
||||
inline int atomic_conditional_increment( int * pw )
|
||||
{
|
||||
// if( *pw != 0 ) ++*pw;
|
||||
// return *pw;
|
||||
|
||||
int v = *pw;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (0 == v)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
_Asm_mov_to_ar(_AREG_CCV,
|
||||
v,
|
||||
(_UP_CALL_FENCE | _UP_SYS_FENCE | _DOWN_CALL_FENCE | _DOWN_SYS_FENCE));
|
||||
int r = static_cast<int>(_Asm_cmpxchg(_SZ_W, _SEM_ACQ, pw, v + 1, _LDHINT_NONE));
|
||||
if (r == v)
|
||||
{
|
||||
return r + 1;
|
||||
}
|
||||
|
||||
v = r;
|
||||
}
|
||||
}
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
int use_count_; // #shared
|
||||
int weak_count_; // #weak + (#shared != 0)
|
||||
|
||||
public:
|
||||
|
||||
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~sp_counted_base() // nothrow
|
||||
{
|
||||
}
|
||||
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
|
||||
virtual void dispose() = 0; // nothrow
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
atomic_increment( &use_count_ );
|
||||
}
|
||||
|
||||
bool add_ref_lock() // true on success
|
||||
{
|
||||
return atomic_conditional_increment( &use_count_ ) != 0;
|
||||
}
|
||||
|
||||
void release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &use_count_ ) == 0 )
|
||||
{
|
||||
dispose();
|
||||
weak_release();
|
||||
}
|
||||
}
|
||||
|
||||
void weak_add_ref() // nothrow
|
||||
{
|
||||
atomic_increment( &weak_count_ );
|
||||
}
|
||||
|
||||
void weak_release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &weak_count_ ) == 0 )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
return static_cast<int const volatile &>( use_count_ ); // TODO use ld.acq here
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED
|
@@ -24,7 +24,7 @@
|
||||
// formulation
|
||||
//
|
||||
|
||||
#include <typeinfo>
|
||||
#include <boost/detail/sp_typeinfo.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
@@ -123,7 +123,7 @@ public:
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( std::type_info const & ti ) = 0;
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
|
@@ -25,7 +25,7 @@
|
||||
// formulation
|
||||
//
|
||||
|
||||
#include <typeinfo>
|
||||
#include <boost/detail/sp_typeinfo.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
@@ -111,7 +111,7 @@ public:
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( std::type_info const & ti ) = 0;
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
|
@@ -16,7 +16,7 @@
|
||||
// Lock-free algorithm by Alexander Terekhov
|
||||
//
|
||||
|
||||
#include <typeinfo>
|
||||
#include <boost/detail/sp_typeinfo.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
@@ -110,7 +110,7 @@ public:
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( std::type_info const & ti ) = 0;
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
|
@@ -24,7 +24,7 @@
|
||||
// formulation
|
||||
//
|
||||
|
||||
#include <typeinfo>
|
||||
#include <boost/detail/sp_typeinfo.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
@@ -134,7 +134,7 @@ public:
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( std::type_info const & ti ) = 0;
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
|
166
include/boost/detail/sp_counted_base_gcc_sparc.hpp
Normal file
166
include/boost/detail/sp_counted_base_gcc_sparc.hpp
Normal file
@@ -0,0 +1,166 @@
|
||||
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// detail/sp_counted_base_gcc_sparc.hpp - g++ on Sparc V8+
|
||||
//
|
||||
// Copyright (c) 2006 Piotr Wyderski
|
||||
// Copyright (c) 2006 Tomas Puverle
|
||||
// Copyright (c) 2006 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
// Thanks to Michael van der Westhuizen
|
||||
|
||||
#include <boost/detail/sp_typeinfo.hpp>
|
||||
#include <inttypes.h> // int32_t
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
inline int32_t compare_and_swap( int32_t * dest_, int32_t compare_, int32_t swap_ )
|
||||
{
|
||||
__asm__ __volatile__( "cas %0, %2, %1"
|
||||
: "+m" (*dest_), "+r" (swap_)
|
||||
: "r" (compare_)
|
||||
: "memory" );
|
||||
|
||||
return swap_;
|
||||
}
|
||||
|
||||
inline int32_t atomic_fetch_and_add( int32_t * pw, int32_t dv )
|
||||
{
|
||||
// long r = *pw;
|
||||
// *pw += dv;
|
||||
// return r;
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
int32_t r = *pw;
|
||||
|
||||
if( __builtin_expect((compare_and_swap(pw, r, r + dv) == r), 1) )
|
||||
{
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void atomic_increment( int32_t * pw )
|
||||
{
|
||||
atomic_fetch_and_add( pw, 1 );
|
||||
}
|
||||
|
||||
inline int32_t atomic_decrement( int32_t * pw )
|
||||
{
|
||||
return atomic_fetch_and_add( pw, -1 );
|
||||
}
|
||||
|
||||
inline int32_t atomic_conditional_increment( int32_t * pw )
|
||||
{
|
||||
// long r = *pw;
|
||||
// if( r != 0 ) ++*pw;
|
||||
// return r;
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
int32_t r = *pw;
|
||||
|
||||
if( r == 0 )
|
||||
{
|
||||
return r;
|
||||
}
|
||||
|
||||
if( __builtin_expect( ( compare_and_swap( pw, r, r + 1 ) == r ), 1 ) )
|
||||
{
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
int32_t use_count_; // #shared
|
||||
int32_t weak_count_; // #weak + (#shared != 0)
|
||||
|
||||
public:
|
||||
|
||||
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~sp_counted_base() // nothrow
|
||||
{
|
||||
}
|
||||
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
|
||||
virtual void dispose() = 0; // nothrow
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
atomic_increment( &use_count_ );
|
||||
}
|
||||
|
||||
bool add_ref_lock() // true on success
|
||||
{
|
||||
return atomic_conditional_increment( &use_count_ ) != 0;
|
||||
}
|
||||
|
||||
void release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &use_count_ ) == 1 )
|
||||
{
|
||||
dispose();
|
||||
weak_release();
|
||||
}
|
||||
}
|
||||
|
||||
void weak_add_ref() // nothrow
|
||||
{
|
||||
atomic_increment( &weak_count_ );
|
||||
}
|
||||
|
||||
void weak_release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &weak_count_ ) == 1 )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
return const_cast< int32_t const volatile & >( use_count_ );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED
|
@@ -24,7 +24,7 @@
|
||||
// formulation
|
||||
//
|
||||
|
||||
#include <typeinfo>
|
||||
#include <boost/detail/sp_typeinfo.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
@@ -126,7 +126,7 @@ public:
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( std::type_info const & ti ) = 0;
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
|
@@ -18,7 +18,7 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <typeinfo>
|
||||
#include <boost/detail/sp_typeinfo.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
@@ -58,7 +58,7 @@ public:
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( std::type_info const & ti ) = 0;
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
|
@@ -18,7 +18,7 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <typeinfo>
|
||||
#include <boost/detail/sp_typeinfo.hpp>
|
||||
#include <pthread.h>
|
||||
|
||||
namespace boost
|
||||
@@ -69,7 +69,7 @@ public:
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( std::type_info const & ti ) = 0;
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
|
113
include/boost/detail/sp_counted_base_solaris.hpp
Normal file
113
include/boost/detail/sp_counted_base_solaris.hpp
Normal file
@@ -0,0 +1,113 @@
|
||||
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// detail/sp_counted_base_solaris.hpp
|
||||
// based on: detail/sp_counted_base_w32.hpp
|
||||
//
|
||||
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
|
||||
// Copyright 2004-2005 Peter Dimov
|
||||
// Copyright 2006 Michael van der Westhuizen
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
//
|
||||
// Lock-free algorithm by Alexander Terekhov
|
||||
//
|
||||
// Thanks to Ben Hitchings for the #weak + (#shared != 0)
|
||||
// formulation
|
||||
//
|
||||
|
||||
#include <boost/detail/sp_typeinfo.hpp>
|
||||
#include <atomic.h>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
uint32_t use_count_; // #shared
|
||||
uint32_t weak_count_; // #weak + (#shared != 0)
|
||||
|
||||
public:
|
||||
|
||||
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~sp_counted_base() // nothrow
|
||||
{
|
||||
}
|
||||
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
|
||||
virtual void dispose() = 0; // nothrow
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
atomic_inc_32( &use_count_ );
|
||||
}
|
||||
|
||||
bool add_ref_lock() // true on success
|
||||
{
|
||||
for( ;; )
|
||||
{
|
||||
uint32_t tmp = static_cast< uint32_t const volatile& >( use_count_ );
|
||||
if( tmp == 0 ) return false;
|
||||
if( atomic_cas_32( &use_count_, tmp, tmp + 1 ) == tmp ) return true;
|
||||
}
|
||||
}
|
||||
|
||||
void release() // nothrow
|
||||
{
|
||||
if( atomic_dec_32_nv( &use_count_ ) == 0 )
|
||||
{
|
||||
dispose();
|
||||
weak_release();
|
||||
}
|
||||
}
|
||||
|
||||
void weak_add_ref() // nothrow
|
||||
{
|
||||
atomic_inc_32( &weak_count_ );
|
||||
}
|
||||
|
||||
void weak_release() // nothrow
|
||||
{
|
||||
if( atomic_dec_32_nv( &weak_count_ ) == 0 )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
return static_cast<long const volatile &>( use_count_ );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED
|
131
include/boost/detail/sp_counted_base_spin.hpp
Normal file
131
include/boost/detail/sp_counted_base_spin.hpp
Normal file
@@ -0,0 +1,131 @@
|
||||
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// detail/sp_counted_base_spin.hpp - spinlock pool atomic emulation
|
||||
//
|
||||
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
|
||||
// Copyright 2004-2008 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <boost/detail/sp_typeinfo.hpp>
|
||||
#include <boost/detail/spinlock_pool.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
inline int atomic_exchange_and_add( int * pw, int dv )
|
||||
{
|
||||
spinlock_pool<1>::scoped_lock lock( pw );
|
||||
|
||||
int r = *pw;
|
||||
*pw += dv;
|
||||
return r;
|
||||
}
|
||||
|
||||
inline void atomic_increment( int * pw )
|
||||
{
|
||||
spinlock_pool<1>::scoped_lock lock( pw );
|
||||
++*pw;
|
||||
}
|
||||
|
||||
inline int atomic_conditional_increment( int * pw )
|
||||
{
|
||||
spinlock_pool<1>::scoped_lock lock( pw );
|
||||
|
||||
int rv = *pw;
|
||||
if( rv != 0 ) ++*pw;
|
||||
return rv;
|
||||
}
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
int use_count_; // #shared
|
||||
int weak_count_; // #weak + (#shared != 0)
|
||||
|
||||
public:
|
||||
|
||||
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~sp_counted_base() // nothrow
|
||||
{
|
||||
}
|
||||
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
|
||||
virtual void dispose() = 0; // nothrow
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
atomic_increment( &use_count_ );
|
||||
}
|
||||
|
||||
bool add_ref_lock() // true on success
|
||||
{
|
||||
return atomic_conditional_increment( &use_count_ ) != 0;
|
||||
}
|
||||
|
||||
void release() // nothrow
|
||||
{
|
||||
if( atomic_exchange_and_add( &use_count_, -1 ) == 1 )
|
||||
{
|
||||
dispose();
|
||||
weak_release();
|
||||
}
|
||||
}
|
||||
|
||||
void weak_add_ref() // nothrow
|
||||
{
|
||||
atomic_increment( &weak_count_ );
|
||||
}
|
||||
|
||||
void weak_release() // nothrow
|
||||
{
|
||||
if( atomic_exchange_and_add( &weak_count_, -1 ) == 1 )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
spinlock_pool<1>::scoped_lock lock( &use_count_ );
|
||||
return use_count_;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED
|
155
include/boost/detail/sp_counted_base_sync.hpp
Normal file
155
include/boost/detail/sp_counted_base_sync.hpp
Normal file
@@ -0,0 +1,155 @@
|
||||
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// detail/sp_counted_base_sync.hpp - g++ 4.1+ __sync intrinsics
|
||||
//
|
||||
// Copyright (c) 2007 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/detail/sp_typeinfo.hpp>
|
||||
#include <limits.h>
|
||||
|
||||
#if defined( __ia64__ ) && defined( __INTEL_COMPILER )
|
||||
# include <ia64intrin.h>
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
#if INT_MAX >= 2147483647
|
||||
|
||||
typedef int sp_int32_t;
|
||||
|
||||
#else
|
||||
|
||||
typedef long sp_int32_t;
|
||||
|
||||
#endif
|
||||
|
||||
inline void atomic_increment( sp_int32_t * pw )
|
||||
{
|
||||
__sync_fetch_and_add( pw, 1 );
|
||||
}
|
||||
|
||||
inline sp_int32_t atomic_decrement( sp_int32_t * pw )
|
||||
{
|
||||
return __sync_fetch_and_add( pw, -1 );
|
||||
}
|
||||
|
||||
inline sp_int32_t atomic_conditional_increment( sp_int32_t * pw )
|
||||
{
|
||||
// long r = *pw;
|
||||
// if( r != 0 ) ++*pw;
|
||||
// return r;
|
||||
|
||||
sp_int32_t r = *pw;
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
if( r == 0 )
|
||||
{
|
||||
return r;
|
||||
}
|
||||
|
||||
sp_int32_t r2 = __sync_val_compare_and_swap( pw, r, r + 1 );
|
||||
|
||||
if( r2 == r )
|
||||
{
|
||||
return r;
|
||||
}
|
||||
else
|
||||
{
|
||||
r = r2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
sp_int32_t use_count_; // #shared
|
||||
sp_int32_t weak_count_; // #weak + (#shared != 0)
|
||||
|
||||
public:
|
||||
|
||||
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~sp_counted_base() // nothrow
|
||||
{
|
||||
}
|
||||
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
|
||||
virtual void dispose() = 0; // nothrow
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
atomic_increment( &use_count_ );
|
||||
}
|
||||
|
||||
bool add_ref_lock() // true on success
|
||||
{
|
||||
return atomic_conditional_increment( &use_count_ ) != 0;
|
||||
}
|
||||
|
||||
void release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &use_count_ ) == 1 )
|
||||
{
|
||||
dispose();
|
||||
weak_release();
|
||||
}
|
||||
}
|
||||
|
||||
void weak_add_ref() // nothrow
|
||||
{
|
||||
atomic_increment( &weak_count_ );
|
||||
}
|
||||
|
||||
void weak_release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &weak_count_ ) == 1 )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
return const_cast< sp_int32_t const volatile & >( use_count_ );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED
|
@@ -26,7 +26,7 @@
|
||||
|
||||
#include <boost/detail/interlocked.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <typeinfo>
|
||||
#include <boost/detail/sp_typeinfo.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
@@ -66,7 +66,7 @@ public:
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( std::type_info const & ti ) = 0;
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
|
@@ -35,7 +35,6 @@
|
||||
#include <memory> // std::allocator
|
||||
#endif
|
||||
|
||||
#include <typeinfo> // std::type_info in get_deleter
|
||||
#include <cstddef> // std::size_t
|
||||
|
||||
namespace boost
|
||||
@@ -79,7 +78,7 @@ public:
|
||||
boost::checked_delete( px_ );
|
||||
}
|
||||
|
||||
virtual void * get_deleter( std::type_info const & )
|
||||
virtual void * get_deleter( detail::sp_typeinfo const & )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -145,9 +144,9 @@ public:
|
||||
del( ptr );
|
||||
}
|
||||
|
||||
virtual void * get_deleter( std::type_info const & ti )
|
||||
virtual void * get_deleter( detail::sp_typeinfo const & ti )
|
||||
{
|
||||
return ti == typeid(D)? &del: 0;
|
||||
return ti == BOOST_SP_TYPEID(D)? &reinterpret_cast<char&>( del ): 0;
|
||||
}
|
||||
|
||||
#if defined(BOOST_SP_USE_STD_ALLOCATOR)
|
||||
@@ -215,9 +214,9 @@ public:
|
||||
a2.deallocate( this, 1 );
|
||||
}
|
||||
|
||||
virtual void * get_deleter( std::type_info const & ti )
|
||||
virtual void * get_deleter( detail::sp_typeinfo const & ti )
|
||||
{
|
||||
return ti == typeid( D )? &d_: 0;
|
||||
return ti == BOOST_SP_TYPEID( D )? &reinterpret_cast<char&>( d_ ): 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
83
include/boost/detail/sp_typeinfo.hpp
Normal file
83
include/boost/detail/sp_typeinfo.hpp
Normal file
@@ -0,0 +1,83 @@
|
||||
#ifndef BOOST_DETAIL_SP_TYPEINFO_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_SP_TYPEINFO_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// detail/sp_typeinfo.hpp
|
||||
//
|
||||
// Copyright 2007 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#if defined( BOOST_NO_TYPEID )
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
typedef void* sp_typeinfo;
|
||||
|
||||
template<class T> struct sp_typeid_
|
||||
{
|
||||
static char v_;
|
||||
};
|
||||
|
||||
template<class T> char sp_typeid_< T >::v_;
|
||||
|
||||
template<class T> struct sp_typeid_< T const >: sp_typeid_< T >
|
||||
{
|
||||
};
|
||||
|
||||
template<class T> struct sp_typeid_< T volatile >: sp_typeid_< T >
|
||||
{
|
||||
};
|
||||
|
||||
template<class T> struct sp_typeid_< T const volatile >: sp_typeid_< T >
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#define BOOST_SP_TYPEID(T) (&boost::detail::sp_typeid_<T>::v_)
|
||||
|
||||
#else
|
||||
|
||||
#include <typeinfo>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
#if defined( BOOST_NO_STD_TYPEINFO )
|
||||
|
||||
typedef ::type_info sp_typeinfo;
|
||||
|
||||
#else
|
||||
|
||||
typedef std::type_info sp_typeinfo;
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#define BOOST_SP_TYPEID(T) typeid(T)
|
||||
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_SP_TYPEINFO_HPP_INCLUDED
|
47
include/boost/detail/spinlock.hpp
Normal file
47
include/boost/detail/spinlock.hpp
Normal file
@@ -0,0 +1,47 @@
|
||||
#ifndef BOOST_DETAIL_SPINLOCK_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_SPINLOCK_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// boost/detail/spinlock.hpp
|
||||
//
|
||||
// Copyright (c) 2008 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// struct spinlock
|
||||
// {
|
||||
// void lock();
|
||||
// bool try_lock();
|
||||
// void unlock();
|
||||
//
|
||||
// class scoped_lock;
|
||||
// };
|
||||
//
|
||||
// #define BOOST_DETAIL_SPINLOCK_INIT <unspecified>
|
||||
//
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#if defined(__GNUC__) && defined( __arm__ ) && !defined( __thumb__ )
|
||||
# include <boost/detail/spinlock_gcc_arm.hpp>
|
||||
#elif defined(__GNUC__) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 ) && !defined( __arm__ ) && !defined( __hppa ) && ( !defined( __INTEL_COMPILER ) || defined( __ia64__ ) )
|
||||
# include <boost/detail/spinlock_sync.hpp>
|
||||
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
|
||||
# include <boost/detail/spinlock_w32.hpp>
|
||||
#elif defined(BOOST_HAS_PTHREADS)
|
||||
# include <boost/detail/spinlock_pt.hpp>
|
||||
#elif !defined(BOOST_HAS_THREADS)
|
||||
# include <boost/detail/spinlock_nt.hpp>
|
||||
#else
|
||||
# error Unrecognized threading platform
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_SPINLOCK_HPP_INCLUDED
|
85
include/boost/detail/spinlock_gcc_arm.hpp
Normal file
85
include/boost/detail/spinlock_gcc_arm.hpp
Normal file
@@ -0,0 +1,85 @@
|
||||
#ifndef BOOST_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// Copyright (c) 2008 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <boost/detail/yield_k.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class spinlock
|
||||
{
|
||||
public:
|
||||
|
||||
int v_;
|
||||
|
||||
public:
|
||||
|
||||
bool try_lock()
|
||||
{
|
||||
int r;
|
||||
|
||||
__asm__ __volatile__(
|
||||
"swp %0, %1, [%2]":
|
||||
"=&r"( r ): // outputs
|
||||
"r"( 1 ), "r"( &v_ ): // inputs
|
||||
"memory", "cc" );
|
||||
|
||||
return r == 0;
|
||||
}
|
||||
|
||||
void lock()
|
||||
{
|
||||
for( unsigned k = 0; !try_lock(); ++k )
|
||||
{
|
||||
boost::detail::yield( k );
|
||||
}
|
||||
}
|
||||
|
||||
void unlock()
|
||||
{
|
||||
__asm__ __volatile__( "" ::: "memory" );
|
||||
*const_cast< int volatile* >( &v_ ) = 0;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
class scoped_lock
|
||||
{
|
||||
private:
|
||||
|
||||
spinlock & sp_;
|
||||
|
||||
scoped_lock( scoped_lock const & );
|
||||
scoped_lock & operator=( scoped_lock const & );
|
||||
|
||||
public:
|
||||
|
||||
explicit scoped_lock( spinlock & sp ): sp_( sp )
|
||||
{
|
||||
sp.lock();
|
||||
}
|
||||
|
||||
~scoped_lock()
|
||||
{
|
||||
sp_.unlock();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace boost
|
||||
|
||||
#define BOOST_DETAIL_SPINLOCK_INIT {0}
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
|
89
include/boost/detail/spinlock_nt.hpp
Normal file
89
include/boost/detail/spinlock_nt.hpp
Normal file
@@ -0,0 +1,89 @@
|
||||
#ifndef BOOST_DETAIL_SPINLOCK_NT_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_SPINLOCK_NT_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// Copyright (c) 2008 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class spinlock
|
||||
{
|
||||
public:
|
||||
|
||||
bool locked_;
|
||||
|
||||
public:
|
||||
|
||||
inline bool try_lock()
|
||||
{
|
||||
if( locked_ )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
locked_ = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
inline void lock()
|
||||
{
|
||||
BOOST_ASSERT( !locked_ );
|
||||
locked_ = true;
|
||||
}
|
||||
|
||||
inline void unlock()
|
||||
{
|
||||
BOOST_ASSERT( locked_ );
|
||||
locked_ = false;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
class scoped_lock
|
||||
{
|
||||
private:
|
||||
|
||||
spinlock & sp_;
|
||||
|
||||
scoped_lock( scoped_lock const & );
|
||||
scoped_lock & operator=( scoped_lock const & );
|
||||
|
||||
public:
|
||||
|
||||
explicit scoped_lock( spinlock & sp ): sp_( sp )
|
||||
{
|
||||
sp.lock();
|
||||
}
|
||||
|
||||
~scoped_lock()
|
||||
{
|
||||
sp_.unlock();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace boost
|
||||
|
||||
#define BOOST_DETAIL_SPINLOCK_INIT { false }
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_SPINLOCK_NT_HPP_INCLUDED
|
87
include/boost/detail/spinlock_pool.hpp
Normal file
87
include/boost/detail/spinlock_pool.hpp
Normal file
@@ -0,0 +1,87 @@
|
||||
#ifndef BOOST_DETAIL_SPINLOCK_POOL_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_SPINLOCK_POOL_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// boost/detail/spinlock_pool.hpp
|
||||
//
|
||||
// Copyright (c) 2008 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// spinlock_pool<0> is reserved for atomic<>, when/if it arrives
|
||||
// spinlock_pool<1> is reserved for shared_ptr reference counts
|
||||
// spinlock_pool<2> is reserved for shared_ptr atomic access
|
||||
//
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/detail/spinlock.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template< int I > class spinlock_pool
|
||||
{
|
||||
private:
|
||||
|
||||
static spinlock pool_[ 41 ];
|
||||
|
||||
public:
|
||||
|
||||
static spinlock & spinlock_for( void const * pv )
|
||||
{
|
||||
std::size_t i = reinterpret_cast< std::size_t >( pv ) % 41;
|
||||
return pool_[ i ];
|
||||
}
|
||||
|
||||
class scoped_lock
|
||||
{
|
||||
private:
|
||||
|
||||
spinlock & sp_;
|
||||
|
||||
scoped_lock( scoped_lock const & );
|
||||
scoped_lock & operator=( scoped_lock const & );
|
||||
|
||||
public:
|
||||
|
||||
explicit scoped_lock( void const * pv ): sp_( spinlock_for( pv ) )
|
||||
{
|
||||
sp_.lock();
|
||||
}
|
||||
|
||||
~scoped_lock()
|
||||
{
|
||||
sp_.unlock();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template< int I > spinlock spinlock_pool< I >::pool_[ 41 ] =
|
||||
{
|
||||
BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
|
||||
BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
|
||||
BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
|
||||
BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
|
||||
BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
|
||||
BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
|
||||
BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
|
||||
BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
|
||||
BOOST_DETAIL_SPINLOCK_INIT
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_SPINLOCK_POOL_HPP_INCLUDED
|
79
include/boost/detail/spinlock_pt.hpp
Normal file
79
include/boost/detail/spinlock_pt.hpp
Normal file
@@ -0,0 +1,79 @@
|
||||
#ifndef BOOST_DETAIL_SPINLOCK_PT_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_SPINLOCK_PT_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// Copyright (c) 2008 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class spinlock
|
||||
{
|
||||
public:
|
||||
|
||||
pthread_mutex_t v_;
|
||||
|
||||
public:
|
||||
|
||||
bool try_lock()
|
||||
{
|
||||
return pthread_mutex_trylock( &v_ ) == 0;
|
||||
}
|
||||
|
||||
void lock()
|
||||
{
|
||||
pthread_mutex_lock( &v_ );
|
||||
}
|
||||
|
||||
void unlock()
|
||||
{
|
||||
pthread_mutex_unlock( &v_ );
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
class scoped_lock
|
||||
{
|
||||
private:
|
||||
|
||||
spinlock & sp_;
|
||||
|
||||
scoped_lock( scoped_lock const & );
|
||||
scoped_lock & operator=( scoped_lock const & );
|
||||
|
||||
public:
|
||||
|
||||
explicit scoped_lock( spinlock & sp ): sp_( sp )
|
||||
{
|
||||
sp.lock();
|
||||
}
|
||||
|
||||
~scoped_lock()
|
||||
{
|
||||
sp_.unlock();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace boost
|
||||
|
||||
#define BOOST_DETAIL_SPINLOCK_INIT { PTHREAD_MUTEX_INITIALIZER }
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_SPINLOCK_PT_HPP_INCLUDED
|
87
include/boost/detail/spinlock_sync.hpp
Normal file
87
include/boost/detail/spinlock_sync.hpp
Normal file
@@ -0,0 +1,87 @@
|
||||
#ifndef BOOST_DETAIL_SPINLOCK_SYNC_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_SPINLOCK_SYNC_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// Copyright (c) 2008 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <boost/detail/yield_k.hpp>
|
||||
|
||||
#if defined( __ia64__ ) && defined( __INTEL_COMPILER )
|
||||
# include <ia64intrin.h>
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class spinlock
|
||||
{
|
||||
public:
|
||||
|
||||
int v_;
|
||||
|
||||
public:
|
||||
|
||||
bool try_lock()
|
||||
{
|
||||
int r = __sync_lock_test_and_set( &v_, 1 );
|
||||
return r == 0;
|
||||
}
|
||||
|
||||
void lock()
|
||||
{
|
||||
for( unsigned k = 0; !try_lock(); ++k )
|
||||
{
|
||||
boost::detail::yield( k );
|
||||
}
|
||||
}
|
||||
|
||||
void unlock()
|
||||
{
|
||||
__sync_lock_release( &v_ );
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
class scoped_lock
|
||||
{
|
||||
private:
|
||||
|
||||
spinlock & sp_;
|
||||
|
||||
scoped_lock( scoped_lock const & );
|
||||
scoped_lock & operator=( scoped_lock const & );
|
||||
|
||||
public:
|
||||
|
||||
explicit scoped_lock( spinlock & sp ): sp_( sp )
|
||||
{
|
||||
sp.lock();
|
||||
}
|
||||
|
||||
~scoped_lock()
|
||||
{
|
||||
sp_.unlock();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace boost
|
||||
|
||||
#define BOOST_DETAIL_SPINLOCK_INIT {0}
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_SPINLOCK_SYNC_HPP_INCLUDED
|
113
include/boost/detail/spinlock_w32.hpp
Normal file
113
include/boost/detail/spinlock_w32.hpp
Normal file
@@ -0,0 +1,113 @@
|
||||
#ifndef BOOST_DETAIL_SPINLOCK_W32_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_SPINLOCK_W32_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// Copyright (c) 2008 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <boost/detail/interlocked.hpp>
|
||||
#include <boost/detail/yield_k.hpp>
|
||||
|
||||
// BOOST_COMPILER_FENCE
|
||||
|
||||
#if defined(__INTEL_COMPILER)
|
||||
|
||||
#define BOOST_COMPILER_FENCE __memory_barrier();
|
||||
|
||||
#elif defined( _MSC_VER ) && _MSC_VER >= 1310
|
||||
|
||||
extern "C" void _ReadWriteBarrier();
|
||||
#pragma intrinsic( _ReadWriteBarrier )
|
||||
|
||||
#define BOOST_COMPILER_FENCE _ReadWriteBarrier();
|
||||
|
||||
#elif defined(__GNUC__)
|
||||
|
||||
#define BOOST_COMPILER_FENCE __asm__ __volatile__( "" : : : "memory" );
|
||||
|
||||
#else
|
||||
|
||||
#define BOOST_COMPILER_FENCE
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class spinlock
|
||||
{
|
||||
public:
|
||||
|
||||
long v_;
|
||||
|
||||
public:
|
||||
|
||||
bool try_lock()
|
||||
{
|
||||
long r = BOOST_INTERLOCKED_EXCHANGE( &v_, 1 );
|
||||
|
||||
BOOST_COMPILER_FENCE
|
||||
|
||||
return r == 0;
|
||||
}
|
||||
|
||||
void lock()
|
||||
{
|
||||
for( unsigned k = 0; !try_lock(); ++k )
|
||||
{
|
||||
boost::detail::yield( k );
|
||||
}
|
||||
}
|
||||
|
||||
void unlock()
|
||||
{
|
||||
BOOST_COMPILER_FENCE
|
||||
*const_cast< long volatile* >( &v_ ) = 0;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
class scoped_lock
|
||||
{
|
||||
private:
|
||||
|
||||
spinlock & sp_;
|
||||
|
||||
scoped_lock( scoped_lock const & );
|
||||
scoped_lock & operator=( scoped_lock const & );
|
||||
|
||||
public:
|
||||
|
||||
explicit scoped_lock( spinlock & sp ): sp_( sp )
|
||||
{
|
||||
sp.lock();
|
||||
}
|
||||
|
||||
~scoped_lock()
|
||||
{
|
||||
sp_.unlock();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace boost
|
||||
|
||||
#define BOOST_DETAIL_SPINLOCK_INIT {0}
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_SPINLOCK_W32_HPP_INCLUDED
|
149
include/boost/detail/yield_k.hpp
Normal file
149
include/boost/detail/yield_k.hpp
Normal file
@@ -0,0 +1,149 @@
|
||||
#ifndef BOOST_DETAIL_YIELD_K_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_YIELD_K_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// boost/detail/yield_k.hpp
|
||||
//
|
||||
// Copyright (c) 2008 Peter Dimov
|
||||
//
|
||||
// void yield( unsigned k );
|
||||
//
|
||||
// Typical use:
|
||||
//
|
||||
// for( unsigned k = 0; !try_lock(); ++k ) yield( k );
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
// BOOST_SMT_PAUSE
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1310 && ( defined(_M_IX86) || defined(_M_X64) )
|
||||
|
||||
extern "C" void _mm_pause();
|
||||
#pragma intrinsic( _mm_pause )
|
||||
|
||||
#define BOOST_SMT_PAUSE _mm_pause();
|
||||
|
||||
#elif defined(__GNUC__) && ( defined(__i386__) || defined(__x86_64__) )
|
||||
|
||||
#define BOOST_SMT_PAUSE __asm__ __volatile__( "rep; nop" : : : "memory" );
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
|
||||
#if defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined( __CYGWIN__ )
|
||||
|
||||
#if defined( BOOST_USE_WINDOWS_H )
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
#if !defined( BOOST_USE_WINDOWS_H )
|
||||
extern "C" void __stdcall Sleep( unsigned ms );
|
||||
#endif
|
||||
|
||||
inline void yield( unsigned k )
|
||||
{
|
||||
if( k < 4 )
|
||||
{
|
||||
}
|
||||
#if defined( BOOST_SMT_PAUSE )
|
||||
else if( k < 16 )
|
||||
{
|
||||
BOOST_SMT_PAUSE
|
||||
}
|
||||
#endif
|
||||
else if( k < 32 )
|
||||
{
|
||||
Sleep( 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
Sleep( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#elif defined( BOOST_HAS_PTHREADS )
|
||||
|
||||
#include <sched.h>
|
||||
#include <time.h>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
inline void yield( unsigned k )
|
||||
{
|
||||
if( k < 4 )
|
||||
{
|
||||
}
|
||||
#if defined( BOOST_SMT_PAUSE )
|
||||
else if( k < 16 )
|
||||
{
|
||||
BOOST_SMT_PAUSE
|
||||
}
|
||||
#endif
|
||||
else if( k < 32 || k & 1 )
|
||||
{
|
||||
sched_yield();
|
||||
}
|
||||
else
|
||||
{
|
||||
// g++ -Wextra warns on {} or {0}
|
||||
struct timespec rqtp = { 0, 0 };
|
||||
|
||||
// POSIX says that timespec has tv_sec and tv_nsec
|
||||
// But it doesn't guarantee order or placement
|
||||
|
||||
rqtp.tv_sec = 0;
|
||||
rqtp.tv_nsec = 1000;
|
||||
|
||||
nanosleep( &rqtp, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#else
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
inline void yield( unsigned )
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_YIELD_K_HPP_INCLUDED
|
@@ -22,9 +22,17 @@
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/detail/sp_convertible.hpp>
|
||||
|
||||
#include <functional> // for std::less
|
||||
#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
|
||||
@@ -66,9 +74,19 @@ public:
|
||||
|
||||
#if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES)
|
||||
|
||||
template<class U> intrusive_ptr(intrusive_ptr<U> const & rhs): p_(rhs.get())
|
||||
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_);
|
||||
if( p_ != 0 ) intrusive_ptr_add_ref( p_ );
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -105,6 +123,16 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
this_type().swap( *this );
|
||||
}
|
||||
|
||||
void reset( T * rhs )
|
||||
{
|
||||
this_type( rhs ).swap( *this );
|
||||
}
|
||||
|
||||
T * get() const
|
||||
{
|
||||
return p_;
|
||||
@@ -112,11 +140,13 @@ public:
|
||||
|
||||
T & operator*() const
|
||||
{
|
||||
BOOST_ASSERT( p_ != 0 );
|
||||
return *p_;
|
||||
}
|
||||
|
||||
T * operator->() const
|
||||
{
|
||||
BOOST_ASSERT( p_ != 0 );
|
||||
return p_;
|
||||
}
|
||||
|
||||
@@ -239,7 +269,9 @@ template<class T, class U> intrusive_ptr<T> dynamic_pointer_cast(intrusive_ptr<U
|
||||
|
||||
// operator<<
|
||||
|
||||
#if defined(__GNUC__) && (__GNUC__ < 3)
|
||||
#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)
|
||||
{
|
||||
@@ -268,6 +300,8 @@ template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::
|
||||
|
||||
#endif // __GNUC__ < 3
|
||||
|
||||
#endif // !defined(BOOST_NO_IOSTREAM)
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
|
433
include/boost/make_shared.hpp
Normal file
433
include/boost/make_shared.hpp
Normal file
@@ -0,0 +1,433 @@
|
||||
#ifndef BOOST_MAKE_SHARED_HPP_INCLUDED
|
||||
#define BOOST_MAKE_SHARED_HPP_INCLUDED
|
||||
|
||||
// make_shared.hpp
|
||||
//
|
||||
// Copyright (c) 2007, 2008 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
// See http://www.boost.org/libs/smart_ptr/make_shared.html
|
||||
// for documentation.
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/type_traits/type_with_alignment.hpp>
|
||||
#include <boost/type_traits/alignment_of.hpp>
|
||||
#include <cstddef>
|
||||
#include <new>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template< std::size_t N, std::size_t A > struct sp_aligned_storage
|
||||
{
|
||||
union type
|
||||
{
|
||||
char data_[ N ];
|
||||
typename boost::type_with_alignment< A >::type align_;
|
||||
};
|
||||
};
|
||||
|
||||
template< class T > class sp_ms_deleter
|
||||
{
|
||||
private:
|
||||
|
||||
typedef typename sp_aligned_storage< sizeof( T ), ::boost::alignment_of< T >::value >::type storage_type;
|
||||
|
||||
bool initialized_;
|
||||
storage_type storage_;
|
||||
|
||||
private:
|
||||
|
||||
void destroy()
|
||||
{
|
||||
if( initialized_ )
|
||||
{
|
||||
reinterpret_cast< T* >( storage_.data_ )->~T();
|
||||
initialized_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
sp_ms_deleter(): initialized_( false )
|
||||
{
|
||||
}
|
||||
|
||||
~sp_ms_deleter()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
void operator()( T * )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
void * address()
|
||||
{
|
||||
return storage_.data_;
|
||||
}
|
||||
|
||||
void set_initialized()
|
||||
{
|
||||
initialized_ = true;
|
||||
}
|
||||
};
|
||||
|
||||
template< class T > T forward( T t )
|
||||
{
|
||||
return t;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// Zero-argument versions
|
||||
//
|
||||
// Used even when variadic templates are available because of the new T() vs new T issue
|
||||
|
||||
template< class T > boost::shared_ptr< T > make_shared()
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
|
||||
|
||||
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
new( pv ) T();
|
||||
pd->set_initialized();
|
||||
|
||||
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
||||
}
|
||||
|
||||
template< class T, class A > boost::shared_ptr< T > allocate_shared( A const & a )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
|
||||
|
||||
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
new( pv ) T();
|
||||
pd->set_initialized();
|
||||
|
||||
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
||||
}
|
||||
|
||||
#if defined( BOOST_HAS_VARIADIC_TMPL ) && defined( BOOST_HAS_RVALUE_REFS )
|
||||
|
||||
// Variadic templates, rvalue reference
|
||||
|
||||
template< class T, class... Args > boost::shared_ptr< T > make_shared( Args && ... args )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
|
||||
|
||||
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
new( pv ) T( detail::forward<Args>( args )... );
|
||||
pd->set_initialized();
|
||||
|
||||
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
||||
}
|
||||
|
||||
template< class T, class A, class... Args > boost::shared_ptr< T > allocate_shared( A const & a, Args && ... args )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
|
||||
|
||||
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
new( pv ) T( detail::forward<Args>( args )... );
|
||||
pd->set_initialized();
|
||||
|
||||
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// C++03 version
|
||||
|
||||
template< class T, class A1 >
|
||||
boost::shared_ptr< T > make_shared( A1 const & a1 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
|
||||
|
||||
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
new( pv ) T( a1 );
|
||||
pd->set_initialized();
|
||||
|
||||
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
||||
}
|
||||
|
||||
template< class T, class A, class A1 >
|
||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
|
||||
|
||||
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
new( pv ) T( a1 );
|
||||
pd->set_initialized();
|
||||
|
||||
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
||||
}
|
||||
|
||||
template< class T, class A1, class A2 >
|
||||
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
|
||||
|
||||
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
new( pv ) T( a1, a2 );
|
||||
pd->set_initialized();
|
||||
|
||||
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
||||
}
|
||||
|
||||
template< class T, class A, class A1, class A2 >
|
||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
|
||||
|
||||
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
new( pv ) T( a1, a2 );
|
||||
pd->set_initialized();
|
||||
|
||||
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
||||
}
|
||||
|
||||
template< class T, class A1, class A2, class A3 >
|
||||
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
|
||||
|
||||
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
new( pv ) T( a1, a2, a3 );
|
||||
pd->set_initialized();
|
||||
|
||||
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
||||
}
|
||||
|
||||
template< class T, class A, class A1, class A2, class A3 >
|
||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
|
||||
|
||||
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
new( pv ) T( a1, a2, a3 );
|
||||
pd->set_initialized();
|
||||
|
||||
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
||||
}
|
||||
|
||||
template< class T, class A1, class A2, class A3, class A4 >
|
||||
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
|
||||
|
||||
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
new( pv ) T( a1, a2, a3, a4 );
|
||||
pd->set_initialized();
|
||||
|
||||
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
||||
}
|
||||
|
||||
template< class T, class A, class A1, class A2, class A3, class A4 >
|
||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
|
||||
|
||||
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
new( pv ) T( a1, a2, a3, a4 );
|
||||
pd->set_initialized();
|
||||
|
||||
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
||||
}
|
||||
|
||||
template< class T, class A1, class A2, class A3, class A4, class A5 >
|
||||
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
|
||||
|
||||
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
new( pv ) T( a1, a2, a3, a4, a5 );
|
||||
pd->set_initialized();
|
||||
|
||||
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
||||
}
|
||||
|
||||
template< class T, class A, class A1, class A2, class A3, class A4, class A5 >
|
||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
|
||||
|
||||
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
new( pv ) T( a1, a2, a3, a4, a5 );
|
||||
pd->set_initialized();
|
||||
|
||||
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
||||
}
|
||||
|
||||
template< class T, class A1, class A2, class A3, class A4, class A5, class A6 >
|
||||
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
|
||||
|
||||
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
new( pv ) T( a1, a2, a3, a4, a5, a6 );
|
||||
pd->set_initialized();
|
||||
|
||||
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
||||
}
|
||||
|
||||
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6 >
|
||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
|
||||
|
||||
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
new( pv ) T( a1, a2, a3, a4, a5, a6 );
|
||||
pd->set_initialized();
|
||||
|
||||
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
||||
}
|
||||
|
||||
template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7 >
|
||||
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
|
||||
|
||||
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
new( pv ) T( a1, a2, a3, a4, a5, a6, a7 );
|
||||
pd->set_initialized();
|
||||
|
||||
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
||||
}
|
||||
|
||||
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7 >
|
||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
|
||||
|
||||
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
new( pv ) T( a1, a2, a3, a4, a5, a6, a7 );
|
||||
pd->set_initialized();
|
||||
|
||||
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
||||
}
|
||||
|
||||
template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 >
|
||||
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
|
||||
|
||||
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8 );
|
||||
pd->set_initialized();
|
||||
|
||||
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
||||
}
|
||||
|
||||
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 >
|
||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
|
||||
|
||||
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8 );
|
||||
pd->set_initialized();
|
||||
|
||||
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
||||
}
|
||||
|
||||
template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 >
|
||||
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8, A9 const & a9 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
|
||||
|
||||
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8, a9 );
|
||||
pd->set_initialized();
|
||||
|
||||
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
||||
}
|
||||
|
||||
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 >
|
||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8, A9 const & a9 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
|
||||
|
||||
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8, a9 );
|
||||
pd->set_initialized();
|
||||
|
||||
return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MAKE_SHARED_HPP_INCLUDED
|
35
include/boost/memory_order.hpp
Normal file
35
include/boost/memory_order.hpp
Normal file
@@ -0,0 +1,35 @@
|
||||
#ifndef BOOST_MEMORY_ORDER_HPP_INCLUDED
|
||||
#define BOOST_MEMORY_ORDER_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// boost/memory_order.hpp
|
||||
//
|
||||
// Defines enum boost::memory_order per the C++0x working draft
|
||||
//
|
||||
// Copyright (c) 2008 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
enum memory_order
|
||||
{
|
||||
memory_order_relaxed = 0,
|
||||
memory_order_acquire = 1,
|
||||
memory_order_release = 2,
|
||||
memory_order_acq_rel = 3, // acquire | release
|
||||
memory_order_seq_cst = 7 // acq_rel | 4
|
||||
};
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MEMORY_ORDER_HPP_INCLUDED
|
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gazta<EFBFBD>aga 2005.
|
||||
// (C) Copyright Ion Gaztanaga 2005.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
@@ -4,7 +4,7 @@
|
||||
//
|
||||
// pointer_to_other.hpp
|
||||
//
|
||||
// (C) Copyright Ion Gazta<EFBFBD>aga 2005.
|
||||
// (C) Copyright Ion Gaztanaga 2005.
|
||||
// Copyright (c) 2005 Peter Dimov.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
|
@@ -46,6 +46,9 @@ private:
|
||||
|
||||
typedef scoped_array<T> this_type;
|
||||
|
||||
void operator==( scoped_array const& ) const;
|
||||
void operator!=( scoped_array const& ) const;
|
||||
|
||||
public:
|
||||
|
||||
typedef T element_type;
|
||||
|
@@ -47,6 +47,9 @@ private:
|
||||
|
||||
typedef scoped_ptr<T> this_type;
|
||||
|
||||
void operator==( scoped_ptr const& ) const;
|
||||
void operator!=( scoped_ptr const& ) const;
|
||||
|
||||
public:
|
||||
|
||||
typedef T element_type;
|
||||
|
@@ -103,7 +103,23 @@ public:
|
||||
return px != 0;
|
||||
}
|
||||
|
||||
#elif defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
|
||||
#elif defined( _MANAGED )
|
||||
|
||||
static void unspecified_bool( this_type*** )
|
||||
{
|
||||
}
|
||||
|
||||
typedef void (*unspecified_bool_type)( this_type*** );
|
||||
|
||||
operator unspecified_bool_type() const // never throws
|
||||
{
|
||||
return px == 0? 0: unspecified_bool;
|
||||
}
|
||||
|
||||
#elif \
|
||||
( defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, < 0x3200) ) || \
|
||||
( defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 304) )
|
||||
|
||||
typedef T * (this_type::*unspecified_bool_type)() const;
|
||||
|
||||
operator unspecified_bool_type() const // never throws
|
||||
|
@@ -5,7 +5,7 @@
|
||||
// shared_ptr.hpp
|
||||
//
|
||||
// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
|
||||
// Copyright (c) 2001-2006 Peter Dimov
|
||||
// Copyright (c) 2001-2008 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -20,18 +20,35 @@
|
||||
#include <boost/detail/shared_ptr_nmt.hpp>
|
||||
#else
|
||||
|
||||
#include <memory> // for std::auto_ptr
|
||||
// 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)
|
||||
@@ -88,6 +105,21 @@ template<class T, class Y> void sp_enable_shared_from_this( shared_count const &
|
||||
if(pe != 0) pe->_internal_weak_this._internal_assign(const_cast<Y*>(px), pn);
|
||||
}
|
||||
|
||||
#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
|
||||
@@ -101,6 +133,8 @@ inline void sp_enable_shared_from_this( shared_count const & /*pn*/, ... )
|
||||
# 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
|
||||
@@ -191,7 +225,31 @@ public:
|
||||
}
|
||||
|
||||
template<class Y>
|
||||
shared_ptr(shared_ptr<Y> const & r): px(r.px), pn(r.pn) // never throws
|
||||
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
|
||||
{
|
||||
}
|
||||
|
||||
@@ -236,7 +294,7 @@ public:
|
||||
#if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
|
||||
|
||||
template<class Ap>
|
||||
explicit shared_ptr( Ap r, typename boost::detail::sp_enable_if_auto_ptr<Ap, int>::type = 0 ): px( r.get() ), pn()
|
||||
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 );
|
||||
@@ -283,6 +341,47 @@ public:
|
||||
|
||||
#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);
|
||||
@@ -304,6 +403,11 @@ public:
|
||||
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);
|
||||
@@ -315,7 +419,7 @@ public:
|
||||
BOOST_ASSERT(px != 0);
|
||||
return px;
|
||||
}
|
||||
|
||||
|
||||
T * get() const // never throws
|
||||
{
|
||||
return px;
|
||||
@@ -323,7 +427,7 @@ public:
|
||||
|
||||
// implicit conversion to "bool"
|
||||
|
||||
#if defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x580)
|
||||
#if ( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, < 0x570) ) || defined(__CINT__)
|
||||
|
||||
operator bool () const
|
||||
{
|
||||
@@ -345,16 +449,17 @@ public:
|
||||
|
||||
#elif \
|
||||
( defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, < 0x3200) ) || \
|
||||
( defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 304) )
|
||||
( defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 304) ) || \
|
||||
( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x590) )
|
||||
|
||||
typedef T * (this_type::*unspecified_bool_type)() const;
|
||||
|
||||
|
||||
operator unspecified_bool_type() const // never throws
|
||||
{
|
||||
return px == 0? 0: &this_type::get;
|
||||
}
|
||||
|
||||
#else
|
||||
#else
|
||||
|
||||
typedef T * this_type::*unspecified_bool_type;
|
||||
|
||||
@@ -393,9 +498,14 @@ public:
|
||||
return pn < rhs.pn;
|
||||
}
|
||||
|
||||
void * _internal_get_deleter(std::type_info const & ti) const
|
||||
void * _internal_get_deleter( detail::sp_typeinfo const & ti ) const
|
||||
{
|
||||
return pn.get_deleter(ti);
|
||||
return pn.get_deleter( ti );
|
||||
}
|
||||
|
||||
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
|
||||
@@ -494,7 +604,9 @@ template<class T> inline T * get_pointer(shared_ptr<T> const & p)
|
||||
|
||||
// operator<<
|
||||
|
||||
#if defined(__GNUC__) && (__GNUC__ < 3)
|
||||
#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)
|
||||
{
|
||||
@@ -513,7 +625,7 @@ using std::basic_ostream;
|
||||
template<class E, class T, class Y> basic_ostream<E, T> & operator<< (basic_ostream<E, T> & os, shared_ptr<Y> const & p)
|
||||
# else
|
||||
template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, shared_ptr<Y> const & p)
|
||||
# endif
|
||||
# endif
|
||||
{
|
||||
os << p.get();
|
||||
return os;
|
||||
@@ -523,7 +635,9 @@ template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::
|
||||
|
||||
#endif // __GNUC__ < 3
|
||||
|
||||
// get_deleter (experimental)
|
||||
#endif // !defined(BOOST_NO_IOSTREAM)
|
||||
|
||||
// get_deleter
|
||||
|
||||
#if ( defined(__GNUC__) && BOOST_WORKAROUND(__GNUC__, < 3) ) || \
|
||||
( defined(__EDG_VERSION__) && BOOST_WORKAROUND(__EDG_VERSION__, <= 238) ) || \
|
||||
@@ -534,7 +648,7 @@ template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::
|
||||
|
||||
template<class D, class T> D * get_deleter(shared_ptr<T> const & p)
|
||||
{
|
||||
void const * q = p._internal_get_deleter(typeid(D));
|
||||
void const * q = p._internal_get_deleter(BOOST_SP_TYPEID(D));
|
||||
return const_cast<D *>(static_cast<D const *>(q));
|
||||
}
|
||||
|
||||
@@ -542,7 +656,86 @@ template<class D, class T> D * get_deleter(shared_ptr<T> const & p)
|
||||
|
||||
template<class D, class T> D * get_deleter(shared_ptr<T> const & p)
|
||||
{
|
||||
return static_cast<D *>(p._internal_get_deleter(typeid(D)));
|
||||
return static_cast<D *>(p._internal_get_deleter(BOOST_SP_TYPEID(D)));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// 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
|
||||
@@ -551,7 +744,7 @@ template<class D, class T> D * get_deleter(shared_ptr<T> const & p)
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif // #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
|
||||
|
||||
|
@@ -61,13 +61,31 @@ public:
|
||||
//
|
||||
|
||||
template<class Y>
|
||||
weak_ptr(weak_ptr<Y> const & r): pn(r.pn) // never throws
|
||||
#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>
|
||||
weak_ptr(shared_ptr<Y> const & r): px(r.px), pn(r.pn) // never throws
|
||||
#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
|
||||
{
|
||||
}
|
||||
|
||||
@@ -93,31 +111,7 @@ public:
|
||||
|
||||
shared_ptr<T> lock() const // never throws
|
||||
{
|
||||
#if defined(BOOST_HAS_THREADS)
|
||||
|
||||
// optimization: avoid throw overhead
|
||||
if(expired())
|
||||
{
|
||||
return shared_ptr<element_type>();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return shared_ptr<element_type>(*this);
|
||||
}
|
||||
catch(bad_weak_ptr const &)
|
||||
{
|
||||
// Q: how can we get here?
|
||||
// A: another thread may have invalidated r after the use_count test above.
|
||||
return shared_ptr<element_type>();
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// optimization: avoid try/catch overhead when single threaded
|
||||
return expired()? shared_ptr<element_type>(): shared_ptr<element_type>(*this);
|
||||
|
||||
#endif
|
||||
return shared_ptr<element_type>( *this, boost::detail::sp_nothrow_tag() );
|
||||
}
|
||||
|
||||
long use_count() const // never throws
|
||||
@@ -179,12 +173,6 @@ template<class T> void swap(weak_ptr<T> & a, weak_ptr<T> & b)
|
||||
a.swap(b);
|
||||
}
|
||||
|
||||
// deprecated, provided for backward compatibility
|
||||
template<class T> shared_ptr<T> make_shared(weak_ptr<T> const & r)
|
||||
{
|
||||
return r.lock();
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
|
@@ -61,7 +61,10 @@
|
||||
|
||||
intrusive_ptr & <A href="#assignment" >operator=</A>(intrusive_ptr const & r);
|
||||
template<class Y> intrusive_ptr & <A href="#assignment" >operator=</A>(intrusive_ptr<Y> const & r);
|
||||
template<class Y> intrusive_ptr & <A href="#assignment" >operator=</A>(T * r);
|
||||
intrusive_ptr & <A href="#assignment" >operator=</A>(T * r);
|
||||
|
||||
void <a href="#reset" >reset</a>();
|
||||
void <a href="#reset" >reset</a>(T * r);
|
||||
|
||||
T & <A href="#indirection" >operator*</A>() const; // never throws
|
||||
T * <A href="#indirection" >operator-></A>() const; // never throws
|
||||
@@ -146,6 +149,15 @@ intrusive_ptr & operator=(T * r);</pre>
|
||||
<P><B>Effects:</B> Equivalent to <code>intrusive_ptr(r).swap(*this)</code>.</P>
|
||||
<P><B>Returns:</B> <code>*this</code>.</P>
|
||||
</BLOCKQUOTE>
|
||||
<H3><a name="reset">reset</a></H3>
|
||||
<pre>void reset();</pre>
|
||||
<BLOCKQUOTE>
|
||||
<P><B>Effects:</B> Equivalent to <code>intrusive_ptr().swap(*this)</code>.</P>
|
||||
</BLOCKQUOTE>
|
||||
<pre>void reset(T * r);</pre>
|
||||
<BLOCKQUOTE>
|
||||
<P><B>Effects:</B> Equivalent to <code>intrusive_ptr(r).swap(*this)</code>.</P>
|
||||
</BLOCKQUOTE>
|
||||
<h3><a name="indirection">indirection</a></h3>
|
||||
<pre>T & operator*() const; // never throws</pre>
|
||||
<blockquote>
|
||||
|
@@ -108,10 +108,9 @@
|
||||
<hr>
|
||||
<p>Revised <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan-->
|
||||
09 January 2003<!--webbot bot="Timestamp" endspan i-checksum="32310"--></p>
|
||||
<p>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
|
||||
Copyright 2002-2005 Peter Dimov. Permission to copy, use, modify, sell and
|
||||
distribute this document is granted provided this copyright notice appears in
|
||||
all copies. This document is provided "as is" without express or implied
|
||||
warranty, and with no claim as to its suitability for any purpose.</p>
|
||||
<p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
|
||||
Copyright 2002-2005 Peter Dimov. Distributed under the Boost Software License, Version
|
||||
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or
|
||||
copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
|
||||
</body>
|
||||
</html>
|
||||
|
@@ -173,10 +173,9 @@ Buckle my shoe</pre>
|
||||
<hr>
|
||||
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B %Y" startspan -->
|
||||
09 January 2003<!--webbot bot="Timestamp" endspan i-checksum="32310" --></p>
|
||||
<p>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
|
||||
Copyright 2002-2005 Peter Dimov. Permission to copy, use, modify, sell and
|
||||
distribute this document is granted provided this copyright notice appears in
|
||||
all copies. This document is provided "as is" without express or implied
|
||||
warranty, and with no claim as to its suitability for any purpose.</p>
|
||||
<p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
|
||||
Copyright 2002-2005 Peter Dimov. Distributed under the Boost Software License, Version
|
||||
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or
|
||||
copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
|
||||
</body>
|
||||
</html>
|
||||
|
@@ -47,7 +47,7 @@
|
||||
void <a href="#reset">reset</a>(T * p = 0);
|
||||
template<class D> void <a href="#reset">reset</a>(T * p, D d);
|
||||
|
||||
T & <a href="#indexing">operator[]</a>(std::ptrdiff_t i) const() const; // never throws
|
||||
T & <a href="#indexing">operator[]</a>(std::ptrdiff_t i) const; // never throws
|
||||
T * <a href="#get">get</a>() const; // never throws
|
||||
|
||||
bool <a href="#unique">unique</a>() const; // never throws
|
||||
@@ -177,10 +177,9 @@ template<class T>
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan -->
|
||||
09 January 2003<!--webbot bot="Timestamp" endspan i-checksum="32310" --></p>
|
||||
<p>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
|
||||
Copyright 2002-2005 Peter Dimov. Permission to copy, use, modify, sell and
|
||||
distribute this document is granted provided this copyright notice appears in
|
||||
all copies. This document is provided "as is" without express or implied
|
||||
warranty, and with no claim as to its suitability for any purpose.</p>
|
||||
<p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
|
||||
Copyright 2002-2005 Peter Dimov. Distributed under the Boost Software License, Version
|
||||
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or
|
||||
copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
|
||||
</body>
|
||||
</html>
|
||||
|
@@ -111,6 +111,7 @@ void bad()
|
||||
|
||||
<A href="#constructors" >shared_ptr</A>(shared_ptr const & r); // never throws
|
||||
template<class Y> <A href="#constructors" >shared_ptr</A>(shared_ptr<Y> const & r); // never throws
|
||||
template<class Y> <A href="#constructors" >shared_ptr</A>(shared_ptr<Y> const & r, T * p); // never throws
|
||||
template<class Y> explicit <A href="#constructors" >shared_ptr</A>(<A href="weak_ptr.htm" >weak_ptr</A><Y> const & r);
|
||||
template<class Y> explicit <A href="#constructors" >shared_ptr</A>(std::auto_ptr<Y> & r);
|
||||
|
||||
@@ -122,6 +123,7 @@ void bad()
|
||||
template<class Y> void <A href="#reset" >reset</A>(Y * p);
|
||||
template<class Y, class D> void <A href="#reset" >reset</A>(Y * p, D d);
|
||||
template<class Y, class D, class A> void <A href="#reset" >reset</A>(Y * p, D d, A a);
|
||||
template<class Y> void <A href="#reset" >reset</A>(shared_ptr<Y> const & r, T * p); // never throws
|
||||
|
||||
T & <A href="#indirection" >operator*</A>() const; // never throws
|
||||
T * <A href="#indirection" >operator-></A>() const; // never throws
|
||||
@@ -253,6 +255,13 @@ template<class Y> shared_ptr(shared_ptr<Y> const & r); // never
|
||||
r.use_count()</code>.</p>
|
||||
<p><b>Throws:</b> nothing.</p>
|
||||
</blockquote>
|
||||
<pre>template<class Y> shared_ptr(shared_ptr<Y> const & r, T * p); // never throws</pre>
|
||||
<blockquote>
|
||||
<p><b>Effects:</b> constructs a <b>shared_ptr</b> that <EM>shares ownership</EM> with
|
||||
<b>r</b> and stores <b>p</b>.</p>
|
||||
<p><b>Postconditions:</b> <code>get() == p && use_count() == r.use_count()</code>.</p>
|
||||
<p><b>Throws:</b> nothing.</p>
|
||||
</blockquote>
|
||||
<pre>template<class Y> explicit shared_ptr(<A href="weak_ptr.htm" >weak_ptr</A><Y> const & r);</pre>
|
||||
<blockquote>
|
||||
<p><b>Effects:</b> Constructs a <b>shared_ptr</b> that <EM>shares ownership</EM> with
|
||||
@@ -328,6 +337,10 @@ q = p;
|
||||
<BLOCKQUOTE>
|
||||
<P><B>Effects:</B> Equivalent to <code>shared_ptr(p, d, a).swap(*this)</code>.</P>
|
||||
</BLOCKQUOTE>
|
||||
<pre>template<class Y> void reset(shared_ptr<Y> const & r, T * p); // never throws</pre>
|
||||
<BLOCKQUOTE>
|
||||
<P><B>Effects:</B> Equivalent to <code>shared_ptr(r, p).swap(*this)</code>.</P>
|
||||
</BLOCKQUOTE>
|
||||
<h3><a name="indirection">indirection</a></h3>
|
||||
<pre>T & operator*() const; // never throws</pre>
|
||||
<blockquote>
|
||||
@@ -360,8 +373,8 @@ q = p;
|
||||
<pre>long use_count() const; // never throws</pre>
|
||||
<blockquote>
|
||||
<p><b>Returns:</b> the number of <b>shared_ptr</b> objects, <STRONG>*this</STRONG> included,
|
||||
that <i>share ownership</i> with <b>*this</b>, or an unspecified nonnegative
|
||||
value when <STRONG>*this</STRONG> is <EM>empty</EM>.</p>
|
||||
that <i>share ownership</i> with <b>*this</b>, or 0 when <STRONG>*this</STRONG>
|
||||
is <EM>empty</EM>.</p>
|
||||
<p><b>Throws:</b> nothing.</p>
|
||||
<P><B>Notes:</B> <code>use_count()</code> is not necessarily efficient. Use only
|
||||
for debugging and testing purposes, not for production code.</P>
|
||||
@@ -509,6 +522,7 @@ q = p;
|
||||
<P><B>Returns:</B> If <STRONG>*this</STRONG> <EM>owns</EM> a deleter <STRONG>d</STRONG>
|
||||
of type (cv-unqualified) <STRONG>D</STRONG>, returns <code>&d</code>;
|
||||
otherwise returns 0.</P>
|
||||
<P><B>Throws:</B> nothing.</P>
|
||||
</BLOCKQUOTE>
|
||||
<h2><a name="example">Example</a></h2>
|
||||
<p>See <A href="example/shared_ptr_example.cpp">shared_ptr_example.cpp</A> for a
|
||||
@@ -696,9 +710,8 @@ int * p = a.release();
|
||||
<p>
|
||||
$Date$</p>
|
||||
<p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
|
||||
Copyright 2002-2005 Peter Dimov. Permission to copy, use, modify, sell and
|
||||
distribute this document is granted provided this copyright notice appears in
|
||||
all copies. This document is provided "as is" without express or implied
|
||||
warranty, and with no claim as to its suitability for any purpose.</small></p>
|
||||
Copyright 2002-2005 Peter Dimov. Distributed under the Boost Software License,
|
||||
Version 1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A>
|
||||
or copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
|
||||
</body>
|
||||
</html>
|
||||
|
@@ -105,7 +105,7 @@
|
||||
and that is thrown only by functions which are explicitly documented as
|
||||
possibly throwing <b>std::bad_alloc</b>.</p>
|
||||
<h2><a name="Exception-specifications">Exception-specifications</a></h2>
|
||||
<p>Exception-specifications are not used; see <a href="../../more/lib_guide.htm#Exception-specification">
|
||||
<p>Exception-specifications are not used; see <a href="http://www.boost.org/more/lib_guide.htm#Exception-specification">
|
||||
exception-specification rationale</a>.</p>
|
||||
<p>All the smart pointer templates contain member functions which can never throw
|
||||
exceptions, because they neither throw exceptions themselves nor call other
|
||||
@@ -177,10 +177,9 @@
|
||||
and an extensive bibliography.</p>
|
||||
<hr>
|
||||
<p>$Date$</p>
|
||||
<p>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
|
||||
Permission to copy, use, modify, sell and distribute this document is granted
|
||||
provided this copyright notice appears in all copies. This document is provided
|
||||
"as is" without express or implied warranty, and with no claim as to its
|
||||
suitability for any purpose.</p>
|
||||
<p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
|
||||
Distributed under the Boost Software License, Version 1.0. See accompanying
|
||||
file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or copy at
|
||||
<A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
|
||||
</body>
|
||||
</html>
|
||||
|
@@ -21,10 +21,10 @@
|
||||
mailing list and the tests which this page describes were performed to provide
|
||||
a guide for current and future investigations into smart pointer implementation
|
||||
strategies.</p>
|
||||
<p>Thanks are due to <a href="../../people/dave_abrahams.htm">Dave Abrahams</a>,
|
||||
<p>Thanks are due to <a href="http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a>,
|
||||
Gavin Collings,
|
||||
<a href="../../people/greg_colvin.htm">Greg Colvin</a> and
|
||||
<a href="../../people/beman_dawes.html">Beman Dawes</a>
|
||||
<a href="http://www.boost.org/people/greg_colvin.htm">Greg Colvin</a> and
|
||||
<a href="http://www.boost.org/people/beman_dawes.html">Beman Dawes</a>
|
||||
for test code and trial implementations, the final version of which can be found
|
||||
in .zip format <a href="smarttest.zip">here</a>.</p>
|
||||
<h2>Description</h2>
|
||||
|
@@ -104,6 +104,8 @@ static void find_unreachable_objects_impl(map_type const & m, map2_type & m2)
|
||||
|
||||
BOOST_ASSERT(p->use_count() != 0); // there should be no inactive counts in the map
|
||||
|
||||
m2[ i->first ];
|
||||
|
||||
scan_and_count(i->second.first, i->second.second, m, m2);
|
||||
}
|
||||
|
||||
@@ -121,7 +123,7 @@ static void find_unreachable_objects_impl(map_type const & m, map2_type & m2)
|
||||
if(p->use_count() != i->second) open.push_back(p);
|
||||
}
|
||||
|
||||
std::cout << "... " << m2.size() << " objects in open.\n";
|
||||
std::cout << "... " << open.size() << " objects in open.\n";
|
||||
|
||||
for(open_type::iterator j = open.begin(); j != open.end(); ++j)
|
||||
{
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# Boost.SmartPtr Library test Jamfile
|
||||
#
|
||||
# Copyright (c) 2003-2005 Peter Dimov
|
||||
# Copyright (c) 2003-2007 Peter Dimov
|
||||
# Copyright (c) 2003 Dave Abrahams
|
||||
#
|
||||
# Distributed under the Boost Software License, Version 1.0. (See
|
||||
@@ -23,9 +23,30 @@ import testing ;
|
||||
[ run lw_mutex_test.cpp ]
|
||||
[ compile-fail shared_ptr_assign_fail.cpp ]
|
||||
[ compile-fail shared_ptr_delete_fail.cpp ]
|
||||
[ compile-fail shared_ptr_compare_fail.cpp ]
|
||||
[ run shared_ptr_alloc2_test.cpp ]
|
||||
[ run pointer_cast_test.cpp ]
|
||||
[ compile pointer_to_other_test.cpp ]
|
||||
[ run auto_ptr_rv_test.cpp ]
|
||||
[ run shared_ptr_alias_test.cpp ]
|
||||
[ run shared_ptr_rv_test.cpp ]
|
||||
[ run shared_ptr_move_test.cpp ]
|
||||
[ compile-fail shared_ptr_pv_fail.cpp ]
|
||||
[ run sp_unary_addr_test.cpp ]
|
||||
[ compile-fail scoped_ptr_eq_fail.cpp ]
|
||||
[ compile-fail scoped_array_eq_fail.cpp ]
|
||||
[ run esft_regtest.cpp ]
|
||||
[ run yield_k_test.cpp ]
|
||||
[ run yield_k_test.cpp : : : <threading>multi : yield_k_test.mt ]
|
||||
[ run spinlock_test.cpp ]
|
||||
[ run spinlock_try_test.cpp ]
|
||||
[ run spinlock_try_test.cpp : : : <threading>multi : spinlock_try_test.mt ]
|
||||
[ run spinlock_pool_test.cpp ]
|
||||
[ run make_shared_test.cpp ]
|
||||
[ run sp_convertible_test.cpp ]
|
||||
[ run wp_convertible_test.cpp ]
|
||||
[ run ip_convertible_test.cpp ]
|
||||
[ run allocate_shared_test.cpp ]
|
||||
[ run sp_atomic_test.cpp ]
|
||||
;
|
||||
}
|
||||
|
189
test/allocate_shared_test.cpp
Normal file
189
test/allocate_shared_test.cpp
Normal file
@@ -0,0 +1,189 @@
|
||||
// allocate_shared_test.cpp
|
||||
//
|
||||
// Copyright (c) 2007, 2008 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/weak_ptr.hpp>
|
||||
|
||||
class X
|
||||
{
|
||||
private:
|
||||
|
||||
X( X const & );
|
||||
X & operator=( X const & );
|
||||
|
||||
public:
|
||||
|
||||
static int instances;
|
||||
|
||||
int v;
|
||||
|
||||
explicit X( int a1 = 0, int a2 = 0, int a3 = 0, int a4 = 0, int a5 = 0, int a6 = 0, int a7 = 0, int a8 = 0, int a9 = 0 ): v( a1+a2+a3+a4+a5+a6+a7+a8+a9 )
|
||||
{
|
||||
++instances;
|
||||
}
|
||||
|
||||
~X()
|
||||
{
|
||||
--instances;
|
||||
}
|
||||
};
|
||||
|
||||
int X::instances = 0;
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
boost::shared_ptr< int > pi = boost::allocate_shared< int >( std::allocator<int>() );
|
||||
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( *pi == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::shared_ptr< int > pi = boost::allocate_shared< int >( std::allocator<int>(), 5 );
|
||||
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( *pi == 5 );
|
||||
}
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > pi = boost::allocate_shared< X >( std::allocator<void>() );
|
||||
boost::weak_ptr<X> wp( pi );
|
||||
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( pi->v == 0 );
|
||||
|
||||
pi.reset();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > pi = boost::allocate_shared< X >( std::allocator<void>(), 1 );
|
||||
boost::weak_ptr<X> wp( pi );
|
||||
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( pi->v == 1 );
|
||||
|
||||
pi.reset();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > pi = boost::allocate_shared< X >( std::allocator<void>(), 1, 2 );
|
||||
boost::weak_ptr<X> wp( pi );
|
||||
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( pi->v == 1+2 );
|
||||
|
||||
pi.reset();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > pi = boost::allocate_shared< X >( std::allocator<void>(), 1, 2, 3 );
|
||||
boost::weak_ptr<X> wp( pi );
|
||||
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( pi->v == 1+2+3 );
|
||||
|
||||
pi.reset();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > pi = boost::allocate_shared< X >( std::allocator<void>(), 1, 2, 3, 4 );
|
||||
boost::weak_ptr<X> wp( pi );
|
||||
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( pi->v == 1+2+3+4 );
|
||||
|
||||
pi.reset();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > pi = boost::allocate_shared< X >( std::allocator<void>(), 1, 2, 3, 4, 5 );
|
||||
boost::weak_ptr<X> wp( pi );
|
||||
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( pi->v == 1+2+3+4+5 );
|
||||
|
||||
pi.reset();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > pi = boost::allocate_shared< X >( std::allocator<void>(), 1, 2, 3, 4, 5, 6 );
|
||||
boost::weak_ptr<X> wp( pi );
|
||||
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( pi->v == 1+2+3+4+5+6 );
|
||||
|
||||
pi.reset();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > pi = boost::allocate_shared< X >( std::allocator<void>(), 1, 2, 3, 4, 5, 6, 7 );
|
||||
boost::weak_ptr<X> wp( pi );
|
||||
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( pi->v == 1+2+3+4+5+6+7 );
|
||||
|
||||
pi.reset();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > pi = boost::allocate_shared< X >( std::allocator<void>(), 1, 2, 3, 4, 5, 6, 7, 8 );
|
||||
boost::weak_ptr<X> wp( pi );
|
||||
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( pi->v == 1+2+3+4+5+6+7+8 );
|
||||
|
||||
pi.reset();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > pi = boost::allocate_shared< X >( std::allocator<void>(), 1, 2, 3, 4, 5, 6, 7, 8, 9 );
|
||||
boost::weak_ptr<X> wp( pi );
|
||||
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( pi->v == 1+2+3+4+5+6+7+8+9 );
|
||||
|
||||
pi.reset();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
221
test/esft_regtest.cpp
Normal file
221
test/esft_regtest.cpp
Normal file
@@ -0,0 +1,221 @@
|
||||
//
|
||||
// esft_regtest.cpp
|
||||
//
|
||||
// A regression test for enable_shared_from_this
|
||||
//
|
||||
// Copyright (c) 2008 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/weak_ptr.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
class X: public boost::enable_shared_from_this< X >
|
||||
{
|
||||
private:
|
||||
|
||||
int destroyed_;
|
||||
int deleted_;
|
||||
int expected_;
|
||||
|
||||
private:
|
||||
|
||||
X( X const& );
|
||||
X& operator=( X const& );
|
||||
|
||||
public:
|
||||
|
||||
static int instances;
|
||||
|
||||
public:
|
||||
|
||||
explicit X( int expected ): destroyed_( 0 ), deleted_( 0 ), expected_( expected )
|
||||
{
|
||||
++instances;
|
||||
}
|
||||
|
||||
~X()
|
||||
{
|
||||
BOOST_TEST( deleted_ == expected_ );
|
||||
BOOST_TEST( destroyed_ == 0 );
|
||||
++destroyed_;
|
||||
--instances;
|
||||
}
|
||||
|
||||
typedef void (*deleter_type)( X* );
|
||||
|
||||
static void deleter( X * px )
|
||||
{
|
||||
++px->deleted_;
|
||||
}
|
||||
|
||||
static void deleter2( X * px )
|
||||
{
|
||||
++px->deleted_;
|
||||
delete px;
|
||||
}
|
||||
};
|
||||
|
||||
int X::instances = 0;
|
||||
|
||||
void test()
|
||||
{
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
{
|
||||
X x( 0 );
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
}
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
{
|
||||
std::auto_ptr<X> px( new X( 0 ) );
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
}
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
{
|
||||
boost::shared_ptr<X> px( new X( 0 ) );
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
|
||||
boost::weak_ptr<X> wp( px );
|
||||
BOOST_TEST( !wp.expired() );
|
||||
|
||||
px.reset();
|
||||
|
||||
BOOST_TEST( wp.expired() );
|
||||
}
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
{
|
||||
X x( 1 );
|
||||
boost::shared_ptr<X> px( &x, X::deleter );
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
|
||||
X::deleter_type * pd = boost::get_deleter<X::deleter_type>( px );
|
||||
BOOST_TEST( pd != 0 && *pd == X::deleter );
|
||||
|
||||
boost::weak_ptr<X> wp( px );
|
||||
BOOST_TEST( !wp.expired() );
|
||||
|
||||
px.reset();
|
||||
|
||||
BOOST_TEST( wp.expired() );
|
||||
}
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
{
|
||||
boost::shared_ptr<X> px( new X( 1 ), X::deleter2 );
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
|
||||
X::deleter_type * pd = boost::get_deleter<X::deleter_type>( px );
|
||||
BOOST_TEST( pd != 0 && *pd == X::deleter2 );
|
||||
|
||||
boost::weak_ptr<X> wp( px );
|
||||
BOOST_TEST( !wp.expired() );
|
||||
|
||||
px.reset();
|
||||
|
||||
BOOST_TEST( wp.expired() );
|
||||
}
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
struct V: public boost::enable_shared_from_this<V>
|
||||
{
|
||||
virtual ~V() {}
|
||||
std::string m_;
|
||||
};
|
||||
|
||||
struct V2
|
||||
{
|
||||
virtual ~V2() {}
|
||||
std::string m2_;
|
||||
};
|
||||
|
||||
struct W: V2, V
|
||||
{
|
||||
};
|
||||
|
||||
void test2()
|
||||
{
|
||||
boost::shared_ptr<W> p( new W );
|
||||
}
|
||||
|
||||
void test3()
|
||||
{
|
||||
V * p = new W;
|
||||
boost::shared_ptr<void> pv( p );
|
||||
BOOST_TEST( pv.get() == p );
|
||||
BOOST_TEST( pv.use_count() == 1 );
|
||||
}
|
||||
|
||||
struct null_deleter
|
||||
{
|
||||
void operator()( void const* ) const {}
|
||||
};
|
||||
|
||||
void test4()
|
||||
{
|
||||
boost::shared_ptr<V> pv( new V );
|
||||
boost::shared_ptr<V> pv2( pv.get(), null_deleter() );
|
||||
BOOST_TEST( pv2.get() == pv.get() );
|
||||
BOOST_TEST( pv2.use_count() == 1 );
|
||||
}
|
||||
|
||||
void test5()
|
||||
{
|
||||
V v;
|
||||
|
||||
boost::shared_ptr<V> p1( &v, null_deleter() );
|
||||
BOOST_TEST( p1.get() == &v );
|
||||
BOOST_TEST( p1.use_count() == 1 );
|
||||
|
||||
try
|
||||
{
|
||||
p1->shared_from_this();
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
BOOST_ERROR( "p1->shared_from_this() failed" );
|
||||
}
|
||||
|
||||
p1.reset();
|
||||
|
||||
boost::shared_ptr<V> p2( &v, null_deleter() );
|
||||
BOOST_TEST( p2.get() == &v );
|
||||
BOOST_TEST( p2.use_count() == 1 );
|
||||
|
||||
try
|
||||
{
|
||||
p2->shared_from_this();
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
BOOST_ERROR( "p2->shared_from_this() failed" );
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test();
|
||||
test2();
|
||||
test3();
|
||||
test4();
|
||||
test5();
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
54
test/ip_convertible_test.cpp
Normal file
54
test/ip_convertible_test.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
#include <boost/config.hpp>
|
||||
|
||||
// wp_convertible_test.cpp
|
||||
//
|
||||
// Copyright (c) 2008 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/intrusive_ptr.hpp>
|
||||
|
||||
//
|
||||
|
||||
struct W
|
||||
{
|
||||
};
|
||||
|
||||
void intrusive_ptr_add_ref( W* )
|
||||
{
|
||||
}
|
||||
|
||||
void intrusive_ptr_release( W* )
|
||||
{
|
||||
}
|
||||
|
||||
struct X: public virtual W
|
||||
{
|
||||
};
|
||||
|
||||
struct Y: public virtual W
|
||||
{
|
||||
};
|
||||
|
||||
struct Z: public X
|
||||
{
|
||||
};
|
||||
|
||||
int f( boost::intrusive_ptr<X> )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int f( boost::intrusive_ptr<Y> )
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
BOOST_TEST( 1 == f( boost::intrusive_ptr<Z>() ) );
|
||||
return boost::report_errors();
|
||||
}
|
189
test/make_shared_test.cpp
Normal file
189
test/make_shared_test.cpp
Normal file
@@ -0,0 +1,189 @@
|
||||
// make_shared_test.cpp
|
||||
//
|
||||
// Copyright (c) 2007, 2008 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/weak_ptr.hpp>
|
||||
|
||||
class X
|
||||
{
|
||||
private:
|
||||
|
||||
X( X const & );
|
||||
X & operator=( X const & );
|
||||
|
||||
public:
|
||||
|
||||
static int instances;
|
||||
|
||||
int v;
|
||||
|
||||
explicit X( int a1 = 0, int a2 = 0, int a3 = 0, int a4 = 0, int a5 = 0, int a6 = 0, int a7 = 0, int a8 = 0, int a9 = 0 ): v( a1+a2+a3+a4+a5+a6+a7+a8+a9 )
|
||||
{
|
||||
++instances;
|
||||
}
|
||||
|
||||
~X()
|
||||
{
|
||||
--instances;
|
||||
}
|
||||
};
|
||||
|
||||
int X::instances = 0;
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
boost::shared_ptr< int > pi = boost::make_shared< int >();
|
||||
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( *pi == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::shared_ptr< int > pi = boost::make_shared< int >( 5 );
|
||||
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( *pi == 5 );
|
||||
}
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > pi = boost::make_shared< X >();
|
||||
boost::weak_ptr<X> wp( pi );
|
||||
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( pi->v == 0 );
|
||||
|
||||
pi.reset();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > pi = boost::make_shared< X >( 1 );
|
||||
boost::weak_ptr<X> wp( pi );
|
||||
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( pi->v == 1 );
|
||||
|
||||
pi.reset();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > pi = boost::make_shared< X >( 1, 2 );
|
||||
boost::weak_ptr<X> wp( pi );
|
||||
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( pi->v == 1+2 );
|
||||
|
||||
pi.reset();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > pi = boost::make_shared< X >( 1, 2, 3 );
|
||||
boost::weak_ptr<X> wp( pi );
|
||||
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( pi->v == 1+2+3 );
|
||||
|
||||
pi.reset();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > pi = boost::make_shared< X >( 1, 2, 3, 4 );
|
||||
boost::weak_ptr<X> wp( pi );
|
||||
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( pi->v == 1+2+3+4 );
|
||||
|
||||
pi.reset();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > pi = boost::make_shared< X >( 1, 2, 3, 4, 5 );
|
||||
boost::weak_ptr<X> wp( pi );
|
||||
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( pi->v == 1+2+3+4+5 );
|
||||
|
||||
pi.reset();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > pi = boost::make_shared< X >( 1, 2, 3, 4, 5, 6 );
|
||||
boost::weak_ptr<X> wp( pi );
|
||||
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( pi->v == 1+2+3+4+5+6 );
|
||||
|
||||
pi.reset();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > pi = boost::make_shared< X >( 1, 2, 3, 4, 5, 6, 7 );
|
||||
boost::weak_ptr<X> wp( pi );
|
||||
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( pi->v == 1+2+3+4+5+6+7 );
|
||||
|
||||
pi.reset();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > pi = boost::make_shared< X >( 1, 2, 3, 4, 5, 6, 7, 8 );
|
||||
boost::weak_ptr<X> wp( pi );
|
||||
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( pi->v == 1+2+3+4+5+6+7+8 );
|
||||
|
||||
pi.reset();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > pi = boost::make_shared< X >( 1, 2, 3, 4, 5, 6, 7, 8, 9 );
|
||||
boost::weak_ptr<X> wp( pi );
|
||||
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( pi.get() != 0 );
|
||||
BOOST_TEST( pi->v == 1+2+3+4+5+6+7+8+9 );
|
||||
|
||||
pi.reset();
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
@@ -1,7 +1,7 @@
|
||||
//
|
||||
// pointer_cast_test.cpp - a test for boost/pointer_cast.hpp
|
||||
//
|
||||
// Copyright (c) 2005 Ion Gazta<EFBFBD>aga
|
||||
// Copyright (c) 2005 Ion Gaztanaga
|
||||
// Copyright (c) 2005 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
|
27
test/scoped_array_eq_fail.cpp
Normal file
27
test/scoped_array_eq_fail.cpp
Normal file
@@ -0,0 +1,27 @@
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(disable: 4786) // identifier truncated in debug info
|
||||
#pragma warning(disable: 4710) // function not inlined
|
||||
#pragma warning(disable: 4711) // function selected for automatic inline expansion
|
||||
#pragma warning(disable: 4514) // unreferenced inline removed
|
||||
#endif
|
||||
|
||||
//
|
||||
// scoped_array_eq_fail.cpp - a negative test for "p == q"
|
||||
//
|
||||
// Copyright (c) 2008 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <boost/scoped_array.hpp>
|
||||
|
||||
int main()
|
||||
{
|
||||
boost::scoped_array<int> p, q;
|
||||
p == q; // must fail
|
||||
return 0;
|
||||
}
|
27
test/scoped_ptr_eq_fail.cpp
Normal file
27
test/scoped_ptr_eq_fail.cpp
Normal file
@@ -0,0 +1,27 @@
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(disable: 4786) // identifier truncated in debug info
|
||||
#pragma warning(disable: 4710) // function not inlined
|
||||
#pragma warning(disable: 4711) // function selected for automatic inline expansion
|
||||
#pragma warning(disable: 4514) // unreferenced inline removed
|
||||
#endif
|
||||
|
||||
//
|
||||
// scoped_ptr_eq_fail.cpp - a negative test for "p == q"
|
||||
//
|
||||
// Copyright (c) 2008 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
|
||||
int main()
|
||||
{
|
||||
boost::scoped_ptr<int> p, q;
|
||||
p == q; // must fail
|
||||
return 0;
|
||||
}
|
@@ -133,7 +133,8 @@ void test3()
|
||||
try
|
||||
{
|
||||
boost::shared_ptr<V> r = v2.shared_from_this();
|
||||
BOOST_ERROR("v2.shared_from_this() failed to throw");
|
||||
BOOST_TEST( p < r || r < p );
|
||||
BOOST_TEST( r.get() == &v2 );
|
||||
}
|
||||
catch(boost::bad_weak_ptr const &)
|
||||
{
|
||||
|
146
test/shared_ptr_alias_test.cpp
Normal file
146
test/shared_ptr_alias_test.cpp
Normal file
@@ -0,0 +1,146 @@
|
||||
#include <boost/config.hpp>
|
||||
|
||||
// shared_ptr_alias_test.cpp
|
||||
//
|
||||
// Copyright (c) 2007 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <memory>
|
||||
#include <cstddef>
|
||||
|
||||
//
|
||||
|
||||
class incomplete;
|
||||
|
||||
struct X
|
||||
{
|
||||
int v_;
|
||||
|
||||
explicit X( int v ): v_( v )
|
||||
{
|
||||
}
|
||||
|
||||
~X()
|
||||
{
|
||||
v_ = 0;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
int m = 0;
|
||||
boost::shared_ptr< int > p;
|
||||
boost::shared_ptr< int > p2( p, &m );
|
||||
|
||||
BOOST_TEST( p2.get() == &m );
|
||||
BOOST_TEST( p2? true: false );
|
||||
BOOST_TEST( !!p2 );
|
||||
BOOST_TEST( p2.use_count() == p.use_count() );
|
||||
BOOST_TEST( !( p < p2 ) && !( p2 < p ) );
|
||||
|
||||
p2.reset( p, 0 );
|
||||
|
||||
BOOST_TEST( p2.get() == 0 );
|
||||
BOOST_TEST( p2? false: true );
|
||||
BOOST_TEST( !p2 );
|
||||
BOOST_TEST( p2.use_count() == p.use_count() );
|
||||
BOOST_TEST( !( p < p2 ) && !( p2 < p ) );
|
||||
}
|
||||
|
||||
{
|
||||
int m = 0;
|
||||
boost::shared_ptr< int > p( new int );
|
||||
boost::shared_ptr< int const > p2( p, &m );
|
||||
|
||||
BOOST_TEST( p2.get() == &m );
|
||||
BOOST_TEST( p2? true: false );
|
||||
BOOST_TEST( !!p2 );
|
||||
BOOST_TEST( p2.use_count() == p.use_count() );
|
||||
BOOST_TEST( !( p < p2 ) && !( p2 < p ) );
|
||||
|
||||
boost::shared_ptr< int volatile > p3;
|
||||
p2.reset( p3, 0 );
|
||||
|
||||
BOOST_TEST( p2.get() == 0 );
|
||||
BOOST_TEST( p2? false: true );
|
||||
BOOST_TEST( !p2 );
|
||||
BOOST_TEST( p2.use_count() == p3.use_count() );
|
||||
BOOST_TEST( !( p3 < p2 ) && !( p2 < p3 ) );
|
||||
}
|
||||
|
||||
{
|
||||
boost::shared_ptr< int > p( new int );
|
||||
boost::shared_ptr< void const > p2( p, 0 );
|
||||
|
||||
BOOST_TEST( p2.get() == 0 );
|
||||
BOOST_TEST( p2? false: true );
|
||||
BOOST_TEST( !p2 );
|
||||
BOOST_TEST( p2.use_count() == p.use_count() );
|
||||
BOOST_TEST( !( p < p2 ) && !( p2 < p ) );
|
||||
|
||||
int m = 0;
|
||||
boost::shared_ptr< void volatile > p3;
|
||||
|
||||
p2.reset( p3, &m );
|
||||
|
||||
BOOST_TEST( p2.get() == &m );
|
||||
BOOST_TEST( p2? true: false );
|
||||
BOOST_TEST( !!p2 );
|
||||
BOOST_TEST( p2.use_count() == p3.use_count() );
|
||||
BOOST_TEST( !( p3 < p2 ) && !( p2 < p3 ) );
|
||||
}
|
||||
|
||||
{
|
||||
boost::shared_ptr< incomplete > p;
|
||||
boost::shared_ptr< incomplete > p2( p, 0 );
|
||||
|
||||
BOOST_TEST( p2.get() == 0 );
|
||||
BOOST_TEST( p2? false: true );
|
||||
BOOST_TEST( !p2 );
|
||||
BOOST_TEST( p2.use_count() == p.use_count() );
|
||||
BOOST_TEST( !( p < p2 ) && !( p2 < p ) );
|
||||
|
||||
p2.reset( p, 0 );
|
||||
|
||||
BOOST_TEST( p2.get() == 0 );
|
||||
BOOST_TEST( p2? false: true );
|
||||
BOOST_TEST( !p2 );
|
||||
BOOST_TEST( p2.use_count() == p.use_count() );
|
||||
BOOST_TEST( !( p < p2 ) && !( p2 < p ) );
|
||||
}
|
||||
|
||||
{
|
||||
boost::shared_ptr< X > p( new X( 5 ) );
|
||||
boost::shared_ptr< int const > p2( p, &p->v_ );
|
||||
|
||||
BOOST_TEST( p2.get() == &p->v_ );
|
||||
BOOST_TEST( p2? true: false );
|
||||
BOOST_TEST( !!p2 );
|
||||
BOOST_TEST( p2.use_count() == p.use_count() );
|
||||
BOOST_TEST( !( p < p2 ) && !( p2 < p ) );
|
||||
|
||||
p.reset();
|
||||
BOOST_TEST( *p2 == 5 );
|
||||
|
||||
boost::shared_ptr< X const > p3( new X( 8 ) );
|
||||
p2.reset( p3, &p3->v_ );
|
||||
|
||||
BOOST_TEST( p2.get() == &p3->v_ );
|
||||
BOOST_TEST( p2? true: false );
|
||||
BOOST_TEST( !!p2 );
|
||||
BOOST_TEST( p2.use_count() == p3.use_count() );
|
||||
BOOST_TEST( !( p3 < p2 ) && !( p2 < p3 ) );
|
||||
|
||||
p3.reset();
|
||||
BOOST_TEST( *p2 == 8 );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
27
test/shared_ptr_compare_fail.cpp
Normal file
27
test/shared_ptr_compare_fail.cpp
Normal file
@@ -0,0 +1,27 @@
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(disable: 4786) // identifier truncated in debug info
|
||||
#pragma warning(disable: 4710) // function not inlined
|
||||
#pragma warning(disable: 4711) // function selected for automatic inline expansion
|
||||
#pragma warning(disable: 4514) // unreferenced inline removed
|
||||
#endif
|
||||
|
||||
//
|
||||
// shared_ptr_compare_fail.cpp - a negative test for "p > q"
|
||||
//
|
||||
// Copyright 2006 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
int main()
|
||||
{
|
||||
boost::shared_ptr<int> p, q;
|
||||
p > q; // must fail
|
||||
return 0;
|
||||
}
|
95
test/shared_ptr_move_test.cpp
Normal file
95
test/shared_ptr_move_test.cpp
Normal file
@@ -0,0 +1,95 @@
|
||||
//
|
||||
// shared_ptr_move_test.cpp
|
||||
//
|
||||
// Copyright (c) 2007 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
struct X
|
||||
{
|
||||
static long instances;
|
||||
|
||||
X()
|
||||
{
|
||||
++instances;
|
||||
}
|
||||
|
||||
~X()
|
||||
{
|
||||
--instances;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
X( X const & );
|
||||
X & operator=( X const & );
|
||||
};
|
||||
|
||||
long X::instances = 0;
|
||||
|
||||
int main()
|
||||
{
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
{
|
||||
boost::shared_ptr<X> p( new X );
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
|
||||
boost::shared_ptr<X> p2( static_cast< boost::shared_ptr<X> && >( p ) );
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( p.get() == 0 );
|
||||
|
||||
boost::shared_ptr<void> p3( static_cast< boost::shared_ptr<X> && >( p2 ) );
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( p2.get() == 0 );
|
||||
|
||||
p3.reset();
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::shared_ptr<X> p( new X );
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
|
||||
boost::shared_ptr<X> p2;
|
||||
p2 = static_cast< boost::shared_ptr<X> && >( p );
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( p.get() == 0 );
|
||||
|
||||
boost::shared_ptr<void> p3;
|
||||
p3 = static_cast< boost::shared_ptr<X> && >( p2 );
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( p2.get() == 0 );
|
||||
|
||||
p3.reset();
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::shared_ptr<X> p( new X );
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
|
||||
boost::shared_ptr<X> p2( new X );
|
||||
BOOST_TEST( X::instances == 2 );
|
||||
p2 = static_cast< boost::shared_ptr<X> && >( p );
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( p.get() == 0 );
|
||||
|
||||
boost::shared_ptr<void> p3( new X );
|
||||
BOOST_TEST( X::instances == 2 );
|
||||
p3 = static_cast< boost::shared_ptr<X> && >( p2 );
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
BOOST_TEST( p2.get() == 0 );
|
||||
|
||||
p3.reset();
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
@@ -7,167 +7,76 @@
|
||||
#pragma warning(disable: 4514) // unreferenced inline removed
|
||||
#endif
|
||||
|
||||
//
|
||||
// shared_ptr_mt_test.cpp - tests shared_ptr with multiple threads
|
||||
//
|
||||
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
|
||||
// Copyright (c) 2008 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <cstdio>
|
||||
#include <ctime>
|
||||
|
||||
// 'portable' thread framework
|
||||
|
||||
class abstract_thread
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~abstract_thread() {}
|
||||
virtual void run() = 0;
|
||||
};
|
||||
|
||||
#if !defined(BOOST_HAS_PTHREADS) && defined(BOOST_HAS_WINTHREADS)
|
||||
|
||||
char const * title = "Using Windows threads";
|
||||
|
||||
#include <windows.h>
|
||||
#include <process.h>
|
||||
|
||||
typedef HANDLE pthread_t;
|
||||
|
||||
unsigned __stdcall common_thread_routine(void * pv)
|
||||
{
|
||||
abstract_thread * pt = static_cast<abstract_thread *>(pv);
|
||||
pt->run();
|
||||
delete pt;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_create(pthread_t * thread, void const *, unsigned (__stdcall * start_routine) (void*), void* arg)
|
||||
{
|
||||
HANDLE h = (HANDLE)_beginthreadex(0, 0, start_routine, arg, 0, 0);
|
||||
|
||||
if(h != 0)
|
||||
{
|
||||
*thread = h;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1; // return errno;
|
||||
}
|
||||
}
|
||||
|
||||
int pthread_join(pthread_t thread, void ** /*value_ptr*/)
|
||||
{
|
||||
::WaitForSingleObject(thread, INFINITE);
|
||||
::CloseHandle(thread);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
char const * title = "Using POSIX threads";
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
extern "C" void * common_thread_routine(void * pv)
|
||||
{
|
||||
abstract_thread * pt = static_cast<abstract_thread *>(pv);
|
||||
pt->run();
|
||||
delete pt;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
|
||||
template<class F> class thread: public abstract_thread
|
||||
{
|
||||
public:
|
||||
|
||||
explicit thread(F f): f_(f)
|
||||
{
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
f_();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
F f_;
|
||||
};
|
||||
|
||||
template<class F> pthread_t createThread(F f)
|
||||
{
|
||||
std::auto_ptr<abstract_thread> p(new thread<F>(f));
|
||||
|
||||
pthread_t r;
|
||||
|
||||
if(pthread_create(&r, 0, common_thread_routine, p.get()) == 0)
|
||||
{
|
||||
p.release();
|
||||
return r;
|
||||
}
|
||||
|
||||
throw std::runtime_error("createThread failed.");
|
||||
}
|
||||
#include <boost/detail/lightweight_thread.hpp>
|
||||
|
||||
//
|
||||
|
||||
int const n = 1024 * 1024;
|
||||
|
||||
void test(boost::shared_ptr<int> const & pi)
|
||||
void test( boost::shared_ptr<int> const & pi )
|
||||
{
|
||||
std::vector< boost::shared_ptr<int> > v;
|
||||
|
||||
for(int i = 0; i < n; ++i)
|
||||
for( int i = 0; i < n; ++i )
|
||||
{
|
||||
v.push_back(pi);
|
||||
v.push_back( pi );
|
||||
}
|
||||
}
|
||||
|
||||
int const m = 16; // threads
|
||||
|
||||
#if defined( BOOST_HAS_PTHREADS )
|
||||
|
||||
char const * thmodel = "POSIX";
|
||||
|
||||
#else
|
||||
|
||||
char const * thmodel = "Windows";
|
||||
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace std; // printf, clock_t, clock
|
||||
|
||||
printf("%s: %d threads, %d iterations: ", title, m, n);
|
||||
printf( "Using %s threads: %d threads, %d iterations: ", thmodel, m, n );
|
||||
|
||||
boost::shared_ptr<int> pi(new int(42));
|
||||
boost::shared_ptr<int> pi( new int(42) );
|
||||
|
||||
clock_t t = clock();
|
||||
|
||||
pthread_t a[m];
|
||||
pthread_t a[ m ];
|
||||
|
||||
for(int i = 0; i < m; ++i)
|
||||
for( int i = 0; i < m; ++i )
|
||||
{
|
||||
a[i] = createThread( boost::bind(test, pi) );
|
||||
boost::detail::lw_thread_create( a[ i ], boost::bind( test, pi ) );
|
||||
}
|
||||
|
||||
for(int j = 0; j < m; ++j)
|
||||
for( int j = 0; j < m; ++j )
|
||||
{
|
||||
pthread_join(a[j], 0);
|
||||
pthread_join( a[j], 0 );
|
||||
}
|
||||
|
||||
t = clock() - t;
|
||||
|
||||
printf("\n\n%.3f seconds.\n", static_cast<double>(t) / CLOCKS_PER_SEC);
|
||||
printf( "\n\n%.3f seconds.\n", static_cast<double>(t) / CLOCKS_PER_SEC );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
31
test/shared_ptr_pv_fail.cpp
Normal file
31
test/shared_ptr_pv_fail.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(disable: 4786) // identifier truncated in debug info
|
||||
#pragma warning(disable: 4710) // function not inlined
|
||||
#pragma warning(disable: 4711) // function selected for automatic inline expansion
|
||||
#pragma warning(disable: 4514) // unreferenced inline removed
|
||||
#endif
|
||||
|
||||
//
|
||||
// shared_ptr_pv_fail.cpp - a negative test for converting a shared_ptr to void*
|
||||
//
|
||||
// Copyright 2007 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
void f( void* )
|
||||
{
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
boost::shared_ptr<int> p;
|
||||
f( p ); // must fail
|
||||
return 0;
|
||||
}
|
110
test/shared_ptr_rv_test.cpp
Normal file
110
test/shared_ptr_rv_test.cpp
Normal file
@@ -0,0 +1,110 @@
|
||||
//
|
||||
// shared_ptr_rv_test.cpp
|
||||
//
|
||||
// Copyright (c) 2007 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
struct X
|
||||
{
|
||||
static long instances;
|
||||
|
||||
X()
|
||||
{
|
||||
++instances;
|
||||
}
|
||||
|
||||
~X()
|
||||
{
|
||||
--instances;
|
||||
}
|
||||
|
||||
static boost::shared_ptr<X> create()
|
||||
{
|
||||
return boost::shared_ptr<X>( new X );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
X( X const & );
|
||||
X & operator=( X const & );
|
||||
};
|
||||
|
||||
long X::instances = 0;
|
||||
|
||||
int main()
|
||||
{
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
{
|
||||
boost::shared_ptr<X> p( X::create() );
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
|
||||
p = X::create();
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
|
||||
p.reset();
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
p = X::create();
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
}
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
{
|
||||
boost::shared_ptr<X const> p( X::create() );
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
|
||||
p = X::create();
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
|
||||
p.reset();
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
p = X::create();
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
}
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
{
|
||||
boost::shared_ptr<void> p( X::create() );
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
|
||||
p = X::create();
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
|
||||
p.reset();
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
p = X::create();
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
}
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
{
|
||||
boost::shared_ptr<void const> p( X::create() );
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
|
||||
p = X::create();
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
|
||||
p.reset();
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
p = X::create();
|
||||
BOOST_TEST( X::instances == 1 );
|
||||
}
|
||||
|
||||
BOOST_TEST( X::instances == 0 );
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
@@ -62,6 +62,7 @@ void default_constructor()
|
||||
BOOST_TEST(pi? false: true);
|
||||
BOOST_TEST(!pi);
|
||||
BOOST_TEST(pi.get() == 0);
|
||||
BOOST_TEST(pi.use_count() == 0);
|
||||
}
|
||||
|
||||
{
|
||||
@@ -69,6 +70,7 @@ void default_constructor()
|
||||
BOOST_TEST(pv? false: true);
|
||||
BOOST_TEST(!pv);
|
||||
BOOST_TEST(pv.get() == 0);
|
||||
BOOST_TEST(pv.use_count() == 0);
|
||||
}
|
||||
|
||||
{
|
||||
@@ -76,6 +78,7 @@ void default_constructor()
|
||||
BOOST_TEST(px? false: true);
|
||||
BOOST_TEST(!px);
|
||||
BOOST_TEST(px.get() == 0);
|
||||
BOOST_TEST(px.use_count() == 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1565,6 +1568,7 @@ void plain_reset()
|
||||
BOOST_TEST(pi? false: true);
|
||||
BOOST_TEST(!pi);
|
||||
BOOST_TEST(pi.get() == 0);
|
||||
BOOST_TEST(pi.use_count() == 0);
|
||||
}
|
||||
|
||||
{
|
||||
@@ -1573,6 +1577,7 @@ void plain_reset()
|
||||
BOOST_TEST(pi? false: true);
|
||||
BOOST_TEST(!pi);
|
||||
BOOST_TEST(pi.get() == 0);
|
||||
BOOST_TEST(pi.use_count() == 0);
|
||||
}
|
||||
|
||||
{
|
||||
@@ -1581,6 +1586,7 @@ void plain_reset()
|
||||
BOOST_TEST(pi? false: true);
|
||||
BOOST_TEST(!pi);
|
||||
BOOST_TEST(pi.get() == 0);
|
||||
BOOST_TEST(pi.use_count() == 0);
|
||||
}
|
||||
|
||||
{
|
||||
@@ -1589,6 +1595,7 @@ void plain_reset()
|
||||
BOOST_TEST(px? false: true);
|
||||
BOOST_TEST(!px);
|
||||
BOOST_TEST(px.get() == 0);
|
||||
BOOST_TEST(px.use_count() == 0);
|
||||
}
|
||||
|
||||
{
|
||||
@@ -1597,6 +1604,7 @@ void plain_reset()
|
||||
BOOST_TEST(px? false: true);
|
||||
BOOST_TEST(!px);
|
||||
BOOST_TEST(px.get() == 0);
|
||||
BOOST_TEST(px.use_count() == 0);
|
||||
}
|
||||
|
||||
{
|
||||
@@ -1605,6 +1613,7 @@ void plain_reset()
|
||||
BOOST_TEST(px? false: true);
|
||||
BOOST_TEST(!px);
|
||||
BOOST_TEST(px.get() == 0);
|
||||
BOOST_TEST(px.use_count() == 0);
|
||||
}
|
||||
|
||||
{
|
||||
@@ -1615,6 +1624,7 @@ void plain_reset()
|
||||
BOOST_TEST(px? false: true);
|
||||
BOOST_TEST(!px);
|
||||
BOOST_TEST(px.get() == 0);
|
||||
BOOST_TEST(px.use_count() == 0);
|
||||
BOOST_TEST(X::instances == 0);
|
||||
}
|
||||
|
||||
@@ -1624,6 +1634,7 @@ void plain_reset()
|
||||
BOOST_TEST(pv? false: true);
|
||||
BOOST_TEST(!pv);
|
||||
BOOST_TEST(pv.get() == 0);
|
||||
BOOST_TEST(pv.use_count() == 0);
|
||||
}
|
||||
|
||||
{
|
||||
@@ -1634,6 +1645,7 @@ void plain_reset()
|
||||
BOOST_TEST(pv? false: true);
|
||||
BOOST_TEST(!pv);
|
||||
BOOST_TEST(pv.get() == 0);
|
||||
BOOST_TEST(pv.use_count() == 0);
|
||||
BOOST_TEST(X::instances == 0);
|
||||
}
|
||||
}
|
||||
|
@@ -40,9 +40,9 @@
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <string.h>
|
||||
|
||||
class Incomplete;
|
||||
|
||||
@@ -51,12 +51,6 @@ Incomplete * get_ptr( boost::shared_ptr<Incomplete>& incomplete )
|
||||
return incomplete.get();
|
||||
}
|
||||
|
||||
using namespace std;
|
||||
using boost::scoped_ptr;
|
||||
using boost::scoped_array;
|
||||
using boost::shared_ptr;
|
||||
using boost::shared_array;
|
||||
|
||||
template<class T>
|
||||
void ck( const T* v1, T v2 ) { BOOST_TEST( *v1 == v2 ); }
|
||||
|
||||
@@ -72,7 +66,7 @@ class UDT {
|
||||
explicit UDT( long value=0 ) : value_(value) { ++UDT_use_count; }
|
||||
~UDT() {
|
||||
--UDT_use_count;
|
||||
cout << "UDT with value " << value_ << " being destroyed\n";
|
||||
std::cout << "UDT with value " << value_ << " being destroyed\n";
|
||||
}
|
||||
long value() const { return value_; }
|
||||
void value( long v ) { value_ = v;; }
|
||||
@@ -86,16 +80,16 @@ class UDT {
|
||||
|
||||
class Incomplete;
|
||||
|
||||
Incomplete * check_incomplete( scoped_ptr<Incomplete>& incomplete )
|
||||
Incomplete * check_incomplete( boost::scoped_ptr<Incomplete>& incomplete )
|
||||
{
|
||||
return incomplete.get();
|
||||
}
|
||||
|
||||
Incomplete * check_incomplete( shared_ptr<Incomplete>& incomplete,
|
||||
shared_ptr<Incomplete>& i2 )
|
||||
Incomplete * check_incomplete( boost::shared_ptr<Incomplete>& incomplete,
|
||||
boost::shared_ptr<Incomplete>& i2 )
|
||||
{
|
||||
incomplete.swap(i2);
|
||||
cout << incomplete.use_count() << ' ' << incomplete.unique() << '\n';
|
||||
std::cout << incomplete.use_count() << ' ' << incomplete.unique() << '\n';
|
||||
return incomplete.get();
|
||||
}
|
||||
|
||||
@@ -107,7 +101,7 @@ void test()
|
||||
|
||||
// test scoped_ptr with a built-in type
|
||||
long * lp = new long;
|
||||
scoped_ptr<long> sp ( lp );
|
||||
boost::scoped_ptr<long> sp ( lp );
|
||||
BOOST_TEST( sp.get() == lp );
|
||||
BOOST_TEST( lp == sp.get() );
|
||||
BOOST_TEST( &*sp == lp );
|
||||
@@ -122,7 +116,7 @@ void test()
|
||||
BOOST_TEST( sp.get() == 0 );
|
||||
|
||||
// test scoped_ptr with a user defined type
|
||||
scoped_ptr<UDT> udt_sp ( new UDT( 999888777 ) );
|
||||
boost::scoped_ptr<UDT> udt_sp ( new UDT( 999888777 ) );
|
||||
BOOST_TEST( udt_sp->value() == 999888777 );
|
||||
udt_sp.reset();
|
||||
udt_sp.reset( new UDT( 111222333 ) );
|
||||
@@ -132,7 +126,7 @@ void test()
|
||||
|
||||
// test scoped_array with a build-in type
|
||||
char * sap = new char [ 100 ];
|
||||
scoped_array<char> sa ( sap );
|
||||
boost::scoped_array<char> sa ( sap );
|
||||
BOOST_TEST( sa.get() == sap );
|
||||
BOOST_TEST( sap == sa.get() );
|
||||
|
||||
@@ -152,7 +146,7 @@ void test()
|
||||
|
||||
// test shared_ptr with a built-in type
|
||||
int * ip = new int;
|
||||
shared_ptr<int> cp ( ip );
|
||||
boost::shared_ptr<int> cp ( ip );
|
||||
BOOST_TEST( ip == cp.get() );
|
||||
BOOST_TEST( cp.use_count() == 1 );
|
||||
|
||||
@@ -162,7 +156,7 @@ void test()
|
||||
ck( static_cast<int*>(cp.get()), 54321 );
|
||||
ck( static_cast<int*>(ip), *cp );
|
||||
|
||||
shared_ptr<int> cp2 ( cp );
|
||||
boost::shared_ptr<int> cp2 ( cp );
|
||||
BOOST_TEST( ip == cp2.get() );
|
||||
BOOST_TEST( cp.use_count() == 2 );
|
||||
BOOST_TEST( cp2.use_count() == 2 );
|
||||
@@ -172,7 +166,7 @@ void test()
|
||||
ck( static_cast<int*>(cp2.get()), 54321 );
|
||||
ck( static_cast<int*>(ip), *cp2 );
|
||||
|
||||
shared_ptr<int> cp3 ( cp );
|
||||
boost::shared_ptr<int> cp3 ( cp );
|
||||
BOOST_TEST( cp.use_count() == 3 );
|
||||
BOOST_TEST( cp2.use_count() == 3 );
|
||||
BOOST_TEST( cp3.use_count() == 3 );
|
||||
@@ -202,20 +196,24 @@ void test()
|
||||
BOOST_TEST( cp.use_count() == 3 );
|
||||
BOOST_TEST( *cp == 87654 );
|
||||
|
||||
shared_ptr<int> cp4;
|
||||
#if defined( BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP )
|
||||
using boost::swap;
|
||||
#endif
|
||||
|
||||
boost::shared_ptr<int> cp4;
|
||||
swap( cp2, cp4 );
|
||||
BOOST_TEST( cp4.use_count() == 3 );
|
||||
BOOST_TEST( *cp4 == 87654 );
|
||||
BOOST_TEST( cp2.get() == 0 );
|
||||
|
||||
set< shared_ptr<int> > scp;
|
||||
std::set< boost::shared_ptr<int> > scp;
|
||||
scp.insert(cp4);
|
||||
BOOST_TEST( scp.find(cp4) != scp.end() );
|
||||
BOOST_TEST( scp.find(cp4) == scp.find( shared_ptr<int>(cp4) ) );
|
||||
BOOST_TEST( scp.find(cp4) == scp.find( boost::shared_ptr<int>(cp4) ) );
|
||||
|
||||
// test shared_array with a built-in type
|
||||
char * cap = new char [ 100 ];
|
||||
shared_array<char> ca ( cap );
|
||||
boost::shared_array<char> ca ( cap );
|
||||
BOOST_TEST( ca.get() == cap );
|
||||
BOOST_TEST( cap == ca.get() );
|
||||
BOOST_TEST( &ca[0] == cap );
|
||||
@@ -227,8 +225,8 @@ void test()
|
||||
BOOST_TEST( ca[0] == 'H' );
|
||||
BOOST_TEST( ca[30] == 'h' );
|
||||
|
||||
shared_array<char> ca2 ( ca );
|
||||
shared_array<char> ca3 ( ca2 );
|
||||
boost::shared_array<char> ca2 ( ca );
|
||||
boost::shared_array<char> ca3 ( ca2 );
|
||||
|
||||
ca[0] = 'N';
|
||||
ca[4] = 'd';
|
||||
@@ -246,24 +244,24 @@ void test()
|
||||
ca.reset();
|
||||
BOOST_TEST( ca.get() == 0 );
|
||||
|
||||
shared_array<char> ca4;
|
||||
boost::shared_array<char> ca4;
|
||||
swap( ca3, ca4 );
|
||||
BOOST_TEST( ca4.use_count() == 1 );
|
||||
BOOST_TEST( strcmp( ca4.get(), "Not dog with mustard and relish" ) == 0 );
|
||||
BOOST_TEST( ca3.get() == 0 );
|
||||
|
||||
set< shared_array<char> > sca;
|
||||
std::set< boost::shared_array<char> > sca;
|
||||
sca.insert(ca4);
|
||||
BOOST_TEST( sca.find(ca4) != sca.end() );
|
||||
BOOST_TEST( sca.find(ca4) == sca.find( shared_array<char>(ca4) ) );
|
||||
BOOST_TEST( sca.find(ca4) == sca.find( boost::shared_array<char>(ca4) ) );
|
||||
|
||||
// test shared_array with user defined type
|
||||
shared_array<UDT> udta ( new UDT[3] );
|
||||
boost::shared_array<UDT> udta ( new UDT[3] );
|
||||
|
||||
udta[0].value( 111 );
|
||||
udta[1].value( 222 );
|
||||
udta[2].value( 333 );
|
||||
shared_array<UDT> udta2 ( udta );
|
||||
boost::shared_array<UDT> udta2 ( udta );
|
||||
|
||||
BOOST_TEST( udta[0].value() == 111 );
|
||||
BOOST_TEST( udta[1].value() == 222 );
|
||||
@@ -280,7 +278,7 @@ void test()
|
||||
|
||||
// test shared_ptr with a user defined type
|
||||
UDT * up = new UDT;
|
||||
shared_ptr<UDT> sup ( up );
|
||||
boost::shared_ptr<UDT> sup ( up );
|
||||
BOOST_TEST( up == sup.get() );
|
||||
BOOST_TEST( sup.use_count() == 1 );
|
||||
|
||||
@@ -288,7 +286,7 @@ void test()
|
||||
BOOST_TEST( sup->value() == 54321 );
|
||||
BOOST_TEST( up->value() == 54321 );
|
||||
|
||||
shared_ptr<UDT> sup2;
|
||||
boost::shared_ptr<UDT> sup2;
|
||||
sup2 = sup;
|
||||
BOOST_TEST( sup2->value() == 54321 );
|
||||
BOOST_TEST( sup.use_count() == 2 );
|
||||
@@ -298,7 +296,7 @@ void test()
|
||||
BOOST_TEST( sup.use_count() == 2 );
|
||||
BOOST_TEST( sup2.use_count() == 2 );
|
||||
|
||||
cout << "OK\n";
|
||||
std::cout << "OK\n";
|
||||
|
||||
new char[12345]; // deliberate memory leak to verify leaks detected
|
||||
}
|
||||
|
247
test/sp_atomic_mt2_test.cpp
Normal file
247
test/sp_atomic_mt2_test.cpp
Normal file
@@ -0,0 +1,247 @@
|
||||
|
||||
// Copyright (c) 2008 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
#include <boost/thread/shared_mutex.hpp>
|
||||
#include <boost/thread/locks.hpp>
|
||||
|
||||
#include <boost/detail/lightweight_mutex.hpp>
|
||||
#include <boost/detail/lightweight_thread.hpp>
|
||||
|
||||
#include <vector>
|
||||
#include <numeric>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstddef>
|
||||
#include <ctime>
|
||||
|
||||
//
|
||||
|
||||
static void next_value( unsigned & v )
|
||||
{
|
||||
v = v % 2? 3 * v + 1: v / 2;
|
||||
}
|
||||
|
||||
struct X
|
||||
{
|
||||
std::vector<unsigned> v_;
|
||||
|
||||
explicit X( std::size_t n ): v_( n )
|
||||
{
|
||||
for( std::size_t i = 0; i < n; ++i )
|
||||
{
|
||||
v_[ i ] = i;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned get() const
|
||||
{
|
||||
return std::accumulate( v_.begin(), v_.end(), 0 );
|
||||
}
|
||||
|
||||
void set()
|
||||
{
|
||||
std::for_each( v_.begin(), v_.end(), next_value );
|
||||
}
|
||||
};
|
||||
|
||||
static boost::shared_ptr<X> ps;
|
||||
|
||||
static boost::detail::lightweight_mutex lm;
|
||||
static boost::shared_mutex rw;
|
||||
|
||||
enum prim_type
|
||||
{
|
||||
pt_mutex,
|
||||
pt_rwlock,
|
||||
pt_atomics
|
||||
};
|
||||
|
||||
int read_access( prim_type pt )
|
||||
{
|
||||
switch( pt )
|
||||
{
|
||||
case pt_mutex:
|
||||
{
|
||||
boost::detail::lightweight_mutex::scoped_lock lock( lm );
|
||||
return ps->get();
|
||||
}
|
||||
|
||||
case pt_rwlock:
|
||||
{
|
||||
boost::shared_lock<boost::shared_mutex> lock( rw );
|
||||
return ps->get();
|
||||
}
|
||||
|
||||
case pt_atomics:
|
||||
{
|
||||
boost::shared_ptr<X> p2 = boost::atomic_load( &ps );
|
||||
return p2->get();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void write_access( prim_type pt )
|
||||
{
|
||||
switch( pt )
|
||||
{
|
||||
case pt_mutex:
|
||||
{
|
||||
boost::detail::lightweight_mutex::scoped_lock lock( lm );
|
||||
ps->set();
|
||||
}
|
||||
break;
|
||||
|
||||
case pt_rwlock:
|
||||
{
|
||||
boost::unique_lock<boost::shared_mutex> lock( rw );
|
||||
ps->set();
|
||||
}
|
||||
break;
|
||||
|
||||
case pt_atomics:
|
||||
{
|
||||
boost::shared_ptr<X> p1 = boost::atomic_load( &ps );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
boost::shared_ptr<X> p2( new X( *p1 ) );
|
||||
p2->set();
|
||||
|
||||
if( boost::atomic_compare_exchange( &ps, &p1, p2 ) ) break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void worker( int k, prim_type pt, int n, int r )
|
||||
{
|
||||
++r;
|
||||
|
||||
unsigned s = 0, nr = 0, nw = 0;
|
||||
|
||||
for( int i = 0; i < n; ++i )
|
||||
{
|
||||
if( i % r )
|
||||
{
|
||||
s += read_access( pt );
|
||||
++nr;
|
||||
}
|
||||
else
|
||||
{
|
||||
write_access( pt );
|
||||
++s;
|
||||
++nw;
|
||||
}
|
||||
}
|
||||
|
||||
printf( "Worker %2d: %u:%u, %10u\n", k, nr, nw, s );
|
||||
}
|
||||
|
||||
#if defined( BOOST_HAS_PTHREADS )
|
||||
char const * thmodel = "POSIX";
|
||||
#else
|
||||
char const * thmodel = "Windows";
|
||||
#endif
|
||||
|
||||
char const * pt_to_string( prim_type pt )
|
||||
{
|
||||
switch( pt )
|
||||
{
|
||||
case pt_mutex:
|
||||
|
||||
return "mutex";
|
||||
|
||||
case pt_rwlock:
|
||||
|
||||
return "rwlock";
|
||||
|
||||
case pt_atomics:
|
||||
|
||||
return "atomics";
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_pt_option( std::string const & opt, prim_type & pt, prim_type pt2 )
|
||||
{
|
||||
if( opt == pt_to_string( pt2 ) )
|
||||
{
|
||||
pt = pt2;
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_int_option( std::string const & opt, std::string const & prefix, int & k, int kmin, int kmax )
|
||||
{
|
||||
if( opt.substr( 0, prefix.size() ) == prefix )
|
||||
{
|
||||
int v = atoi( opt.substr( prefix.size() ).c_str() );
|
||||
|
||||
if( v >= kmin && v <= kmax )
|
||||
{
|
||||
k = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main( int ac, char const * av[] )
|
||||
{
|
||||
using namespace std; // printf, clock_t, clock
|
||||
|
||||
int m = 4; // threads
|
||||
int n = 10000; // vector size
|
||||
int k = 1000000; // iterations
|
||||
int r = 100; // read/write ratio, r:1
|
||||
|
||||
prim_type pt = pt_atomics;
|
||||
|
||||
for( int i = 1; i < ac; ++i )
|
||||
{
|
||||
handle_pt_option( av[i], pt, pt_mutex );
|
||||
handle_pt_option( av[i], pt, pt_rwlock );
|
||||
handle_pt_option( av[i], pt, pt_atomics );
|
||||
|
||||
handle_int_option( av[i], "n=", n, 1, INT_MAX );
|
||||
handle_int_option( av[i], "size=", n, 1, INT_MAX );
|
||||
|
||||
handle_int_option( av[i], "k=", k, 1, INT_MAX );
|
||||
handle_int_option( av[i], "iterations=", k, 1, INT_MAX );
|
||||
|
||||
handle_int_option( av[i], "m=", m, 1, INT_MAX );
|
||||
handle_int_option( av[i], "threads=", m, 1, INT_MAX );
|
||||
|
||||
handle_int_option( av[i], "r=", r, 1, INT_MAX );
|
||||
handle_int_option( av[i], "ratio=", r, 1, INT_MAX );
|
||||
}
|
||||
|
||||
printf( "%s: threads=%d size=%d iterations=%d ratio=%d %s\n\n", thmodel, m, n, k, r, pt_to_string( pt ) );
|
||||
|
||||
ps.reset( new X( n ) );
|
||||
|
||||
clock_t t = clock();
|
||||
|
||||
std::vector<pthread_t> a( m );
|
||||
|
||||
for( int i = 0; i < m; ++i )
|
||||
{
|
||||
boost::detail::lw_thread_create( a[ i ], boost::bind( worker, i, pt, k, r ) );
|
||||
}
|
||||
|
||||
for( int j = 0; j < m; ++j )
|
||||
{
|
||||
pthread_join( a[ j ], 0 );
|
||||
}
|
||||
|
||||
t = clock() - t;
|
||||
|
||||
double ts = static_cast<double>( t ) / CLOCKS_PER_SEC;
|
||||
printf( "%.3f seconds, %.3f accesses per microsecond.\n", ts, m * k / ts / 1e+6 );
|
||||
}
|
191
test/sp_atomic_mt_test.cpp
Normal file
191
test/sp_atomic_mt_test.cpp
Normal file
@@ -0,0 +1,191 @@
|
||||
|
||||
// Copyright (c) 2008 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
//#define USE_MUTEX
|
||||
//#define USE_RWLOCK
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
#if defined( USE_RWLOCK )
|
||||
#include <boost/thread/shared_mutex.hpp>
|
||||
#include <boost/thread/locks.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/detail/lightweight_mutex.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/detail/lightweight_thread.hpp>
|
||||
|
||||
#include <cstdio>
|
||||
#include <ctime>
|
||||
|
||||
//
|
||||
|
||||
int const n = 1024 * 1024;
|
||||
|
||||
struct X
|
||||
{
|
||||
int v_; // version
|
||||
|
||||
unsigned a_;
|
||||
unsigned b_;
|
||||
|
||||
X(): v_( 0 ), a_( 1 ), b_( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
int get() const
|
||||
{
|
||||
return a_ * 7 + b_ * 11;
|
||||
}
|
||||
|
||||
void set()
|
||||
{
|
||||
int tmp = get();
|
||||
|
||||
b_ = a_;
|
||||
a_ = tmp;
|
||||
|
||||
++v_;
|
||||
}
|
||||
};
|
||||
|
||||
static boost::shared_ptr<X> ps( new X );
|
||||
|
||||
static boost::detail::lightweight_mutex lm;
|
||||
|
||||
#if defined( USE_RWLOCK )
|
||||
static boost::shared_mutex rw;
|
||||
#endif
|
||||
|
||||
static int tr = 0;
|
||||
|
||||
void reader( int r )
|
||||
{
|
||||
int k = 0;
|
||||
unsigned s = 0;
|
||||
|
||||
for( int i = 0; i < n; ++k )
|
||||
{
|
||||
#if defined( USE_MUTEX )
|
||||
|
||||
boost::detail::lightweight_mutex::scoped_lock lock( lm );
|
||||
|
||||
s += ps->get();
|
||||
|
||||
BOOST_TEST( ps->v_ >= i );
|
||||
i = ps->v_;
|
||||
|
||||
#elif defined( USE_RWLOCK )
|
||||
|
||||
boost::shared_lock<boost::shared_mutex> lock( rw );
|
||||
|
||||
s += ps->get();
|
||||
|
||||
BOOST_TEST( ps->v_ >= i );
|
||||
i = ps->v_;
|
||||
|
||||
#else
|
||||
|
||||
boost::shared_ptr<X> p2 = boost::atomic_load( &ps );
|
||||
|
||||
s += p2->get();
|
||||
|
||||
BOOST_TEST( p2->v_ >= i );
|
||||
i = p2->v_;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
printf( "Reader %d: %9d iterations (%6.3fx), %u\n", r, k, (double)k / n, s );
|
||||
|
||||
boost::detail::lightweight_mutex::scoped_lock lock( lm );
|
||||
tr += k;
|
||||
}
|
||||
|
||||
void writer()
|
||||
{
|
||||
for( int i = 0; i < n; ++i )
|
||||
{
|
||||
#if defined( USE_MUTEX )
|
||||
|
||||
boost::detail::lightweight_mutex::scoped_lock lock( lm );
|
||||
|
||||
BOOST_TEST( ps->v_ == i );
|
||||
ps->set();
|
||||
|
||||
#elif defined( USE_RWLOCK )
|
||||
|
||||
boost::unique_lock<boost::shared_mutex> lock( rw );
|
||||
|
||||
BOOST_TEST( ps->v_ == i );
|
||||
ps->set();
|
||||
|
||||
#else
|
||||
|
||||
boost::shared_ptr<X> p2( new X( *ps ) );
|
||||
|
||||
BOOST_TEST( p2->v_ == i );
|
||||
p2->set();
|
||||
|
||||
boost::atomic_store( &ps, p2 );
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if defined( BOOST_HAS_PTHREADS )
|
||||
char const * thmodel = "POSIX";
|
||||
#else
|
||||
char const * thmodel = "Windows";
|
||||
#endif
|
||||
|
||||
int const mr = 8; // reader threads
|
||||
int const mw = 1; // writer thread
|
||||
|
||||
#if defined( USE_MUTEX )
|
||||
char const * prim = "mutex";
|
||||
#elif defined( USE_RWLOCK )
|
||||
char const * prim = "rwlock";
|
||||
#else
|
||||
char const * prim = "atomics";
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace std; // printf, clock_t, clock
|
||||
|
||||
printf( "Using %s threads: %dR + %dW threads, %d iterations, %s\n\n", thmodel, mr, mw, n, prim );
|
||||
|
||||
clock_t t = clock();
|
||||
|
||||
pthread_t a[ mr+mw ];
|
||||
|
||||
for( int i = 0; i < mr; ++i )
|
||||
{
|
||||
boost::detail::lw_thread_create( a[ i ], boost::bind( reader, i ) );
|
||||
}
|
||||
|
||||
for( int i = mr; i < mr+mw; ++i )
|
||||
{
|
||||
boost::detail::lw_thread_create( a[ i ], writer );
|
||||
}
|
||||
|
||||
for( int j = 0; j < mr+mw; ++j )
|
||||
{
|
||||
pthread_join( a[ j ], 0 );
|
||||
}
|
||||
|
||||
t = clock() - t;
|
||||
|
||||
double ts = static_cast<double>( t ) / CLOCKS_PER_SEC;
|
||||
printf( "%.3f seconds, %.3f reads per microsecond.\n", ts, tr / ts / 1e+6 );
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
87
test/sp_atomic_test.cpp
Normal file
87
test/sp_atomic_test.cpp
Normal file
@@ -0,0 +1,87 @@
|
||||
#include <boost/config.hpp>
|
||||
|
||||
// sp_atomic_test.cpp
|
||||
//
|
||||
// Copyright (c) 2008 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
//
|
||||
|
||||
struct X
|
||||
{
|
||||
};
|
||||
|
||||
#define BOOST_TEST_SP_EQ( p, q ) BOOST_TEST( p == q && !( p < q ) && !( q < p ) )
|
||||
|
||||
int main()
|
||||
{
|
||||
boost::shared_ptr<X> px( new X );
|
||||
|
||||
{
|
||||
boost::shared_ptr<X> p2 = boost::atomic_load( &px );
|
||||
BOOST_TEST_SP_EQ( p2, px );
|
||||
|
||||
boost::shared_ptr<X> px2( new X );
|
||||
boost::atomic_store( &px, px2 );
|
||||
BOOST_TEST_SP_EQ( px, px2 );
|
||||
|
||||
p2 = boost::atomic_load( &px );
|
||||
BOOST_TEST_SP_EQ( p2, px );
|
||||
BOOST_TEST_SP_EQ( p2, px2 );
|
||||
|
||||
boost::shared_ptr<X> px3( new X );
|
||||
boost::shared_ptr<X> p3 = boost::atomic_exchange( &px, px3 );
|
||||
BOOST_TEST_SP_EQ( p3, px2 );
|
||||
BOOST_TEST_SP_EQ( px, px3 );
|
||||
|
||||
boost::shared_ptr<X> px4( new X );
|
||||
boost::shared_ptr<X> cmp;
|
||||
|
||||
bool r = boost::atomic_compare_exchange( &px, &cmp, px4 );
|
||||
BOOST_TEST( !r );
|
||||
BOOST_TEST_SP_EQ( px, px3 );
|
||||
BOOST_TEST_SP_EQ( cmp, px3 );
|
||||
|
||||
r = boost::atomic_compare_exchange( &px, &cmp, px4 );
|
||||
BOOST_TEST( r );
|
||||
BOOST_TEST_SP_EQ( px, px4 );
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
px.reset();
|
||||
|
||||
{
|
||||
boost::shared_ptr<X> p2 = boost::atomic_load_explicit( &px, boost::memory_order_acquire );
|
||||
BOOST_TEST_SP_EQ( p2, px );
|
||||
|
||||
boost::shared_ptr<X> px2( new X );
|
||||
boost::atomic_store_explicit( &px, px2, boost::memory_order_release );
|
||||
BOOST_TEST_SP_EQ( px, px2 );
|
||||
|
||||
boost::shared_ptr<X> p3 = boost::atomic_exchange_explicit( &px, boost::shared_ptr<X>(), boost::memory_order_acq_rel );
|
||||
BOOST_TEST_SP_EQ( p3, px2 );
|
||||
BOOST_TEST_SP_EQ( px, p2 );
|
||||
|
||||
boost::shared_ptr<X> px4( new X );
|
||||
boost::shared_ptr<X> cmp( px2 );
|
||||
|
||||
bool r = boost::atomic_compare_exchange_explicit( &px, &cmp, px4, boost::memory_order_acquire, boost::memory_order_relaxed );
|
||||
BOOST_TEST( !r );
|
||||
BOOST_TEST_SP_EQ( px, p2 );
|
||||
BOOST_TEST_SP_EQ( cmp, p2 );
|
||||
|
||||
r = boost::atomic_compare_exchange_explicit( &px, &cmp, px4, boost::memory_order_release, boost::memory_order_acquire );
|
||||
BOOST_TEST( r );
|
||||
BOOST_TEST_SP_EQ( px, px4 );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
71
test/sp_convertible_test.cpp
Normal file
71
test/sp_convertible_test.cpp
Normal file
@@ -0,0 +1,71 @@
|
||||
#include <boost/config.hpp>
|
||||
|
||||
// sp_convertible_test.cpp
|
||||
//
|
||||
// Copyright (c) 2008 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
//
|
||||
|
||||
class incomplete;
|
||||
|
||||
struct X
|
||||
{
|
||||
};
|
||||
|
||||
struct Y
|
||||
{
|
||||
};
|
||||
|
||||
struct Z: public X
|
||||
{
|
||||
};
|
||||
|
||||
int f( boost::shared_ptr<void const> )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int f( boost::shared_ptr<int> )
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
int f( boost::shared_ptr<incomplete> )
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
int g( boost::shared_ptr<X> )
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
int g( boost::shared_ptr<Y> )
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
|
||||
int g( boost::shared_ptr<incomplete> )
|
||||
{
|
||||
return 6;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
boost::shared_ptr<double> p1;
|
||||
BOOST_TEST( 1 == f( p1 ) );
|
||||
BOOST_TEST( 1 == f( boost::shared_ptr<double>() ) );
|
||||
|
||||
boost::shared_ptr<Z> p2;
|
||||
BOOST_TEST( 4 == g( p2 ) );
|
||||
BOOST_TEST( 4 == g( boost::shared_ptr<Z>() ) );
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
67
test/sp_unary_addr_test.cpp
Normal file
67
test/sp_unary_addr_test.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
//
|
||||
// sp_unary_addr_test.cpp
|
||||
//
|
||||
// Copyright (c) 2007 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <memory>
|
||||
|
||||
struct deleter
|
||||
{
|
||||
private:
|
||||
|
||||
void operator& ();
|
||||
void operator& () const;
|
||||
|
||||
public:
|
||||
|
||||
int data;
|
||||
|
||||
deleter(): data( 17041 )
|
||||
{
|
||||
}
|
||||
|
||||
void operator()( void * )
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct X
|
||||
{
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
X x;
|
||||
|
||||
{
|
||||
boost::shared_ptr<X> p( &x, deleter() );
|
||||
|
||||
deleter * q = boost::get_deleter<deleter>( p );
|
||||
|
||||
BOOST_TEST( q != 0 );
|
||||
BOOST_TEST( q != 0 && q->data == 17041 );
|
||||
}
|
||||
|
||||
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, < 1300 )
|
||||
#else
|
||||
|
||||
{
|
||||
boost::shared_ptr<X> p( &x, deleter(), std::allocator<X>() );
|
||||
|
||||
deleter * q = boost::get_deleter<deleter>( p );
|
||||
|
||||
BOOST_TEST( q != 0 );
|
||||
BOOST_TEST( q != 0 && q->data == 17041 );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
30
test/spinlock_pool_test.cpp
Normal file
30
test/spinlock_pool_test.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
//
|
||||
// spinlock_pool_test.cpp
|
||||
//
|
||||
// Copyright 2008 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
|
||||
#include <boost/detail/spinlock_pool.hpp>
|
||||
|
||||
// Sanity check only
|
||||
|
||||
int main()
|
||||
{
|
||||
int x = 0;
|
||||
|
||||
{
|
||||
boost::detail::spinlock_pool<0>::scoped_lock lock( &x );
|
||||
++x;
|
||||
}
|
||||
|
||||
{
|
||||
boost::detail::spinlock_pool<1>::scoped_lock lock( &x );
|
||||
boost::detail::spinlock_pool<2>::scoped_lock lock2( &x );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
31
test/spinlock_test.cpp
Normal file
31
test/spinlock_test.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
//
|
||||
// spinlock_test.cpp
|
||||
//
|
||||
// Copyright 2008 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <boost/detail/spinlock.hpp>
|
||||
|
||||
// Sanity check only
|
||||
|
||||
static boost::detail::spinlock sp = BOOST_DETAIL_SPINLOCK_INIT;
|
||||
static boost::detail::spinlock sp2 = BOOST_DETAIL_SPINLOCK_INIT;
|
||||
|
||||
int main()
|
||||
{
|
||||
sp.lock();
|
||||
sp2.lock();
|
||||
sp.unlock();
|
||||
sp2.unlock();
|
||||
|
||||
{
|
||||
boost::detail::spinlock::scoped_lock lock( sp );
|
||||
boost::detail::spinlock::scoped_lock lock2( sp2 );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
46
test/spinlock_try_test.cpp
Normal file
46
test/spinlock_try_test.cpp
Normal file
@@ -0,0 +1,46 @@
|
||||
//
|
||||
// spinlock_try_test.cpp
|
||||
//
|
||||
// Copyright 2008 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <boost/detail/spinlock.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
// Sanity check only
|
||||
|
||||
static boost::detail::spinlock sp = BOOST_DETAIL_SPINLOCK_INIT;
|
||||
static boost::detail::spinlock sp2 = BOOST_DETAIL_SPINLOCK_INIT;
|
||||
|
||||
int main()
|
||||
{
|
||||
BOOST_TEST( sp.try_lock() );
|
||||
BOOST_TEST( !sp.try_lock() );
|
||||
BOOST_TEST( sp2.try_lock() );
|
||||
BOOST_TEST( !sp.try_lock() );
|
||||
BOOST_TEST( !sp2.try_lock() );
|
||||
sp.unlock();
|
||||
sp2.unlock();
|
||||
|
||||
sp.lock();
|
||||
BOOST_TEST( !sp.try_lock() );
|
||||
sp2.lock();
|
||||
BOOST_TEST( !sp.try_lock() );
|
||||
BOOST_TEST( !sp2.try_lock() );
|
||||
sp.unlock();
|
||||
sp2.unlock();
|
||||
|
||||
{
|
||||
boost::detail::spinlock::scoped_lock lock( sp );
|
||||
BOOST_TEST( !sp.try_lock() );
|
||||
boost::detail::spinlock::scoped_lock lock2( sp2 );
|
||||
BOOST_TEST( !sp.try_lock() );
|
||||
BOOST_TEST( !sp2.try_lock() );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
@@ -7,128 +7,26 @@
|
||||
#pragma warning(disable: 4514) // unreferenced inline removed
|
||||
#endif
|
||||
|
||||
//
|
||||
// weak_ptr_mt_test.cpp
|
||||
//
|
||||
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
|
||||
// Copyright 2005 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Copyright 2005, 2008 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/weak_ptr.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <cstdio>
|
||||
#include <ctime>
|
||||
#include <cstdlib>
|
||||
|
||||
// 'portable' thread framework
|
||||
|
||||
class abstract_thread
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~abstract_thread() {}
|
||||
virtual void run() = 0;
|
||||
};
|
||||
|
||||
#if !defined(BOOST_HAS_PTHREADS) && defined(BOOST_HAS_WINTHREADS)
|
||||
|
||||
char const * title = "Using Windows threads";
|
||||
|
||||
#include <windows.h>
|
||||
#include <process.h>
|
||||
|
||||
typedef HANDLE pthread_t;
|
||||
|
||||
unsigned __stdcall common_thread_routine(void * pv)
|
||||
{
|
||||
abstract_thread * pt = static_cast<abstract_thread *>(pv);
|
||||
pt->run();
|
||||
delete pt;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_create(pthread_t * thread, void const *, unsigned (__stdcall * start_routine) (void*), void* arg)
|
||||
{
|
||||
HANDLE h = (HANDLE)_beginthreadex(0, 0, start_routine, arg, 0, 0);
|
||||
|
||||
if(h != 0)
|
||||
{
|
||||
*thread = h;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1; // return errno;
|
||||
}
|
||||
}
|
||||
|
||||
int pthread_join(pthread_t thread, void ** /*value_ptr*/)
|
||||
{
|
||||
::WaitForSingleObject(thread, INFINITE);
|
||||
::CloseHandle(thread);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
char const * title = "Using POSIX threads";
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
extern "C" void * common_thread_routine(void * pv)
|
||||
{
|
||||
abstract_thread * pt = static_cast<abstract_thread *>(pv);
|
||||
pt->run();
|
||||
delete pt;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
|
||||
template<class F> class thread: public abstract_thread
|
||||
{
|
||||
public:
|
||||
|
||||
explicit thread(F f): f_(f)
|
||||
{
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
f_();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
F f_;
|
||||
};
|
||||
|
||||
template<class F> pthread_t createThread(F f)
|
||||
{
|
||||
std::auto_ptr<abstract_thread> p(new thread<F>(f));
|
||||
|
||||
pthread_t r;
|
||||
|
||||
if(pthread_create(&r, 0, common_thread_routine, p.get()) == 0)
|
||||
{
|
||||
p.release();
|
||||
return r;
|
||||
}
|
||||
|
||||
throw std::runtime_error("createThread failed.");
|
||||
}
|
||||
#include <boost/detail/lightweight_thread.hpp>
|
||||
|
||||
//
|
||||
|
||||
@@ -177,11 +75,21 @@ void test( std::vector< boost::shared_ptr<int> > & v )
|
||||
printf( "\n%d locks, %d forced rebinds, %d normal rebinds.", s, f, r );
|
||||
}
|
||||
|
||||
#if defined( BOOST_HAS_PTHREADS )
|
||||
|
||||
char const * thmodel = "POSIX";
|
||||
|
||||
#else
|
||||
|
||||
char const * thmodel = "Windows";
|
||||
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace std; // printf, clock_t, clock
|
||||
|
||||
printf("%s: %d threads, %d * %d iterations: ", title, m, n, k );
|
||||
printf("Using %s threads: %d threads, %d * %d iterations: ", thmodel, m, n, k );
|
||||
|
||||
std::vector< boost::shared_ptr<int> > v( k );
|
||||
|
||||
@@ -192,16 +100,16 @@ int main()
|
||||
|
||||
clock_t t = clock();
|
||||
|
||||
pthread_t a[m];
|
||||
pthread_t a[ m ];
|
||||
|
||||
for(int i = 0; i < m; ++i)
|
||||
for( int i = 0; i < m; ++i )
|
||||
{
|
||||
a[i] = createThread( boost::bind( test, v ) );
|
||||
boost::detail::lw_thread_create( a[ i ], boost::bind( test, v ) );
|
||||
}
|
||||
|
||||
v.resize( 0 ); // kill original copies
|
||||
|
||||
for(int j = 0; j < m; ++j)
|
||||
for( int j = 0; j < m; ++j )
|
||||
{
|
||||
pthread_join( a[j], 0 );
|
||||
}
|
||||
|
68
test/wp_convertible_test.cpp
Normal file
68
test/wp_convertible_test.cpp
Normal file
@@ -0,0 +1,68 @@
|
||||
#include <boost/config.hpp>
|
||||
|
||||
// wp_convertible_test.cpp
|
||||
//
|
||||
// Copyright (c) 2008 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/weak_ptr.hpp>
|
||||
|
||||
//
|
||||
|
||||
class incomplete;
|
||||
|
||||
struct X
|
||||
{
|
||||
};
|
||||
|
||||
struct Y
|
||||
{
|
||||
};
|
||||
|
||||
struct Z: public X
|
||||
{
|
||||
};
|
||||
|
||||
int f( boost::weak_ptr<void const> )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int f( boost::weak_ptr<int> )
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
int f( boost::weak_ptr<incomplete> )
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
int g( boost::weak_ptr<X> )
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
int g( boost::weak_ptr<Y> )
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
|
||||
int g( boost::weak_ptr<incomplete> )
|
||||
{
|
||||
return 6;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
BOOST_TEST( 1 == f( boost::weak_ptr<double>() ) );
|
||||
BOOST_TEST( 1 == f( boost::shared_ptr<double>() ) );
|
||||
BOOST_TEST( 4 == g( boost::weak_ptr<Z>() ) );
|
||||
BOOST_TEST( 4 == g( boost::shared_ptr<Z>() ) );
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
23
test/yield_k_test.cpp
Normal file
23
test/yield_k_test.cpp
Normal file
@@ -0,0 +1,23 @@
|
||||
//
|
||||
// yield_k_test.cpp
|
||||
//
|
||||
// Copyright 2008 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <boost/detail/yield_k.hpp>
|
||||
|
||||
// Sanity check only
|
||||
|
||||
int main()
|
||||
{
|
||||
for( unsigned k = 0; k < 256; ++k )
|
||||
{
|
||||
boost::detail::yield( k );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@@ -235,10 +235,8 @@ public:
|
||||
<hr>
|
||||
<p>$Date$</p>
|
||||
<p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
|
||||
Copyright 2002-2005 Peter Dimov. Permission to copy, use, modify, sell and
|
||||
distribute this document is granted provided this copyright notice appears in
|
||||
all copies. This document is provided "as is" without express or implied
|
||||
warranty, and with no claim as to its suitability for any purpose.</small></p>
|
||||
</A>
|
||||
Copyright 2002-2005 Peter Dimov. Distributed under the Boost Software License, Version
|
||||
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or
|
||||
copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
|
||||
</body>
|
||||
</html>
|
||||
|
Reference in New Issue
Block a user