Compare commits

...

24 Commits

Author SHA1 Message Date
Beman Dawes
28a0d328bf 1.37.0 Beta 1
[SVN r49441]
2008-10-23 11:39:59 +00:00
Nicola Musatti
6f91ea87c3 CodeGear patch. Fixes #2342
[SVN r49320]
2008-10-13 19:22:17 +00:00
Peter Dimov
6e804e64b8 Merge 48832-48840 from trunk.
[SVN r48989]
2008-09-28 15:05:17 +00:00
Peter Dimov
6ba78f76f6 Merge 47736 from trunk (untabify).
[SVN r47739]
2008-07-23 20:47:47 +00:00
Peter Dimov
556b9fe563 Merge 47357 (atomic access N2674 edits) from trunk to release.
[SVN r47358]
2008-07-12 16:18:05 +00:00
Peter Dimov
991b02b03e Whitespace fix.
[SVN r47356]
2008-07-12 15:16:31 +00:00
Peter Dimov
31d0c48f18 Merged 45224, 45225 from trunk to release.
[SVN r47355]
2008-07-12 14:47:13 +00:00
Peter Dimov
1b49f08cb8 Merged 44686 from trunk to release.
[SVN r47350]
2008-07-12 12:21:19 +00:00
Peter Dimov
034c12d244 Merged 44636, 44640, 45094 (atomic access) from trunk to release.
[SVN r47349]
2008-07-12 11:57:45 +00:00
Peter Dimov
f884c53bd6 Updated spinlock_pool.hpp from trunk HEAD; takes care of 45069.
[SVN r47346]
2008-07-12 11:41:20 +00:00
Peter Dimov
07b4c17980 Merged 44979, 45068, 45085, 45089, 45177, 45194, 45346, 45422, 45545, 46055 from trunk to release
[SVN r47345]
2008-07-12 11:37:16 +00:00
Peter Dimov
1bc4f16ff8 Update esft_regtest.cpp to trunk HEAD; takes care of 43829, 43856, 44775.
[SVN r47342]
2008-07-12 10:45:56 +00:00
Peter Dimov
774a8d330c Merged 44595, 44638, 44707, 44711, 44728 from trunk to release
[SVN r47341]
2008-07-12 10:41:24 +00:00
Peter Dimov
0fd94d6d56 Updated sp_counted_base.hpp to trunk version; takes care of 44369, 44441.
[SVN r47340]
2008-07-12 10:17:08 +00:00
Peter Dimov
866590ee97 Merged 43316, 43317, 43318, 43733, 43782, 43873, 43888, 43916, 43950, 44055, 44056, 44058, 44073, 44074, 44132, 44137, 44138, 44140, 44344 from trunk to release
[SVN r47339]
2008-07-12 09:55:08 +00:00
Peter Dimov
a9cd84f43d Fix #1938 in release
[SVN r45691]
2008-05-23 20:30:15 +00:00
Peter Dimov
2fe899cdfe Disable sync use for arm and hppa.
[SVN r44440]
2008-04-15 18:57:46 +00:00
Peter Dimov
316d00c3fc Fix #1759 in release.
[SVN r44005]
2008-04-02 21:52:08 +00:00
Daniel James
4ba016d29e Merged revisions 43206,43208-43213 via svnmerge from
https://svn.boost.org/svn/boost/trunk

........
  r43206 | danieljames | 2008-02-10 09:55:03 +0000 (Sun, 10 Feb 2008) | 1 line
  
  Fix some broken links.
........
  r43209 | danieljames | 2008-02-10 14:56:22 +0000 (Sun, 10 Feb 2008) | 1 line
  
  Link to people pages on the website, as they've been removed from the download.
........
  r43210 | danieljames | 2008-02-10 15:02:17 +0000 (Sun, 10 Feb 2008) | 1 line
  
  Point links to the pages that used to be in 'more' to the site.
........
  r43212 | danieljames | 2008-02-10 16:10:16 +0000 (Sun, 10 Feb 2008) | 1 line
  
  Fix links on the home page as well.
........
  r43213 | danieljames | 2008-02-10 16:21:22 +0000 (Sun, 10 Feb 2008) | 1 line
  
  Generated documentation which is no longer generated.
........


[SVN r43214]
2008-02-10 16:39:38 +00:00
Beman Dawes
60ae24f4ae Pick up missing smart_ptr, utility, and type_traits files from full merge from trunk at revision 41356 of entire boost-root tree.
[SVN r41386]
2007-11-25 22:34:55 +00:00
Beman Dawes
dba6ebbb01 Full merge from trunk at revision 41356 of entire boost-root tree.
[SVN r41370]
2007-11-25 18:38:02 +00:00
Beman Dawes
d2194e3b24 Full merge from trunk at revision 41356 of entire boost-root tree.
[SVN r41369]
2007-11-25 18:07:19 +00:00
Beman Dawes
5ab6b24856 config, detail, filesystem, system, tools, at 41278.
[SVN r41316]
2007-11-23 17:03:14 +00:00
Beman Dawes
87c6b6b403 Starting point for releases
[SVN r39706]
2007-10-05 14:25:06 +00:00
81 changed files with 4838 additions and 430 deletions

View File

@@ -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>

View File

@@ -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

View File

@@ -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
{

View 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

View 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

View 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

View File

@@ -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

View File

@@ -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 &);

View File

@@ -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

View 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

View File

@@ -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

View 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

View File

@@ -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()
{

View File

@@ -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()
{

View File

@@ -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()
{

View File

@@ -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()
{

View 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

View File

@@ -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()
{

View File

@@ -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()
{

View File

@@ -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()
{

View 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

View 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

View 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

View File

@@ -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()
{

View File

@@ -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;
}
};

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View File

@@ -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

View 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

View 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

View File

@@ -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)

View File

@@ -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.

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -61,7 +61,10 @@
intrusive_ptr &amp; <A href="#assignment" >operator=</A>(intrusive_ptr const &amp; r);
template&lt;class Y&gt; intrusive_ptr &amp; <A href="#assignment" >operator=</A>(intrusive_ptr&lt;Y&gt; const &amp; r);
template&lt;class Y&gt; intrusive_ptr &amp; <A href="#assignment" >operator=</A>(T * r);
intrusive_ptr &amp; <A href="#assignment" >operator=</A>(T * r);
void <a href="#reset" >reset</a>();
void <a href="#reset" >reset</a>(T * r);
T &amp; <A href="#indirection" >operator*</A>() const; // never throws
T * <A href="#indirection" >operator-&gt;</A>() const; // never throws
@@ -146,6 +149,15 @@ intrusive_ptr &amp; 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 &amp; operator*() const; // never throws</pre>
<blockquote>

View File

@@ -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>

View File

@@ -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>

View File

@@ -47,7 +47,7 @@
void <a href="#reset">reset</a>(T * p = 0);
template&lt;class D&gt; void <a href="#reset">reset</a>(T * p, D d);
T &amp; <a href="#indexing">operator[]</a>(std::ptrdiff_t i) const() const; // never throws
T &amp; <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&lt;class T&gt;
<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>

View File

@@ -111,6 +111,7 @@ void bad()
<A href="#constructors" >shared_ptr</A>(shared_ptr const &amp; r); // never throws
template&lt;class Y&gt; <A href="#constructors" >shared_ptr</A>(shared_ptr&lt;Y&gt; const &amp; r); // never throws
template&lt;class Y&gt; <A href="#constructors" >shared_ptr</A>(shared_ptr&lt;Y&gt; const &amp; r, T * p); // never throws
template&lt;class Y&gt; explicit <A href="#constructors" >shared_ptr</A>(<A href="weak_ptr.htm" >weak_ptr</A>&lt;Y&gt; const &amp; r);
template&lt;class Y&gt; explicit <A href="#constructors" >shared_ptr</A>(std::auto_ptr&lt;Y&gt; &amp; r);
@@ -122,6 +123,7 @@ void bad()
template&lt;class Y&gt; void <A href="#reset" >reset</A>(Y * p);
template&lt;class Y, class D&gt; void <A href="#reset" >reset</A>(Y * p, D d);
template&lt;class Y, class D, class A&gt; void <A href="#reset" >reset</A>(Y * p, D d, A a);
template&lt;class Y&gt; void <A href="#reset" >reset</A>(shared_ptr&lt;Y&gt; const &amp; r, T * p); // never throws
T &amp; <A href="#indirection" >operator*</A>() const; // never throws
T * <A href="#indirection" >operator-&gt;</A>() const; // never throws
@@ -253,6 +255,13 @@ template&lt;class Y&gt; shared_ptr(shared_ptr&lt;Y&gt; const &amp; r); // never
r.use_count()</code>.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<pre>template&lt;class Y&gt; shared_ptr(shared_ptr&lt;Y&gt; const &amp; 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 &amp;&amp; use_count() == r.use_count()</code>.</p>
<p><b>Throws:</b> nothing.</p>
</blockquote>
<pre>template&lt;class Y&gt; explicit shared_ptr(<A href="weak_ptr.htm" >weak_ptr</A>&lt;Y&gt; const &amp; 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&lt;class Y&gt; void reset(shared_ptr&lt;Y&gt; const &amp; 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 &amp; 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>&amp;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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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)
{

View File

@@ -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 ]
;
}

View 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
View 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();
}

View 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
View 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();
}

View File

@@ -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

View 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;
}

View 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;
}

View File

@@ -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 &)
{

View 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();
}

View 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;
}

View 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();
}

View File

@@ -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;
}

View 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
View 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();
}

View File

@@ -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);
}
}

View File

@@ -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
View 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
View 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
View 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();
}

View 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();
}

View 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();
}

View 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
View 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;
}

View 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();
}

View File

@@ -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 );
}

View 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
View 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;
}

View File

@@ -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>