forked from boostorg/smart_ptr
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]
This commit is contained in:
@ -46,6 +46,8 @@ int const weak_count_id = 0x298C38A4;
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct sp_nothrow_tag {};
|
||||||
|
|
||||||
class weak_count;
|
class weak_count;
|
||||||
|
|
||||||
class shared_count
|
class shared_count
|
||||||
@ -216,6 +218,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
explicit shared_count(weak_count const & r); // throws bad_weak_ptr when r.use_count() == 0
|
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
|
shared_count & operator= (shared_count const & r) // nothrow
|
||||||
{
|
{
|
||||||
@ -248,6 +251,11 @@ public:
|
|||||||
return use_count() == 1;
|
return use_count() == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool empty() const // nothrow
|
||||||
|
{
|
||||||
|
return pi_ == 0;
|
||||||
|
}
|
||||||
|
|
||||||
friend inline bool operator==(shared_count const & a, shared_count const & b)
|
friend inline bool operator==(shared_count const & a, shared_count const & b)
|
||||||
{
|
{
|
||||||
return a.pi_ == b.pi_;
|
return a.pi_ == b.pi_;
|
||||||
@ -364,6 +372,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 detail
|
||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
@ -23,6 +23,10 @@
|
|||||||
|
|
||||||
# include <boost/detail/sp_counted_base_nt.hpp>
|
# include <boost/detail/sp_counted_base_nt.hpp>
|
||||||
|
|
||||||
|
#elif defined( BOOST_SP_USE_SPINLOCK )
|
||||||
|
|
||||||
|
# include <boost/detail/sp_counted_base_spin.hpp>
|
||||||
|
|
||||||
#elif defined( BOOST_SP_USE_PTHREADS )
|
#elif defined( BOOST_SP_USE_PTHREADS )
|
||||||
|
|
||||||
# include <boost/detail/sp_counted_base_pt.hpp>
|
# include <boost/detail/sp_counted_base_pt.hpp>
|
||||||
|
131
include/boost/detail/sp_counted_base_spin.hpp
Normal file
131
include/boost/detail/sp_counted_base_spin.hpp
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
#ifndef BOOST_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED
|
||||||
|
#define BOOST_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED
|
||||||
|
|
||||||
|
// MS compatible compilers support #pragma once
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||||
|
# pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
// detail/sp_counted_base_spin.hpp - spinlock pool atomic emulation
|
||||||
|
//
|
||||||
|
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
|
||||||
|
// Copyright 2004-2008 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See
|
||||||
|
// accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/detail/sp_typeinfo.hpp>
|
||||||
|
#include <boost/detail/spinlock_pool.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
inline int atomic_exchange_and_add( int * pw, int dv )
|
||||||
|
{
|
||||||
|
spinlock_pool<1>::scoped_lock lock( pw );
|
||||||
|
|
||||||
|
int r = *pw;
|
||||||
|
*pw += dv;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void atomic_increment( int * pw )
|
||||||
|
{
|
||||||
|
spinlock_pool<1>::scoped_lock lock( pw );
|
||||||
|
++*pw;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int atomic_conditional_increment( int * pw )
|
||||||
|
{
|
||||||
|
spinlock_pool<1>::scoped_lock lock( pw );
|
||||||
|
|
||||||
|
int rv = *pw;
|
||||||
|
if( rv != 0 ) ++*pw;
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
class sp_counted_base
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
sp_counted_base( sp_counted_base const & );
|
||||||
|
sp_counted_base & operator= ( sp_counted_base const & );
|
||||||
|
|
||||||
|
int use_count_; // #shared
|
||||||
|
int weak_count_; // #weak + (#shared != 0)
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~sp_counted_base() // nothrow
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// dispose() is called when use_count_ drops to zero, to release
|
||||||
|
// the resources managed by *this.
|
||||||
|
|
||||||
|
virtual void dispose() = 0; // nothrow
|
||||||
|
|
||||||
|
// destroy() is called when weak_count_ drops to zero.
|
||||||
|
|
||||||
|
virtual void destroy() // nothrow
|
||||||
|
{
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||||
|
|
||||||
|
void add_ref_copy()
|
||||||
|
{
|
||||||
|
atomic_increment( &use_count_ );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool add_ref_lock() // true on success
|
||||||
|
{
|
||||||
|
return atomic_conditional_increment( &use_count_ ) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void release() // nothrow
|
||||||
|
{
|
||||||
|
if( atomic_exchange_and_add( &use_count_, -1 ) == 1 )
|
||||||
|
{
|
||||||
|
dispose();
|
||||||
|
weak_release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void weak_add_ref() // nothrow
|
||||||
|
{
|
||||||
|
atomic_increment( &weak_count_ );
|
||||||
|
}
|
||||||
|
|
||||||
|
void weak_release() // nothrow
|
||||||
|
{
|
||||||
|
if( atomic_exchange_and_add( &weak_count_, -1 ) == 1 )
|
||||||
|
{
|
||||||
|
destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
long use_count() const // nothrow
|
||||||
|
{
|
||||||
|
spinlock_pool<1>::scoped_lock lock( &use_count_ );
|
||||||
|
return use_count_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED
|
47
include/boost/detail/spinlock.hpp
Normal file
47
include/boost/detail/spinlock.hpp
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
#ifndef BOOST_DETAIL_SPINLOCK_HPP_INCLUDED
|
||||||
|
#define BOOST_DETAIL_SPINLOCK_HPP_INCLUDED
|
||||||
|
|
||||||
|
// MS compatible compilers support #pragma once
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||||
|
# pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
// boost/detail/spinlock.hpp
|
||||||
|
//
|
||||||
|
// Copyright (c) 2008 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
// struct spinlock
|
||||||
|
// {
|
||||||
|
// void lock();
|
||||||
|
// bool try_lock();
|
||||||
|
// void unlock();
|
||||||
|
//
|
||||||
|
// class scoped_lock;
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// #define BOOST_DETAIL_SPINLOCK_INIT <unspecified>
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
|
||||||
|
#if defined(__GNUC__) && defined( __arm__ )
|
||||||
|
# include <boost/detail/spinlock_gcc_arm.hpp>
|
||||||
|
#elif defined(__GNUC__) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 )
|
||||||
|
# include <boost/detail/spinlock_sync.hpp>
|
||||||
|
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
|
||||||
|
# include <boost/detail/spinlock_w32.hpp>
|
||||||
|
#elif defined(BOOST_HAS_PTHREADS)
|
||||||
|
# include <boost/detail/spinlock_pt.hpp>
|
||||||
|
#elif !defined(BOOST_HAS_THREADS)
|
||||||
|
# include <boost/detail/spinlock_nt.hpp>
|
||||||
|
#else
|
||||||
|
# error Unrecognized threading platform
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_DETAIL_SPINLOCK_HPP_INCLUDED
|
85
include/boost/detail/spinlock_gcc_arm.hpp
Normal file
85
include/boost/detail/spinlock_gcc_arm.hpp
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
#ifndef BOOST_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
|
||||||
|
#define BOOST_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
|
||||||
|
|
||||||
|
//
|
||||||
|
// Copyright (c) 2008 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/detail/yield_k.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
class spinlock
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
int v_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
bool try_lock()
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
|
||||||
|
__asm__ __volatile__(
|
||||||
|
"swp %0, %1, [%2]":
|
||||||
|
"=&r"( r ): // outputs
|
||||||
|
"r"( 1 ), "r"( &v_ ): // inputs
|
||||||
|
"memory", "cc" );
|
||||||
|
|
||||||
|
return r == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lock()
|
||||||
|
{
|
||||||
|
for( unsigned k = 0; !try_lock(); ++k )
|
||||||
|
{
|
||||||
|
boost::detail::yield( k );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void unlock()
|
||||||
|
{
|
||||||
|
__asm__ __volatile__( "" ::: "memory" );
|
||||||
|
*const_cast< int volatile* >( &v_ ) = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
class scoped_lock
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
spinlock & sp_;
|
||||||
|
|
||||||
|
scoped_lock( scoped_lock const & );
|
||||||
|
scoped_lock & operator=( scoped_lock const & );
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
explicit scoped_lock( spinlock & sp ): sp_( sp )
|
||||||
|
{
|
||||||
|
sp.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
~scoped_lock()
|
||||||
|
{
|
||||||
|
sp_.unlock();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#define BOOST_DETAIL_SPINLOCK_INIT {0}
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
|
89
include/boost/detail/spinlock_nt.hpp
Normal file
89
include/boost/detail/spinlock_nt.hpp
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
#ifndef BOOST_DETAIL_SPINLOCK_NT_HPP_INCLUDED
|
||||||
|
#define BOOST_DETAIL_SPINLOCK_NT_HPP_INCLUDED
|
||||||
|
|
||||||
|
// MS compatible compilers support #pragma once
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||||
|
# pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
// Copyright (c) 2008 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/assert.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
class spinlock
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
bool locked_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
inline bool try_lock()
|
||||||
|
{
|
||||||
|
if( locked_ )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
locked_ = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void lock()
|
||||||
|
{
|
||||||
|
BOOST_ASSERT( !locked_ );
|
||||||
|
locked_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void unlock()
|
||||||
|
{
|
||||||
|
BOOST_ASSERT( locked_ );
|
||||||
|
locked_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
class scoped_lock
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
spinlock & sp_;
|
||||||
|
|
||||||
|
scoped_lock( scoped_lock const & );
|
||||||
|
scoped_lock & operator=( scoped_lock const & );
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
explicit scoped_lock( spinlock & sp ): sp_( sp )
|
||||||
|
{
|
||||||
|
sp.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
~scoped_lock()
|
||||||
|
{
|
||||||
|
sp_.unlock();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#define BOOST_DETAIL_SPINLOCK_INIT { false }
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_DETAIL_SPINLOCK_NT_HPP_INCLUDED
|
85
include/boost/detail/spinlock_pool.hpp
Normal file
85
include/boost/detail/spinlock_pool.hpp
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
#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/detail/spinlock.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template< int I > class spinlock_pool
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
static spinlock pool_[ 41 ];
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
static spinlock & spinlock_for( void const * pv )
|
||||||
|
{
|
||||||
|
size_t i = reinterpret_cast< size_t >( pv ) % 41;
|
||||||
|
return pool_[ i ];
|
||||||
|
}
|
||||||
|
|
||||||
|
class scoped_lock
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
spinlock & sp_;
|
||||||
|
|
||||||
|
scoped_lock( scoped_lock const & );
|
||||||
|
scoped_lock & operator=( scoped_lock const & );
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
explicit scoped_lock( void const * pv ): sp_( spinlock_for( pv ) )
|
||||||
|
{
|
||||||
|
sp_.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
~scoped_lock()
|
||||||
|
{
|
||||||
|
sp_.unlock();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template< int I > spinlock spinlock_pool< I >::pool_[ 41 ] =
|
||||||
|
{
|
||||||
|
BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
|
||||||
|
BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
|
||||||
|
BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
|
||||||
|
BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
|
||||||
|
BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
|
||||||
|
BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
|
||||||
|
BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
|
||||||
|
BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
|
||||||
|
BOOST_DETAIL_SPINLOCK_INIT
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_DETAIL_SPINLOCK_POOL_HPP_INCLUDED
|
79
include/boost/detail/spinlock_pt.hpp
Normal file
79
include/boost/detail/spinlock_pt.hpp
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
#ifndef BOOST_DETAIL_SPINLOCK_PT_HPP_INCLUDED
|
||||||
|
#define BOOST_DETAIL_SPINLOCK_PT_HPP_INCLUDED
|
||||||
|
|
||||||
|
// MS compatible compilers support #pragma once
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||||
|
# pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
// Copyright (c) 2008 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
class spinlock
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
pthread_mutex_t v_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
bool try_lock()
|
||||||
|
{
|
||||||
|
return pthread_mutex_trylock( &v_ ) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lock()
|
||||||
|
{
|
||||||
|
pthread_mutex_lock( &v_ );
|
||||||
|
}
|
||||||
|
|
||||||
|
void unlock()
|
||||||
|
{
|
||||||
|
pthread_mutex_unlock( &v_ );
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
class scoped_lock
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
spinlock & sp_;
|
||||||
|
|
||||||
|
scoped_lock( scoped_lock const & );
|
||||||
|
scoped_lock & operator=( scoped_lock const & );
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
explicit scoped_lock( spinlock & sp ): sp_( sp )
|
||||||
|
{
|
||||||
|
sp.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
~scoped_lock()
|
||||||
|
{
|
||||||
|
sp_.unlock();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#define BOOST_DETAIL_SPINLOCK_INIT { PTHREAD_MUTEX_INITIALIZER }
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_DETAIL_SPINLOCK_PT_HPP_INCLUDED
|
83
include/boost/detail/spinlock_sync.hpp
Normal file
83
include/boost/detail/spinlock_sync.hpp
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
#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>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
class spinlock
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
int v_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
bool try_lock()
|
||||||
|
{
|
||||||
|
int r = __sync_lock_test_and_set( &v_, 1 );
|
||||||
|
return r == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lock()
|
||||||
|
{
|
||||||
|
for( unsigned k = 0; !try_lock(); ++k )
|
||||||
|
{
|
||||||
|
boost::detail::yield( k );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void unlock()
|
||||||
|
{
|
||||||
|
__sync_lock_release( &v_ );
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
class scoped_lock
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
spinlock & sp_;
|
||||||
|
|
||||||
|
scoped_lock( scoped_lock const & );
|
||||||
|
scoped_lock & operator=( scoped_lock const & );
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
explicit scoped_lock( spinlock & sp ): sp_( sp )
|
||||||
|
{
|
||||||
|
sp.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
~scoped_lock()
|
||||||
|
{
|
||||||
|
sp_.unlock();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#define BOOST_DETAIL_SPINLOCK_INIT {0}
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_DETAIL_SPINLOCK_SYNC_HPP_INCLUDED
|
113
include/boost/detail/spinlock_w32.hpp
Normal file
113
include/boost/detail/spinlock_w32.hpp
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
#ifndef BOOST_DETAIL_SPINLOCK_W32_HPP_INCLUDED
|
||||||
|
#define BOOST_DETAIL_SPINLOCK_W32_HPP_INCLUDED
|
||||||
|
|
||||||
|
// MS compatible compilers support #pragma once
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||||
|
# pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
// Copyright (c) 2008 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/detail/interlocked.hpp>
|
||||||
|
#include <boost/detail/yield_k.hpp>
|
||||||
|
|
||||||
|
// BOOST_COMPILER_FENCE
|
||||||
|
|
||||||
|
#if defined(__INTEL_COMPILER)
|
||||||
|
|
||||||
|
#define BOOST_COMPILER_FENCE __memory_barrier();
|
||||||
|
|
||||||
|
#elif defined( _MSC_VER ) && _MSC_VER >= 1310
|
||||||
|
|
||||||
|
extern "C" void _ReadWriteBarrier();
|
||||||
|
#pragma intrinsic( _ReadWriteBarrier )
|
||||||
|
|
||||||
|
#define BOOST_COMPILER_FENCE _ReadWriteBarrier();
|
||||||
|
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
|
||||||
|
#define BOOST_COMPILER_FENCE __asm__ __volatile__( "" ::: "memory" );
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define BOOST_COMPILER_FENCE
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
class spinlock
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
long v_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
bool try_lock()
|
||||||
|
{
|
||||||
|
long r = BOOST_INTERLOCKED_EXCHANGE( &v_, 1 );
|
||||||
|
|
||||||
|
BOOST_COMPILER_FENCE
|
||||||
|
|
||||||
|
return r == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lock()
|
||||||
|
{
|
||||||
|
for( unsigned k = 0; !try_lock(); ++k )
|
||||||
|
{
|
||||||
|
boost::detail::yield( k );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void unlock()
|
||||||
|
{
|
||||||
|
BOOST_COMPILER_FENCE
|
||||||
|
*const_cast< long volatile* >( &v_ ) = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
class scoped_lock
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
spinlock & sp_;
|
||||||
|
|
||||||
|
scoped_lock( scoped_lock const & );
|
||||||
|
scoped_lock & operator=( scoped_lock const & );
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
explicit scoped_lock( spinlock & sp ): sp_( sp )
|
||||||
|
{
|
||||||
|
sp.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
~scoped_lock()
|
||||||
|
{
|
||||||
|
sp_.unlock();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#define BOOST_DETAIL_SPINLOCK_INIT {0}
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_DETAIL_SPINLOCK_W32_HPP_INCLUDED
|
145
include/boost/detail/yield_k.hpp
Normal file
145
include/boost/detail/yield_k.hpp
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
#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
|
||||||
|
{
|
||||||
|
struct timespec rqtp = { 0 };
|
||||||
|
|
||||||
|
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
|
@ -46,6 +46,9 @@ private:
|
|||||||
|
|
||||||
typedef scoped_array<T> this_type;
|
typedef scoped_array<T> this_type;
|
||||||
|
|
||||||
|
void operator==( scoped_array const& ) const;
|
||||||
|
void operator!=( scoped_array const& ) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef T element_type;
|
typedef T element_type;
|
||||||
|
@ -47,6 +47,9 @@ private:
|
|||||||
|
|
||||||
typedef scoped_ptr<T> this_type;
|
typedef scoped_ptr<T> this_type;
|
||||||
|
|
||||||
|
void operator==( scoped_ptr const& ) const;
|
||||||
|
void operator!=( scoped_ptr const& ) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef T element_type;
|
typedef T element_type;
|
||||||
|
@ -31,7 +31,14 @@
|
|||||||
#include <algorithm> // for std::swap
|
#include <algorithm> // for std::swap
|
||||||
#include <functional> // for std::less
|
#include <functional> // for std::less
|
||||||
#include <typeinfo> // for std::bad_cast
|
#include <typeinfo> // for std::bad_cast
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_IOSTREAM)
|
||||||
|
#if !defined(BOOST_NO_IOSFWD)
|
||||||
#include <iosfwd> // for std::basic_ostream
|
#include <iosfwd> // for std::basic_ostream
|
||||||
|
#else
|
||||||
|
#include <ostream>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef BOOST_MSVC // moved here to work around VC++ compiler crash
|
#ifdef BOOST_MSVC // moved here to work around VC++ compiler crash
|
||||||
# pragma warning(push)
|
# pragma warning(push)
|
||||||
@ -207,6 +214,15 @@ public:
|
|||||||
px = r.px;
|
px = r.px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class Y>
|
||||||
|
shared_ptr( weak_ptr<Y> const & r, boost::detail::sp_nothrow_tag ): px( 0 ), pn( r.pn, boost::detail::sp_nothrow_tag() ) // never throws
|
||||||
|
{
|
||||||
|
if( !pn.empty() )
|
||||||
|
{
|
||||||
|
px = r.px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template<class Y>
|
template<class Y>
|
||||||
shared_ptr(shared_ptr<Y> const & r): px(r.px), pn(r.pn) // never throws
|
shared_ptr(shared_ptr<Y> const & r): px(r.px), pn(r.pn) // never throws
|
||||||
{
|
{
|
||||||
@ -555,6 +571,8 @@ template<class T> inline T * get_pointer(shared_ptr<T> const & p)
|
|||||||
|
|
||||||
// operator<<
|
// operator<<
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_IOSTREAM)
|
||||||
|
|
||||||
#if defined(__GNUC__) && (__GNUC__ < 3)
|
#if defined(__GNUC__) && (__GNUC__ < 3)
|
||||||
|
|
||||||
template<class Y> std::ostream & operator<< (std::ostream & os, shared_ptr<Y> const & p)
|
template<class Y> std::ostream & operator<< (std::ostream & os, shared_ptr<Y> const & p)
|
||||||
@ -584,6 +602,8 @@ template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::
|
|||||||
|
|
||||||
#endif // __GNUC__ < 3
|
#endif // __GNUC__ < 3
|
||||||
|
|
||||||
|
#endif // !defined(BOOST_NO_IOSTREAM)
|
||||||
|
|
||||||
// get_deleter
|
// get_deleter
|
||||||
|
|
||||||
#if ( defined(__GNUC__) && BOOST_WORKAROUND(__GNUC__, < 3) ) || \
|
#if ( defined(__GNUC__) && BOOST_WORKAROUND(__GNUC__, < 3) ) || \
|
||||||
|
@ -93,31 +93,7 @@ public:
|
|||||||
|
|
||||||
shared_ptr<T> lock() const // never throws
|
shared_ptr<T> lock() const // never throws
|
||||||
{
|
{
|
||||||
#if defined(BOOST_HAS_THREADS)
|
return shared_ptr<element_type>( *this, boost::detail::sp_nothrow_tag() );
|
||||||
|
|
||||||
// optimization: avoid throw overhead
|
|
||||||
if(expired())
|
|
||||||
{
|
|
||||||
return shared_ptr<element_type>();
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return shared_ptr<element_type>(*this);
|
|
||||||
}
|
|
||||||
catch(bad_weak_ptr const &)
|
|
||||||
{
|
|
||||||
// Q: how can we get here?
|
|
||||||
// A: another thread may have invalidated r after the use_count test above.
|
|
||||||
return shared_ptr<element_type>();
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
// optimization: avoid try/catch overhead when single threaded
|
|
||||||
return expired()? shared_ptr<element_type>(): shared_ptr<element_type>(*this);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
long use_count() const // never throws
|
long use_count() const // never throws
|
||||||
|
@ -373,8 +373,8 @@ q = p;
|
|||||||
<pre>long use_count() const; // never throws</pre>
|
<pre>long use_count() const; // never throws</pre>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<p><b>Returns:</b> the number of <b>shared_ptr</b> objects, <STRONG>*this</STRONG> included,
|
<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
|
that <i>share ownership</i> with <b>*this</b>, or 0 when <STRONG>*this</STRONG>
|
||||||
value when <STRONG>*this</STRONG> is <EM>empty</EM>.</p>
|
is <EM>empty</EM>.</p>
|
||||||
<p><b>Throws:</b> nothing.</p>
|
<p><b>Throws:</b> nothing.</p>
|
||||||
<P><B>Notes:</B> <code>use_count()</code> is not necessarily efficient. Use only
|
<P><B>Notes:</B> <code>use_count()</code> is not necessarily efficient. Use only
|
||||||
for debugging and testing purposes, not for production code.</P>
|
for debugging and testing purposes, not for production code.</P>
|
||||||
@ -522,6 +522,7 @@ q = p;
|
|||||||
<P><B>Returns:</B> If <STRONG>*this</STRONG> <EM>owns</EM> a deleter <STRONG>d</STRONG>
|
<P><B>Returns:</B> If <STRONG>*this</STRONG> <EM>owns</EM> a deleter <STRONG>d</STRONG>
|
||||||
of type (cv-unqualified) <STRONG>D</STRONG>, returns <code>&d</code>;
|
of type (cv-unqualified) <STRONG>D</STRONG>, returns <code>&d</code>;
|
||||||
otherwise returns 0.</P>
|
otherwise returns 0.</P>
|
||||||
|
<P><B>Throws:</B> nothing.</P>
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
<h2><a name="example">Example</a></h2>
|
<h2><a name="example">Example</a></h2>
|
||||||
<p>See <A href="example/shared_ptr_example.cpp">shared_ptr_example.cpp</A> for a
|
<p>See <A href="example/shared_ptr_example.cpp">shared_ptr_example.cpp</A> for a
|
||||||
@ -709,8 +710,8 @@ int * p = a.release();
|
|||||||
<p>
|
<p>
|
||||||
$Date$</p>
|
$Date$</p>
|
||||||
<p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
|
<p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
|
||||||
Copyright 2002-2005 Peter Dimov. Distributed under the Boost Software License, Version
|
Copyright 2002-2005 Peter Dimov. Distributed under the Boost Software License,
|
||||||
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or
|
Version 1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A>
|
||||||
copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
|
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>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -33,5 +33,14 @@ import testing ;
|
|||||||
[ run shared_ptr_move_test.cpp ]
|
[ run shared_ptr_move_test.cpp ]
|
||||||
[ compile-fail shared_ptr_pv_fail.cpp ]
|
[ compile-fail shared_ptr_pv_fail.cpp ]
|
||||||
[ run sp_unary_addr_test.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 ]
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
136
test/esft_regtest.cpp
Normal file
136
test/esft_regtest.cpp
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
//
|
||||||
|
// 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>
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
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 );
|
||||||
|
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
27
test/scoped_array_eq_fail.cpp
Normal file
27
test/scoped_array_eq_fail.cpp
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#include <boost/config.hpp>
|
||||||
|
|
||||||
|
#if defined(BOOST_MSVC)
|
||||||
|
#pragma warning(disable: 4786) // identifier truncated in debug info
|
||||||
|
#pragma warning(disable: 4710) // function not inlined
|
||||||
|
#pragma warning(disable: 4711) // function selected for automatic inline expansion
|
||||||
|
#pragma warning(disable: 4514) // unreferenced inline removed
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
// scoped_array_eq_fail.cpp - a negative test for "p == q"
|
||||||
|
//
|
||||||
|
// Copyright (c) 2008 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See
|
||||||
|
// accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/scoped_array.hpp>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
boost::scoped_array<int> p, q;
|
||||||
|
p == q; // must fail
|
||||||
|
return 0;
|
||||||
|
}
|
27
test/scoped_ptr_eq_fail.cpp
Normal file
27
test/scoped_ptr_eq_fail.cpp
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#include <boost/config.hpp>
|
||||||
|
|
||||||
|
#if defined(BOOST_MSVC)
|
||||||
|
#pragma warning(disable: 4786) // identifier truncated in debug info
|
||||||
|
#pragma warning(disable: 4710) // function not inlined
|
||||||
|
#pragma warning(disable: 4711) // function selected for automatic inline expansion
|
||||||
|
#pragma warning(disable: 4514) // unreferenced inline removed
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
// scoped_ptr_eq_fail.cpp - a negative test for "p == q"
|
||||||
|
//
|
||||||
|
// Copyright (c) 2008 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See
|
||||||
|
// accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/scoped_ptr.hpp>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
boost::scoped_ptr<int> p, q;
|
||||||
|
p == q; // must fail
|
||||||
|
return 0;
|
||||||
|
}
|
@ -133,7 +133,8 @@ void test3()
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
boost::shared_ptr<V> r = v2.shared_from_this();
|
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 &)
|
catch(boost::bad_weak_ptr const &)
|
||||||
{
|
{
|
||||||
|
@ -62,6 +62,7 @@ void default_constructor()
|
|||||||
BOOST_TEST(pi? false: true);
|
BOOST_TEST(pi? false: true);
|
||||||
BOOST_TEST(!pi);
|
BOOST_TEST(!pi);
|
||||||
BOOST_TEST(pi.get() == 0);
|
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? false: true);
|
||||||
BOOST_TEST(!pv);
|
BOOST_TEST(!pv);
|
||||||
BOOST_TEST(pv.get() == 0);
|
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? false: true);
|
||||||
BOOST_TEST(!px);
|
BOOST_TEST(!px);
|
||||||
BOOST_TEST(px.get() == 0);
|
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? false: true);
|
||||||
BOOST_TEST(!pi);
|
BOOST_TEST(!pi);
|
||||||
BOOST_TEST(pi.get() == 0);
|
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? false: true);
|
||||||
BOOST_TEST(!pi);
|
BOOST_TEST(!pi);
|
||||||
BOOST_TEST(pi.get() == 0);
|
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? false: true);
|
||||||
BOOST_TEST(!pi);
|
BOOST_TEST(!pi);
|
||||||
BOOST_TEST(pi.get() == 0);
|
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? false: true);
|
||||||
BOOST_TEST(!px);
|
BOOST_TEST(!px);
|
||||||
BOOST_TEST(px.get() == 0);
|
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? false: true);
|
||||||
BOOST_TEST(!px);
|
BOOST_TEST(!px);
|
||||||
BOOST_TEST(px.get() == 0);
|
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? false: true);
|
||||||
BOOST_TEST(!px);
|
BOOST_TEST(!px);
|
||||||
BOOST_TEST(px.get() == 0);
|
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? false: true);
|
||||||
BOOST_TEST(!px);
|
BOOST_TEST(!px);
|
||||||
BOOST_TEST(px.get() == 0);
|
BOOST_TEST(px.get() == 0);
|
||||||
|
BOOST_TEST(px.use_count() == 0);
|
||||||
BOOST_TEST(X::instances == 0);
|
BOOST_TEST(X::instances == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1624,6 +1634,7 @@ void plain_reset()
|
|||||||
BOOST_TEST(pv? false: true);
|
BOOST_TEST(pv? false: true);
|
||||||
BOOST_TEST(!pv);
|
BOOST_TEST(!pv);
|
||||||
BOOST_TEST(pv.get() == 0);
|
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? false: true);
|
||||||
BOOST_TEST(!pv);
|
BOOST_TEST(!pv);
|
||||||
BOOST_TEST(pv.get() == 0);
|
BOOST_TEST(pv.get() == 0);
|
||||||
|
BOOST_TEST(pv.use_count() == 0);
|
||||||
BOOST_TEST(X::instances == 0);
|
BOOST_TEST(X::instances == 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
30
test/spinlock_pool_test.cpp
Normal file
30
test/spinlock_pool_test.cpp
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
//
|
||||||
|
// spinlock_pool_test.cpp
|
||||||
|
//
|
||||||
|
// Copyright 2008 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/detail/spinlock_pool.hpp>
|
||||||
|
|
||||||
|
// Sanity check only
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
int x = 0;
|
||||||
|
|
||||||
|
{
|
||||||
|
boost::detail::spinlock_pool<0>::scoped_lock lock( &x );
|
||||||
|
++x;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
boost::detail::spinlock_pool<1>::scoped_lock lock( &x );
|
||||||
|
boost::detail::spinlock_pool<2>::scoped_lock lock2( &x );
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
31
test/spinlock_test.cpp
Normal file
31
test/spinlock_test.cpp
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
//
|
||||||
|
// spinlock_test.cpp
|
||||||
|
//
|
||||||
|
// Copyright 2008 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/detail/spinlock.hpp>
|
||||||
|
|
||||||
|
// Sanity check only
|
||||||
|
|
||||||
|
static boost::detail::spinlock sp = BOOST_DETAIL_SPINLOCK_INIT;
|
||||||
|
static boost::detail::spinlock sp2 = BOOST_DETAIL_SPINLOCK_INIT;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
sp.lock();
|
||||||
|
sp2.lock();
|
||||||
|
sp.unlock();
|
||||||
|
sp2.unlock();
|
||||||
|
|
||||||
|
{
|
||||||
|
boost::detail::spinlock::scoped_lock lock( sp );
|
||||||
|
boost::detail::spinlock::scoped_lock lock2( sp2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
46
test/spinlock_try_test.cpp
Normal file
46
test/spinlock_try_test.cpp
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
//
|
||||||
|
// spinlock_try_test.cpp
|
||||||
|
//
|
||||||
|
// Copyright 2008 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/detail/spinlock.hpp>
|
||||||
|
#include <boost/detail/lightweight_test.hpp>
|
||||||
|
|
||||||
|
// Sanity check only
|
||||||
|
|
||||||
|
static boost::detail::spinlock sp = BOOST_DETAIL_SPINLOCK_INIT;
|
||||||
|
static boost::detail::spinlock sp2 = BOOST_DETAIL_SPINLOCK_INIT;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
BOOST_TEST( sp.try_lock() );
|
||||||
|
BOOST_TEST( !sp.try_lock() );
|
||||||
|
BOOST_TEST( sp2.try_lock() );
|
||||||
|
BOOST_TEST( !sp.try_lock() );
|
||||||
|
BOOST_TEST( !sp2.try_lock() );
|
||||||
|
sp.unlock();
|
||||||
|
sp2.unlock();
|
||||||
|
|
||||||
|
sp.lock();
|
||||||
|
BOOST_TEST( !sp.try_lock() );
|
||||||
|
sp2.lock();
|
||||||
|
BOOST_TEST( !sp.try_lock() );
|
||||||
|
BOOST_TEST( !sp2.try_lock() );
|
||||||
|
sp.unlock();
|
||||||
|
sp2.unlock();
|
||||||
|
|
||||||
|
{
|
||||||
|
boost::detail::spinlock::scoped_lock lock( sp );
|
||||||
|
BOOST_TEST( !sp.try_lock() );
|
||||||
|
boost::detail::spinlock::scoped_lock lock2( sp2 );
|
||||||
|
BOOST_TEST( !sp.try_lock() );
|
||||||
|
BOOST_TEST( !sp2.try_lock() );
|
||||||
|
}
|
||||||
|
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
23
test/yield_k_test.cpp
Normal file
23
test/yield_k_test.cpp
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
//
|
||||||
|
// yield_k_test.cpp
|
||||||
|
//
|
||||||
|
// Copyright 2008 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/detail/yield_k.hpp>
|
||||||
|
|
||||||
|
// Sanity check only
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
for( unsigned k = 0; k < 256; ++k )
|
||||||
|
{
|
||||||
|
boost::detail::yield( k );
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Reference in New Issue
Block a user