diff --git a/include/boost/detail/lwm_win32_cs.hpp b/include/boost/detail/lwm_win32_cs.hpp index 4ee0a71..8142069 100644 --- a/include/boost/detail/lwm_win32_cs.hpp +++ b/include/boost/detail/lwm_win32_cs.hpp @@ -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 &); diff --git a/include/boost/detail/shared_count.hpp b/include/boost/detail/shared_count.hpp index 2745649..8f13777 100644 --- a/include/boost/detail/shared_count.hpp +++ b/include/boost/detail/shared_count.hpp @@ -104,11 +104,18 @@ public: #endif } - template shared_count(P p, D d): pi_(0) +#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) + template shared_count( Y * p, D d ): pi_(0) +#else + template 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 diff --git a/include/boost/detail/sp_convertible.hpp b/include/boost/detail/sp_convertible.hpp new file mode 100644 index 0000000..017217b --- /dev/null +++ b/include/boost/detail/sp_convertible.hpp @@ -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 + +#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__ < 0x600 ) +# 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 +{ + typedef sp_empty type; +}; + +template<> struct sp_enable_if_convertible_impl +{ +}; + +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 diff --git a/include/boost/detail/spinlock_sync.hpp b/include/boost/detail/spinlock_sync.hpp index d602365..a752396 100644 --- a/include/boost/detail/spinlock_sync.hpp +++ b/include/boost/detail/spinlock_sync.hpp @@ -17,6 +17,10 @@ #include +#if defined( __ia64__ ) && defined( __INTEL_COMPILER ) +# include +#endif + namespace boost { diff --git a/include/boost/detail/spinlock_w32.hpp b/include/boost/detail/spinlock_w32.hpp index 76cfe8f..aa416c3 100644 --- a/include/boost/detail/spinlock_w32.hpp +++ b/include/boost/detail/spinlock_w32.hpp @@ -33,7 +33,7 @@ extern "C" void _ReadWriteBarrier(); #elif defined(__GNUC__) -#define BOOST_COMPILER_FENCE __asm__ __volatile__( "" ::: "memory" ); +#define BOOST_COMPILER_FENCE __asm__ __volatile__( "" : : : "memory" ); #else diff --git a/include/boost/detail/yield_k.hpp b/include/boost/detail/yield_k.hpp index 0d964a7..d97542d 100644 --- a/include/boost/detail/yield_k.hpp +++ b/include/boost/detail/yield_k.hpp @@ -36,7 +36,7 @@ extern "C" void _mm_pause(); #elif defined(__GNUC__) && ( defined(__i386__) || defined(__x86_64__) ) -#define BOOST_SMT_PAUSE __asm__ __volatile__( "rep; nop" ::: "memory" ); +#define BOOST_SMT_PAUSE __asm__ __volatile__( "rep; nop" : : : "memory" ); #endif diff --git a/include/boost/intrusive_ptr.hpp b/include/boost/intrusive_ptr.hpp index c4ec407..338e672 100644 --- a/include/boost/intrusive_ptr.hpp +++ b/include/boost/intrusive_ptr.hpp @@ -22,9 +22,17 @@ #include #include +#include -#include // for std::less +#include // for std::less + +#if !defined(BOOST_NO_IOSTREAM) +#if !defined(BOOST_NO_IOSFWD) #include // for std::basic_ostream +#else +#include +#endif +#endif namespace boost @@ -66,9 +74,19 @@ public: #if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES) - template intrusive_ptr(intrusive_ptr const & rhs): p_(rhs.get()) + template +#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) + + intrusive_ptr( intrusive_ptr const & rhs, typename detail::sp_enable_if_convertible::type = detail::sp_empty() ) + +#else + + intrusive_ptr( intrusive_ptr 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,11 @@ public: return *this; } + void reset() + { + this_type().swap( *this ); + } + void reset( T * rhs ) { this_type( rhs ).swap( *this ); @@ -246,7 +269,9 @@ template intrusive_ptr dynamic_pointer_cast(intrusive_ptr std::ostream & operator<< (std::ostream & os, intrusive_ptr const & p) { @@ -275,6 +300,8 @@ template std::basic_ostream & operator<< (std:: #endif // __GNUC__ < 3 +#endif // !defined(BOOST_NO_IOSTREAM) + } // namespace boost #ifdef BOOST_MSVC diff --git a/include/boost/make_shared.hpp b/include/boost/make_shared.hpp new file mode 100644 index 0000000..cc3685b --- /dev/null +++ b/include/boost/make_shared.hpp @@ -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 +#include +#include +#include +#include +#include + +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 )... ); + 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 )... ); + 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 diff --git a/include/boost/shared_ptr.hpp b/include/boost/shared_ptr.hpp index b6af46d..5a172b9 100644 --- a/include/boost/shared_ptr.hpp +++ b/include/boost/shared_ptr.hpp @@ -31,6 +31,7 @@ #include #include #include +#include #include // for std::swap #include // for std::less @@ -228,7 +229,16 @@ public: } template - shared_ptr(shared_ptr const & r): px(r.px), pn(r.pn) // never throws +#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) + + shared_ptr( shared_ptr const & r, typename detail::sp_enable_if_convertible::type = detail::sp_empty() ) + +#else + + shared_ptr( shared_ptr const & r ) + +#endif + : px( r.px ), pn( r.pn ) // never throws { } @@ -337,7 +347,16 @@ public: } template - shared_ptr( shared_ptr && r ): px( r.px ), pn() // never throws +#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) + + shared_ptr( shared_ptr && r, typename detail::sp_enable_if_convertible::type = detail::sp_empty() ) + +#else + + shared_ptr( shared_ptr && r ) + +#endif + : px( r.px ), pn() // never throws { pn.swap( r.pn ); r.px = 0; diff --git a/include/boost/weak_ptr.hpp b/include/boost/weak_ptr.hpp index 4335738..b300813 100644 --- a/include/boost/weak_ptr.hpp +++ b/include/boost/weak_ptr.hpp @@ -61,13 +61,31 @@ public: // template - weak_ptr(weak_ptr const & r): pn(r.pn) // never throws +#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) + + weak_ptr( weak_ptr const & r, typename detail::sp_enable_if_convertible::type = detail::sp_empty() ) + +#else + + weak_ptr( weak_ptr const & r ) + +#endif + : pn(r.pn) // never throws { px = r.lock().get(); } template - weak_ptr(shared_ptr const & r): px(r.px), pn(r.pn) // never throws +#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) + + weak_ptr( shared_ptr const & r, typename detail::sp_enable_if_convertible::type = detail::sp_empty() ) + +#else + + weak_ptr( shared_ptr const & r ) + +#endif + : px( r.px ), pn( r.pn ) // never throws { } diff --git a/intrusive_ptr.html b/intrusive_ptr.html index c4eb899..16097dd 100644 --- a/intrusive_ptr.html +++ b/intrusive_ptr.html @@ -62,6 +62,8 @@ intrusive_ptr & operator=(intrusive_ptr const & r); template<class Y> intrusive_ptr & operator=(intrusive_ptr<Y> const & r); intrusive_ptr & operator=(T * r); + + void reset(); void reset(T * r); T & operator*() const; // never throws @@ -148,6 +150,10 @@ intrusive_ptr & operator=(T * r);

Returns: *this.

reset

+
void reset();
+
+

Effects: Equivalent to intrusive_ptr().swap(*this).

+
void reset(T * r);

Effects: Equivalent to intrusive_ptr(r).swap(*this).

diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 7abcb6e..955b282 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -42,5 +42,10 @@ import testing ; [ run spinlock_try_test.cpp ] [ run spinlock_try_test.cpp : : : 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 ] ; } diff --git a/test/allocate_shared_test.cpp b/test/allocate_shared_test.cpp new file mode 100644 index 0000000..71ee948 --- /dev/null +++ b/test/allocate_shared_test.cpp @@ -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 +#include +#include +#include + +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() ); + + BOOST_TEST( pi.get() != 0 ); + BOOST_TEST( *pi == 0 ); + } + + { + boost::shared_ptr< int > pi = boost::allocate_shared< int >( std::allocator(), 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() ); + boost::weak_ptr 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(), 1 ); + boost::weak_ptr 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(), 1, 2 ); + boost::weak_ptr 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(), 1, 2, 3 ); + boost::weak_ptr 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(), 1, 2, 3, 4 ); + boost::weak_ptr 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(), 1, 2, 3, 4, 5 ); + boost::weak_ptr 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(), 1, 2, 3, 4, 5, 6 ); + boost::weak_ptr 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(), 1, 2, 3, 4, 5, 6, 7 ); + boost::weak_ptr 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(), 1, 2, 3, 4, 5, 6, 7, 8 ); + boost::weak_ptr 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(), 1, 2, 3, 4, 5, 6, 7, 8, 9 ); + boost::weak_ptr 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(); +} diff --git a/test/ip_convertible_test.cpp b/test/ip_convertible_test.cpp new file mode 100644 index 0000000..081f7b0 --- /dev/null +++ b/test/ip_convertible_test.cpp @@ -0,0 +1,54 @@ +#include + +// 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 +#include + +// + +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 ) +{ + return 1; +} + +int f( boost::intrusive_ptr ) +{ + return 2; +} + +int main() +{ + BOOST_TEST( 1 == f( boost::intrusive_ptr() ) ); + return boost::report_errors(); +} diff --git a/test/make_shared_test.cpp b/test/make_shared_test.cpp new file mode 100644 index 0000000..9930e31 --- /dev/null +++ b/test/make_shared_test.cpp @@ -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 +#include +#include +#include + +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 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 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 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 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 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 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 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 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 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 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(); +} diff --git a/test/smart_ptr_test.cpp b/test/smart_ptr_test.cpp index 0c29c9c..8832deb 100644 --- a/test/smart_ptr_test.cpp +++ b/test/smart_ptr_test.cpp @@ -196,6 +196,10 @@ void test() BOOST_TEST( cp.use_count() == 3 ); BOOST_TEST( *cp == 87654 ); +#if defined( BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP ) + using boost::swap; +#endif + boost::shared_ptr cp4; swap( cp2, cp4 ); BOOST_TEST( cp4.use_count() == 3 ); diff --git a/test/sp_convertible_test.cpp b/test/sp_convertible_test.cpp new file mode 100644 index 0000000..7f49e1f --- /dev/null +++ b/test/sp_convertible_test.cpp @@ -0,0 +1,71 @@ +#include + +// 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 +#include + +// + +class incomplete; + +struct X +{ +}; + +struct Y +{ +}; + +struct Z: public X +{ +}; + +int f( boost::shared_ptr ) +{ + return 1; +} + +int f( boost::shared_ptr ) +{ + return 2; +} + +int f( boost::shared_ptr ) +{ + return 3; +} + +int g( boost::shared_ptr ) +{ + return 4; +} + +int g( boost::shared_ptr ) +{ + return 5; +} + +int g( boost::shared_ptr ) +{ + return 6; +} + +int main() +{ + boost::shared_ptr p1; + BOOST_TEST( 1 == f( p1 ) ); + BOOST_TEST( 1 == f( boost::shared_ptr() ) ); + + boost::shared_ptr p2; + BOOST_TEST( 4 == g( p2 ) ); + BOOST_TEST( 4 == g( boost::shared_ptr() ) ); + + return boost::report_errors(); +} diff --git a/test/sp_unary_addr_test.cpp b/test/sp_unary_addr_test.cpp index 4522640..a4007a2 100644 --- a/test/sp_unary_addr_test.cpp +++ b/test/sp_unary_addr_test.cpp @@ -49,6 +49,9 @@ int main() BOOST_TEST( q != 0 && q->data == 17041 ); } +#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, < 1300 ) +#else + { boost::shared_ptr p( &x, deleter(), std::allocator() ); @@ -58,5 +61,7 @@ int main() BOOST_TEST( q != 0 && q->data == 17041 ); } +#endif + return boost::report_errors(); } diff --git a/test/wp_convertible_test.cpp b/test/wp_convertible_test.cpp new file mode 100644 index 0000000..cceacda --- /dev/null +++ b/test/wp_convertible_test.cpp @@ -0,0 +1,68 @@ +#include + +// 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 +#include + +// + +class incomplete; + +struct X +{ +}; + +struct Y +{ +}; + +struct Z: public X +{ +}; + +int f( boost::weak_ptr ) +{ + return 1; +} + +int f( boost::weak_ptr ) +{ + return 2; +} + +int f( boost::weak_ptr ) +{ + return 3; +} + +int g( boost::weak_ptr ) +{ + return 4; +} + +int g( boost::weak_ptr ) +{ + return 5; +} + +int g( boost::weak_ptr ) +{ + return 6; +} + +int main() +{ + BOOST_TEST( 1 == f( boost::weak_ptr() ) ); + BOOST_TEST( 1 == f( boost::shared_ptr() ) ); + BOOST_TEST( 4 == g( boost::weak_ptr() ) ); + BOOST_TEST( 4 == g( boost::shared_ptr() ) ); + + return boost::report_errors(); +}