Merged revision(s) 81149, 81159, 81171, 81174, 81219-81220, 81222-81224, 81226, 81229-81239, 81242, 81253, 81257-81262, 81265-81268, 81271-81272, 81275-81277, 81299-81300 from trunk:

Implement shared_ptr<X[]>, weak_ptr<X[]>. Refs #1113.
........
Fix shared_ptr<T[]> EDG issues.
........
Disable make_shared<T> overloads when T is Q[].
........
Add catch(...) clauses to sp_array_test.cpp.
........
Add allocate_shared and make_shared for shared_ptr arrays of runtime size. Fulfills need for allocate_shared_array and make_shared_array. 
........
Update Jamfile.v2 to run make_shared array tests and allocate_shared array tests.
........
Fix g++ issues.
........
Add specialization of sp_if_not_array<T[N]>.
........
Rename make_shared.hpp to make_shared_object.hpp, include from make_shared.hpp.
........
Add make_shared_array_args_test.cpp.
........
Add support for make_shared of array of arrays. Correctly destroy elements and construct elements for the variadic template constructor variants.
........
Fix sp_convertible<T const[], T const[]>.
........
Update smart_ptr/detail/array_helper to have create and create_noinit for non-array case.
........
Rename sp_convertible_test.cpp to shared_ptr_convertible_test.cpp.
........
Don't treat array_helper create and create_noinit for array types as a special case.
........
Add sp_convertible_test.cpp.
........
Fix array_helper (create_noinit and use of args...).
........
Update allocate_shared and make_shared to treat multidimensional array as single dimension. Remove detail array_helper. Add detail array traits. Update tests. 
........
Simplify array_deleter interface
........
Add missing semicolon.
........
Fix typo.
........
Add tests for variadic template constructors overload of array forms of make_shared and allocate_shared for multidimensional arrays and up to 9 constructor arguments.
........
Add support for shared_ptr<X[N>.
........
Add C++11 initializer list support for make_shared and allocate_shared array forms.

........
Clean up code in allocate_shared_array.hpp and make_shared_array.hpp
........
Change make_shared and allocate_shared array form semantics with initializer lists overload that takes no size.
........
Disable make_shared for arrays when the compiler doesn't support partial specialization or SFINAE.
........
For allocate_shared and make_shared: Separate test case that g++ does support yet. Remove macros testing for no partial specialization in traits. Add additional traits.
........
Actually remove test cases from make_shared_array_create_test.cpp and allocate_shared_array_create_test.cpp that g++ does not handle.
........
Add overloads to support fixed size arrays, T[N], to allocate_shared (variadic) and make_shared (variadic) and make_shared_noinit.
........
Add additional overload for make_shared and allocate_shared for arrays for fixed size arrays and initializer lists.
........
Add assertion to overload of make_shared and allocate_shared for T[N] with initializer lists. Rename detail type to be more intuitive.
........
Add allocate_shared_array_args_test.cpp.
........
Keep old definition of sp_assert_convertible when BOOST_SP_NO_SP_CONVERTIBLE is set.
........
Updated shared_array to match shared_ptr. Refs #1113.
........
Add final overload of make_shared and allocate_shared (array forms) for T[][N] with C++11 initializer lists.
........
Change traits for initializer list for g++
........
Tidy long line formatting in allocate_shared_array.hpp and make_shared_array.hpp
........
Update tests for make_shared and allocate_shared array forms, for normal case, initializer lists, variadic template arguments, for arrays and fixed size arrays.
........
Update Jamfile.v2 with two new smart_ptr tests for allocate_shared and make_shared
........


[SVN r81339]
This commit is contained in:
Peter Dimov committed 2012-11-14 13:52:11 +00:00
1 parent e8103f9774
commit cb0797acf0
90 files changed
+5636 -1070

No files matched your search

+220 -43
View File
@@ -67,34 +67,129 @@ struct const_cast_tag {};
struct dynamic_cast_tag {};
struct polymorphic_cast_tag {};
template<class T> struct shared_ptr_traits
// sp_element, element_type
template< class T > struct sp_element
{
typedef T & reference;
typedef T type;
};
template<> struct shared_ptr_traits<void>
#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
template< class T > struct sp_element< T[] >
{
typedef void reference;
typedef T type;
};
template< class T, std::size_t N > struct sp_element< T[N] >
{
typedef T type;
};
#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
// sp_dereference, return type of operator*
template< class T > struct sp_dereference
{
typedef T & type;
};
template<> struct sp_dereference< void >
{
typedef void type;
};
#if !defined(BOOST_NO_CV_VOID_SPECIALIZATIONS)
template<> struct shared_ptr_traits<void const>
template<> struct sp_dereference< void const >
{
typedef void reference;
typedef void type;
};
template<> struct shared_ptr_traits<void volatile>
template<> struct sp_dereference< void volatile >
{
typedef void reference;
typedef void type;
};
template<> struct shared_ptr_traits<void const volatile>
template<> struct sp_dereference< void const volatile >
{
typedef void reference;
typedef void type;
};
#endif
#endif // !defined(BOOST_NO_CV_VOID_SPECIALIZATIONS)
#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
template< class T > struct sp_dereference< T[] >
{
typedef void type;
};
template< class T, std::size_t N > struct sp_dereference< T[N] >
{
typedef void type;
};
#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
// sp_member_access, return type of operator->
template< class T > struct sp_member_access
{
typedef T * type;
};
#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
template< class T > struct sp_member_access< T[] >
{
typedef void type;
};
template< class T, std::size_t N > struct sp_member_access< T[N] >
{
typedef void type;
};
#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
// sp_array_access, return type of operator[]
template< class T > struct sp_array_access
{
typedef void type;
};
#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
template< class T > struct sp_array_access< T[] >
{
typedef T & type;
};
template< class T, std::size_t N > struct sp_array_access< T[N] >
{
typedef T & type;
};
#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
// sp_extent, for operator[] index check
template< class T > struct sp_extent
{
enum _vt { value = 0 };
};
#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
template< class T, std::size_t N > struct sp_extent< T[N] >
{
enum _vt { value = N };
};
#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
// enable_shared_from_this support
@@ -144,6 +239,69 @@ template< class T, class R > struct sp_enable_if_auto_ptr< std::auto_ptr< T >, R
#endif
// sp_assert_convertible
template< class Y, class T > inline void sp_assert_convertible()
{
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
// static_assert( sp_convertible< Y, T >::value );
typedef char tmp[ sp_convertible< Y, T >::value? 1: -1 ];
(void)sizeof( tmp );
#else
T* p = static_cast< Y* >( 0 );
(void)p;
#endif
}
// pointer constructor helper
template< class T, class Y > inline void sp_pointer_construct( boost::shared_ptr< T > * ppx, Y * p, boost::detail::shared_count & pn )
{
boost::detail::shared_count( p ).swap( pn );
boost::detail::sp_enable_shared_from_this( ppx, p, p );
}
#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
template< class T, class Y > inline void sp_pointer_construct( boost::shared_ptr< T[] > * /*ppx*/, Y * p, boost::detail::shared_count & pn )
{
sp_assert_convertible< Y[], T[] >();
boost::detail::shared_count( p, boost::checked_array_deleter< T >() ).swap( pn );
}
template< class T, std::size_t N, class Y > inline void sp_pointer_construct( boost::shared_ptr< T[N] > * /*ppx*/, Y * p, boost::detail::shared_count & pn )
{
sp_assert_convertible< Y[N], T[N] >();
boost::detail::shared_count( p, boost::checked_array_deleter< T >() ).swap( pn );
}
#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
// deleter constructor helper
template< class T, class Y > inline void sp_deleter_construct( boost::shared_ptr< T > * ppx, Y * p )
{
boost::detail::sp_enable_shared_from_this( ppx, p, p );
}
#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
template< class T, class Y > inline void sp_deleter_construct( boost::shared_ptr< T[] > * /*ppx*/, Y * /*p*/ )
{
sp_assert_convertible< Y[], T[] >();
}
template< class T, std::size_t N, class Y > inline void sp_deleter_construct( boost::shared_ptr< T[N] > * /*ppx*/, Y * /*p*/ )
{
sp_assert_convertible< Y[N], T[N] >();
}
#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
} // namespace detail
@@ -164,19 +322,16 @@ private:
public:
typedef T element_type;
typedef T value_type;
typedef T * pointer;
typedef typename boost::detail::shared_ptr_traits<T>::reference reference;
typedef typename boost::detail::sp_element< T >::type element_type;
shared_ptr(): px(0), pn() // never throws in 1.30+
shared_ptr(): px( 0 ), pn() // never throws in 1.30+
{
}
template<class Y>
explicit shared_ptr( Y * p ): px( p ), pn( p ) // Y must be complete
explicit shared_ptr( Y * p ): px( p ), pn() // Y must be complete
{
boost::detail::sp_enable_shared_from_this( this, p, p );
boost::detail::sp_pointer_construct( this, p, pn );
}
//
@@ -185,16 +340,16 @@ public:
// shared_ptr will release p by calling d(p)
//
template<class Y, class D> shared_ptr(Y * p, D d): px(p), pn(p, d)
template<class Y, class D> shared_ptr( Y * p, D d ): px( p ), pn( p, d )
{
boost::detail::sp_enable_shared_from_this( this, p, p );
boost::detail::sp_deleter_construct( this, p );
}
// As above, but with allocator. A's copy constructor shall not throw.
template<class Y, class D, class A> shared_ptr( Y * p, D d, A a ): px( p ), pn( p, d, a )
{
boost::detail::sp_enable_shared_from_this( this, p, p );
boost::detail::sp_deleter_construct( this, p );
}
// generated copy constructor, destructor are fine...
@@ -210,8 +365,10 @@ public:
#endif
template<class Y>
explicit shared_ptr(weak_ptr<Y> const & r): pn(r.pn) // may throw
explicit shared_ptr( weak_ptr<Y> const & r ): pn( r.pn ) // may throw
{
boost::detail::sp_assert_convertible< Y, T >();
// it is now safe to copy r.px, as pn(r.pn) did not throw
px = r.px;
}
@@ -237,11 +394,12 @@ public:
#endif
: px( r.px ), pn( r.pn ) // never throws
{
boost::detail::sp_assert_convertible< Y, T >();
}
// aliasing
template< class Y >
shared_ptr( shared_ptr<Y> const & r, T * p ): px( p ), pn( r.pn ) // never throws
shared_ptr( shared_ptr<Y> const & r, element_type * p ): px( p ), pn( r.pn ) // never throws
{
}
@@ -278,9 +436,12 @@ public:
template<class Y>
explicit shared_ptr(std::auto_ptr<Y> & r): px(r.get()), pn()
{
boost::detail::sp_assert_convertible< Y, T >();
Y * tmp = r.get();
pn = boost::detail::shared_count(r);
boost::detail::sp_enable_shared_from_this( this, tmp, tmp );
boost::detail::sp_deleter_construct( this, tmp );
}
#if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
@@ -288,11 +449,15 @@ public:
template<class Ap>
explicit shared_ptr( Ap r, typename boost::detail::sp_enable_if_auto_ptr<Ap, int>::type = 0 ): px( r.get() ), pn()
{
typename Ap::element_type * tmp = r.get();
pn = boost::detail::shared_count( r );
boost::detail::sp_enable_shared_from_this( this, tmp, tmp );
}
typedef typename Ap::element_type Y;
boost::detail::sp_assert_convertible< Y, T >();
Y * tmp = r.get();
pn = boost::detail::shared_count( r );
boost::detail::sp_deleter_construct( this, tmp );
}
#endif // BOOST_NO_SFINAE, BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
@@ -301,11 +466,14 @@ public:
#if !defined( BOOST_NO_CXX11_SMART_PTR )
template< class Y, class D >
shared_ptr( std::unique_ptr< Y, D > && r): px( r.get() ), pn()
shared_ptr( std::unique_ptr< Y, D > && r ): px( r.get() ), pn()
{
Y * tmp = r.get();
boost::detail::sp_assert_convertible< Y, T >();
typename std::unique_ptr< Y, D >::pointer tmp = r.get();
pn = boost::detail::shared_count( r );
boost::detail::sp_enable_shared_from_this( this, tmp, tmp );
boost::detail::sp_deleter_construct( this, tmp );
}
#endif
@@ -347,7 +515,6 @@ public:
return *this;
}
#endif // BOOST_NO_SFINAE, BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#endif // BOOST_NO_AUTO_PTR
@@ -374,6 +541,8 @@ public:
#endif
: px( r.px ), pn() // never throws
{
boost::detail::sp_assert_convertible< Y, T >();
pn.swap( r.pn );
r.px = 0;
}
@@ -398,10 +567,10 @@ public:
this_type().swap(*this);
}
template<class Y> void reset(Y * p) // Y must be complete
template<class Y> void reset( Y * p ) // Y must be complete
{
BOOST_ASSERT(p == 0 || p != px); // catch self-reset errors
this_type(p).swap(*this);
BOOST_ASSERT( p == 0 || p != px ); // catch self-reset errors
this_type( p ).swap( *this );
}
template<class Y, class D> void reset( Y * p, D d )
@@ -414,24 +583,32 @@ public:
this_type( p, d, a ).swap( *this );
}
template<class Y> void reset( shared_ptr<Y> const & r, T * p )
template<class Y> void reset( shared_ptr<Y> const & r, element_type * p )
{
this_type( r, p ).swap( *this );
}
reference operator* () const // never throws
typename boost::detail::sp_dereference< T >::type operator* () const // never throws
{
BOOST_ASSERT(px != 0);
BOOST_ASSERT( px != 0 );
return *px;
}
T * operator-> () const // never throws
typename boost::detail::sp_member_access< T >::type operator-> () const // never throws
{
BOOST_ASSERT(px != 0);
BOOST_ASSERT( px != 0 );
return px;
}
T * get() const // never throws
typename boost::detail::sp_array_access< T >::type operator[] ( std::ptrdiff_t i ) const // never throws
{
BOOST_ASSERT( px != 0 );
BOOST_ASSERT( i >= 0 && ( i < boost::detail::sp_extent< T >::value || boost::detail::sp_extent< T >::value == 0 ) );
return px[ i ];
}
element_type * get() const // never throws
{
return px;
}
@@ -449,7 +626,7 @@ public:
return pn.use_count();
}
void swap(shared_ptr<T> & other) // never throws
void swap( shared_ptr & other ) // never throws
{
std::swap(px, other.px);
pn.swap(other.pn);
@@ -488,7 +665,7 @@ private:
#endif
T * px; // contained pointer
element_type * px; // contained pointer
boost::detail::shared_count pn; // reference counter
}; // shared_ptr