mirror of
https://github.com/boostorg/smart_ptr.git
synced 2025-10-04 19:51:02 +02:00
Compare commits
87 Commits
boost-1.41
...
boost-1.55
Author | SHA1 | Date | |
---|---|---|---|
|
9b964f6881 | ||
|
be06392771 | ||
|
fc20a29c99 | ||
|
6eefc6bf81 | ||
|
9355404d10 | ||
|
240c66e633 | ||
|
e497aec58a | ||
|
579b347267 | ||
|
3178d38137 | ||
|
e39fcad839 | ||
|
de6dc3a26e | ||
|
72095a4804 | ||
|
dcc1713c59 | ||
|
f6d5257597 | ||
|
d3a549e93a | ||
|
c55ffa1cab | ||
|
049d0698b7 | ||
|
5ba3312519 | ||
|
6a218a5ef2 | ||
|
c14369aac9 | ||
|
7ab4f6ce92 | ||
|
c28bef2e9b | ||
|
5fc6fe474b | ||
|
d42ce87557 | ||
|
b306c9751f | ||
|
c03bfd0b4d | ||
|
08e5894510 | ||
|
3551d17566 | ||
|
32fe0b8f26 | ||
|
88c2baa20b | ||
|
ea55019260 | ||
|
2346941b15 | ||
|
c7b6e56b30 | ||
|
215771c83d | ||
|
2805ae9362 | ||
|
cb0797acf0 | ||
|
e8103f9774 | ||
|
71eb435412 | ||
|
4a2dad1574 | ||
|
babc72757d | ||
|
c19cbc1892 | ||
|
d065e4d971 | ||
|
777b86a661 | ||
|
aae5440854 | ||
|
227d2e3255 | ||
|
8bf183b373 | ||
|
5017da2514 | ||
|
c2048732d8 | ||
|
5979c1d4bd | ||
|
3090f6f4af | ||
|
40073ef64f | ||
|
b9970eda45 | ||
|
9147489b4c | ||
|
d1348ea05e | ||
|
90db9a6435 | ||
|
1c208ad3ea | ||
|
5fc9bf5bc5 | ||
|
c846d230f0 | ||
|
7b097467d6 | ||
|
7cb040edb0 | ||
|
d6ac116b71 | ||
|
8abc8889d1 | ||
|
c5b47e2136 | ||
|
7c0815c567 | ||
|
210288f02e | ||
|
cf7b6904e8 | ||
|
b978919dd1 | ||
|
1086aff971 | ||
|
445e8d1728 | ||
|
545745d649 | ||
|
d71cc6ab08 | ||
|
0d77fd0678 | ||
|
6ca6d3ce6f | ||
|
cfc82854d3 | ||
|
b9d77d877e | ||
|
1f50e3abe4 | ||
|
697f338510 | ||
|
f4386409d9 | ||
|
ba349679f3 | ||
|
a3b84f8586 | ||
|
b0fd8a6b08 | ||
|
4f5062004a | ||
|
f040bed751 | ||
|
2f8945a885 | ||
|
2bd0778778 | ||
|
eec640bfd7 | ||
|
754fd941ee |
@@ -29,20 +29,24 @@
|
|||||||
and <STRONG>shared_ptr<T const></STRONG>, depending on constness, to <STRONG>this</STRONG>.</P>
|
and <STRONG>shared_ptr<T const></STRONG>, depending on constness, to <STRONG>this</STRONG>.</P>
|
||||||
<h3><a name="Example">Example</a></h3>
|
<h3><a name="Example">Example</a></h3>
|
||||||
<pre>
|
<pre>
|
||||||
class Y: public enable_shared_from_this<Y>
|
#include <boost/enable_shared_from_this.hpp>
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
class Y: public boost::enable_shared_from_this<Y>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
shared_ptr<Y> f()
|
boost::shared_ptr<Y> f()
|
||||||
{
|
{
|
||||||
return shared_from_this();
|
return shared_from_this();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
shared_ptr<Y> p(new Y);
|
boost::shared_ptr<Y> p(new Y);
|
||||||
shared_ptr<Y> q = p->f();
|
boost::shared_ptr<Y> q = p->f();
|
||||||
assert(p == q);
|
assert(p == q);
|
||||||
assert(!(p < q || q < p)); // p and q must share ownership
|
assert(!(p < q || q < p)); // p and q must share ownership
|
||||||
}
|
}
|
||||||
|
@@ -19,20 +19,72 @@
|
|||||||
|
|
||||||
#if defined( BOOST_NO_TYPEID )
|
#if defined( BOOST_NO_TYPEID )
|
||||||
|
|
||||||
|
#include <boost/current_function.hpp>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
|
|
||||||
typedef void* sp_typeinfo;
|
class sp_typeinfo
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
sp_typeinfo( sp_typeinfo const& );
|
||||||
|
sp_typeinfo& operator=( sp_typeinfo const& );
|
||||||
|
|
||||||
|
char const * name_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
explicit sp_typeinfo( char const * name ): name_( name )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==( sp_typeinfo const& rhs ) const
|
||||||
|
{
|
||||||
|
return this == &rhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=( sp_typeinfo const& rhs ) const
|
||||||
|
{
|
||||||
|
return this != &rhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool before( sp_typeinfo const& rhs ) const
|
||||||
|
{
|
||||||
|
return std::less< sp_typeinfo const* >()( this, &rhs );
|
||||||
|
}
|
||||||
|
|
||||||
|
char const* name() const
|
||||||
|
{
|
||||||
|
return name_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template<class T> struct sp_typeid_
|
template<class T> struct sp_typeid_
|
||||||
{
|
{
|
||||||
static char v_;
|
static sp_typeinfo ti_;
|
||||||
|
|
||||||
|
static char const * name()
|
||||||
|
{
|
||||||
|
return BOOST_CURRENT_FUNCTION;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class T> char sp_typeid_< T >::v_;
|
#if defined(__SUNPRO_CC)
|
||||||
|
// see #4199, the Sun Studio compiler gets confused about static initialization
|
||||||
|
// constructor arguments. But an assignment works just fine.
|
||||||
|
template<class T> sp_typeinfo sp_typeid_< T >::ti_ = sp_typeid_< T >::name();
|
||||||
|
#else
|
||||||
|
template<class T> sp_typeinfo sp_typeid_< T >::ti_(sp_typeid_< T >::name());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<class T> struct sp_typeid_< T & >: sp_typeid_< T >
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
template<class T> struct sp_typeid_< T const >: sp_typeid_< T >
|
template<class T> struct sp_typeid_< T const >: sp_typeid_< T >
|
||||||
{
|
{
|
||||||
@@ -50,7 +102,7 @@ template<class T> struct sp_typeid_< T const volatile >: sp_typeid_< T >
|
|||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
#define BOOST_SP_TYPEID(T) (&boost::detail::sp_typeid_<T>::v_)
|
#define BOOST_SP_TYPEID(T) (boost::detail::sp_typeid_<T>::ti_)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
@@ -3,13 +3,15 @@
|
|||||||
// accompanying file LICENSE_1_0.txt or copy at
|
// accompanying file LICENSE_1_0.txt or copy at
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
#ifndef GET_POINTER_DWA20021219_HPP
|
#ifndef GET_POINTER_DWA20021219_HPP
|
||||||
# define GET_POINTER_DWA20021219_HPP
|
#define GET_POINTER_DWA20021219_HPP
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
|
||||||
// In order to avoid circular dependencies with Boost.TR1
|
// In order to avoid circular dependencies with Boost.TR1
|
||||||
// we make sure that our include of <memory> doesn't try to
|
// we make sure that our include of <memory> doesn't try to
|
||||||
// pull in the TR1 headers: that's why we use this header
|
// pull in the TR1 headers: that's why we use this header
|
||||||
// rather than including <memory> directly:
|
// rather than including <memory> directly:
|
||||||
# include <boost/config/no_tr1/memory.hpp> // std::auto_ptr
|
#include <boost/config/no_tr1/memory.hpp> // std::auto_ptr
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
|
|
||||||
@@ -27,6 +29,19 @@ template<class T> T * get_pointer(std::auto_ptr<T> const& p)
|
|||||||
return p.get();
|
return p.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined( BOOST_NO_CXX11_SMART_PTR )
|
||||||
|
|
||||||
|
template<class T> T * get_pointer( std::unique_ptr<T> const& p )
|
||||||
|
{
|
||||||
|
return p.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> T * get_pointer( std::shared_ptr<T> const& p )
|
||||||
|
{
|
||||||
|
return p.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
|
@@ -11,7 +11,7 @@
|
|||||||
//
|
//
|
||||||
// Defines enum boost::memory_order per the C++0x working draft
|
// Defines enum boost::memory_order per the C++0x working draft
|
||||||
//
|
//
|
||||||
// Copyright (c) 2008 Peter Dimov
|
// Copyright (c) 2008, 2009 Peter Dimov
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0.
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
// See accompanying file LICENSE_1_0.txt or copy at
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
@@ -21,13 +21,31 @@
|
|||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
|
|
||||||
|
//
|
||||||
|
// Enum values are chosen so that code that needs to insert
|
||||||
|
// a trailing fence for acquire semantics can use a single
|
||||||
|
// test such as:
|
||||||
|
//
|
||||||
|
// if( mo & memory_order_acquire ) { ...fence... }
|
||||||
|
//
|
||||||
|
// For leading fences one can use:
|
||||||
|
//
|
||||||
|
// if( mo & memory_order_release ) { ...fence... }
|
||||||
|
//
|
||||||
|
// Architectures such as Alpha that need a fence on consume
|
||||||
|
// can use:
|
||||||
|
//
|
||||||
|
// if( mo & ( memory_order_acquire | memory_order_consume ) ) { ...fence... }
|
||||||
|
//
|
||||||
|
|
||||||
enum memory_order
|
enum memory_order
|
||||||
{
|
{
|
||||||
memory_order_relaxed = 0,
|
memory_order_relaxed = 0,
|
||||||
memory_order_acquire = 1,
|
memory_order_acquire = 1,
|
||||||
memory_order_release = 2,
|
memory_order_release = 2,
|
||||||
memory_order_acq_rel = 3, // acquire | release
|
memory_order_acq_rel = 3, // acquire | release
|
||||||
memory_order_seq_cst = 7 // acq_rel | 4
|
memory_order_seq_cst = 7, // acq_rel | 4
|
||||||
|
memory_order_consume = 8
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
@@ -1,3 +1,6 @@
|
|||||||
|
#ifndef BOOST_SMART_PTR_HPP_INCLUDED
|
||||||
|
#define BOOST_SMART_PTR_HPP_INCLUDED
|
||||||
|
|
||||||
//
|
//
|
||||||
// smart_ptr.hpp
|
// smart_ptr.hpp
|
||||||
//
|
//
|
||||||
@@ -22,4 +25,7 @@
|
|||||||
# include <boost/weak_ptr.hpp>
|
# include <boost/weak_ptr.hpp>
|
||||||
# include <boost/intrusive_ptr.hpp>
|
# include <boost/intrusive_ptr.hpp>
|
||||||
# include <boost/enable_shared_from_this.hpp>
|
# include <boost/enable_shared_from_this.hpp>
|
||||||
|
# include <boost/make_shared.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_SMART_PTR_HPP_INCLUDED
|
||||||
|
250
include/boost/smart_ptr/allocate_shared_array.hpp
Normal file
250
include/boost/smart_ptr/allocate_shared_array.hpp
Normal file
@@ -0,0 +1,250 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2012 Glen Joseph Fernandes
|
||||||
|
* glenfe at live dot com
|
||||||
|
*
|
||||||
|
* Distributed under the Boost Software License,
|
||||||
|
* Version 1.0. (See accompanying file LICENSE_1_0.txt
|
||||||
|
* or copy at http://boost.org/LICENSE_1_0.txt)
|
||||||
|
*/
|
||||||
|
#ifndef BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP
|
||||||
|
#define BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP
|
||||||
|
|
||||||
|
#include <boost/smart_ptr/shared_ptr.hpp>
|
||||||
|
#include <boost/smart_ptr/detail/allocate_array_helper.hpp>
|
||||||
|
#include <boost/smart_ptr/detail/array_deleter.hpp>
|
||||||
|
#include <boost/smart_ptr/detail/array_traits.hpp>
|
||||||
|
#include <boost/smart_ptr/detail/sp_if_array.hpp>
|
||||||
|
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||||
|
#include <initializer_list>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
template<typename T, typename A>
|
||||||
|
inline typename boost::detail::sp_if_array<T>::type
|
||||||
|
allocate_shared(const A& allocator, std::size_t size) {
|
||||||
|
typedef typename boost::detail::array_inner<T>::type T1;
|
||||||
|
typedef typename boost::detail::array_base<T1>::type T2;
|
||||||
|
T1* p1 = 0;
|
||||||
|
T2* p2 = 0;
|
||||||
|
std::size_t n1 = size * boost::detail::array_total<T1>::size;
|
||||||
|
boost::detail::allocate_array_helper<A, T2[]> a1(allocator, n1, &p2);
|
||||||
|
boost::detail::array_deleter<T2[]> d1(n1);
|
||||||
|
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||||
|
typedef boost::detail::array_deleter<T2[]>* D2;
|
||||||
|
p1 = reinterpret_cast<T1*>(p2);
|
||||||
|
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||||
|
d2->init(p2);
|
||||||
|
return boost::shared_ptr<T>(s1, p1);
|
||||||
|
}
|
||||||
|
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||||
|
template<typename T, typename A, typename... Args>
|
||||||
|
inline typename boost::detail::sp_if_array<T>::type
|
||||||
|
allocate_shared(const A& allocator, std::size_t size, Args&&... args) {
|
||||||
|
typedef typename boost::detail::array_inner<T>::type T1;
|
||||||
|
typedef typename boost::detail::array_base<T1>::type T2;
|
||||||
|
T1* p1 = 0;
|
||||||
|
T2* p2 = 0;
|
||||||
|
std::size_t n1 = size * boost::detail::array_total<T1>::size;
|
||||||
|
boost::detail::allocate_array_helper<A, T2[]> a1(allocator, n1, &p2);
|
||||||
|
boost::detail::array_deleter<T2[]> d1(n1);
|
||||||
|
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||||
|
typedef boost::detail::array_deleter<T2[]>* D2;
|
||||||
|
p1 = reinterpret_cast<T1*>(p2);
|
||||||
|
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||||
|
d2->init(p2, boost::detail::sp_forward<Args>(args)...);
|
||||||
|
return boost::shared_ptr<T>(s1, p1);
|
||||||
|
}
|
||||||
|
template<typename T, typename A, typename... Args>
|
||||||
|
inline typename boost::detail::sp_if_size_array<T>::type
|
||||||
|
allocate_shared(const A& allocator, Args&&... args) {
|
||||||
|
typedef typename boost::detail::array_inner<T>::type T1;
|
||||||
|
typedef typename boost::detail::array_base<T1>::type T2;
|
||||||
|
enum {
|
||||||
|
N = boost::detail::array_total<T>::size
|
||||||
|
};
|
||||||
|
T1* p1 = 0;
|
||||||
|
T2* p2 = 0;
|
||||||
|
boost::detail::allocate_array_helper<A, T2[N]> a1(allocator, &p2);
|
||||||
|
boost::detail::array_deleter<T2[N]> d1;
|
||||||
|
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||||
|
typedef boost::detail::array_deleter<T2[N]>* D2;
|
||||||
|
p1 = reinterpret_cast<T1*>(p2);
|
||||||
|
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||||
|
d2->init(p2, boost::detail::sp_forward<Args>(args)...);
|
||||||
|
return boost::shared_ptr<T>(s1, p1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
|
||||||
|
template<typename T, typename A>
|
||||||
|
inline typename boost::detail::sp_if_size_array<T>::type
|
||||||
|
allocate_shared(const A& allocator, const T& list) {
|
||||||
|
typedef typename boost::detail::array_inner<T>::type T1;
|
||||||
|
typedef typename boost::detail::array_base<T1>::type T2;
|
||||||
|
typedef const T2 T3;
|
||||||
|
enum {
|
||||||
|
N = boost::detail::array_total<T>::size
|
||||||
|
};
|
||||||
|
T1* p1 = 0;
|
||||||
|
T2* p2 = 0;
|
||||||
|
T3* p3 = 0;
|
||||||
|
boost::detail::allocate_array_helper<A, T2[N]> a1(allocator, &p2);
|
||||||
|
boost::detail::array_deleter<T2[N]> d1;
|
||||||
|
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||||
|
typedef boost::detail::array_deleter<T2[N]>* D2;
|
||||||
|
p3 = reinterpret_cast<T3*>(list);
|
||||||
|
p1 = reinterpret_cast<T1*>(p2);
|
||||||
|
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||||
|
d2->init_list(p2, p3);
|
||||||
|
return boost::shared_ptr<T>(s1, p1);
|
||||||
|
}
|
||||||
|
template<typename T, typename A>
|
||||||
|
inline typename boost::detail::sp_if_array<T>::type
|
||||||
|
allocate_shared(const A& allocator, std::size_t size,
|
||||||
|
const typename boost::detail::array_inner<T>::type& list) {
|
||||||
|
typedef typename boost::detail::array_inner<T>::type T1;
|
||||||
|
typedef typename boost::detail::array_base<T1>::type T2;
|
||||||
|
typedef const T2 T3;
|
||||||
|
enum {
|
||||||
|
M = boost::detail::array_total<T1>::size
|
||||||
|
};
|
||||||
|
T1* p1 = 0;
|
||||||
|
T2* p2 = 0;
|
||||||
|
T3* p3 = 0;
|
||||||
|
std::size_t n1 = M * size;
|
||||||
|
boost::detail::allocate_array_helper<A, T2[]> a1(allocator, n1, &p2);
|
||||||
|
boost::detail::array_deleter<T2[]> d1(n1);
|
||||||
|
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||||
|
typedef boost::detail::array_deleter<T2[]>* D2;
|
||||||
|
p3 = reinterpret_cast<T3*>(list);
|
||||||
|
p1 = reinterpret_cast<T1*>(p2);
|
||||||
|
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||||
|
d2->template init_list<M>(p2, p3);
|
||||||
|
return boost::shared_ptr<T>(s1, p1);
|
||||||
|
}
|
||||||
|
template<typename T, typename A>
|
||||||
|
inline typename boost::detail::sp_if_size_array<T>::type
|
||||||
|
allocate_shared(const A& allocator,
|
||||||
|
const typename boost::detail::array_inner<T>::type& list) {
|
||||||
|
typedef typename boost::detail::array_inner<T>::type T1;
|
||||||
|
typedef typename boost::detail::array_base<T1>::type T2;
|
||||||
|
typedef const T2 T3;
|
||||||
|
enum {
|
||||||
|
M = boost::detail::array_total<T1>::size,
|
||||||
|
N = boost::detail::array_total<T>::size
|
||||||
|
};
|
||||||
|
T1* p1 = 0;
|
||||||
|
T2* p2 = 0;
|
||||||
|
T3* p3 = 0;
|
||||||
|
boost::detail::allocate_array_helper<A, T2[N]> a1(allocator, &p2);
|
||||||
|
boost::detail::array_deleter<T2[N]> d1;
|
||||||
|
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||||
|
typedef boost::detail::array_deleter<T2[N]>* D2;
|
||||||
|
p3 = reinterpret_cast<T3*>(list);
|
||||||
|
p1 = reinterpret_cast<T1*>(p2);
|
||||||
|
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||||
|
d2->template init_list<M>(p2, p3);
|
||||||
|
return boost::shared_ptr<T>(s1, p1);
|
||||||
|
}
|
||||||
|
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||||
|
template<typename T, typename A>
|
||||||
|
inline typename boost::detail::sp_if_array<T>::type
|
||||||
|
allocate_shared(const A& allocator,
|
||||||
|
std::initializer_list<typename boost::detail::array_inner<T>::type> list) {
|
||||||
|
typedef typename boost::detail::array_inner<T>::type T1;
|
||||||
|
typedef typename boost::detail::array_base<T1>::type T2;
|
||||||
|
typedef const T2 T3;
|
||||||
|
T1* p1 = 0;
|
||||||
|
T2* p2 = 0;
|
||||||
|
T3* p3 = 0;
|
||||||
|
std::size_t n1 = list.size() * boost::detail::array_total<T1>::size;
|
||||||
|
boost::detail::allocate_array_helper<A, T2[]> a1(allocator, n1, &p2);
|
||||||
|
boost::detail::array_deleter<T2[]> d1(n1);
|
||||||
|
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||||
|
typedef boost::detail::array_deleter<T2[]>* D2;
|
||||||
|
p3 = reinterpret_cast<T3*>(list.begin());
|
||||||
|
p1 = reinterpret_cast<T1*>(p2);
|
||||||
|
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||||
|
d2->init_list(p2, p3);
|
||||||
|
return boost::shared_ptr<T>(s1, p1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||||
|
template<typename T, typename A>
|
||||||
|
inline typename boost::detail::sp_if_array<T>::type
|
||||||
|
allocate_shared(const A& allocator, std::size_t size,
|
||||||
|
typename boost::detail::array_base<T>::type&& value) {
|
||||||
|
typedef typename boost::detail::array_inner<T>::type T1;
|
||||||
|
typedef typename boost::detail::array_base<T1>::type T2;
|
||||||
|
T1* p1 = 0;
|
||||||
|
T2* p2 = 0;
|
||||||
|
std::size_t n1 = size * boost::detail::array_total<T1>::size;
|
||||||
|
boost::detail::allocate_array_helper<A, T2[]> a1(allocator, n1, &p2);
|
||||||
|
boost::detail::array_deleter<T2[]> d1(n1);
|
||||||
|
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||||
|
typedef boost::detail::array_deleter<T2[]>* D2;
|
||||||
|
p1 = reinterpret_cast<T1*>(p2);
|
||||||
|
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||||
|
d2->init(p2, boost::detail::sp_forward<T2>(value));
|
||||||
|
return boost::shared_ptr<T>(s1, p1);
|
||||||
|
}
|
||||||
|
template<typename T, typename A>
|
||||||
|
inline typename boost::detail::sp_if_size_array<T>::type
|
||||||
|
allocate_shared(const A& allocator,
|
||||||
|
typename boost::detail::array_base<T>::type&& value) {
|
||||||
|
typedef typename boost::detail::array_inner<T>::type T1;
|
||||||
|
typedef typename boost::detail::array_base<T1>::type T2;
|
||||||
|
enum {
|
||||||
|
N = boost::detail::array_total<T>::size
|
||||||
|
};
|
||||||
|
T1* p1 = 0;
|
||||||
|
T2* p2 = 0;
|
||||||
|
boost::detail::allocate_array_helper<A, T2[N]> a1(allocator, &p2);
|
||||||
|
boost::detail::array_deleter<T2[N]> d1;
|
||||||
|
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||||
|
typedef boost::detail::array_deleter<T2[N]>* D2;
|
||||||
|
p1 = reinterpret_cast<T1*>(p2);
|
||||||
|
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||||
|
d2->init(p2, boost::detail::sp_forward<T2>(value));
|
||||||
|
return boost::shared_ptr<T>(s1, p1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
template<typename T, typename A>
|
||||||
|
inline typename boost::detail::sp_if_array<T>::type
|
||||||
|
allocate_shared_noinit(const A& allocator, std::size_t size) {
|
||||||
|
typedef typename boost::detail::array_inner<T>::type T1;
|
||||||
|
typedef typename boost::detail::array_base<T1>::type T2;
|
||||||
|
T1* p1 = 0;
|
||||||
|
T2* p2 = 0;
|
||||||
|
std::size_t n1 = size * boost::detail::array_total<T1>::size;
|
||||||
|
boost::detail::allocate_array_helper<A, T2[]> a1(allocator, n1, &p2);
|
||||||
|
boost::detail::array_deleter<T2[]> d1(n1);
|
||||||
|
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||||
|
typedef boost::detail::array_deleter<T2[]>* D2;
|
||||||
|
p1 = reinterpret_cast<T1*>(p2);
|
||||||
|
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||||
|
d2->noinit(p2);
|
||||||
|
return boost::shared_ptr<T>(s1, p1);
|
||||||
|
}
|
||||||
|
template<typename T, typename A>
|
||||||
|
inline typename boost::detail::sp_if_size_array<T>::type
|
||||||
|
allocate_shared_noinit(const A& allocator) {
|
||||||
|
typedef typename boost::detail::array_inner<T>::type T1;
|
||||||
|
typedef typename boost::detail::array_base<T1>::type T2;
|
||||||
|
enum {
|
||||||
|
N = boost::detail::array_total<T>::size
|
||||||
|
};
|
||||||
|
T1* p1 = 0;
|
||||||
|
T2* p2 = 0;
|
||||||
|
boost::detail::allocate_array_helper<A, T2[N]> a1(allocator, &p2);
|
||||||
|
boost::detail::array_deleter<T2[N]> d1;
|
||||||
|
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||||
|
typedef boost::detail::array_deleter<T2[N]>* D2;
|
||||||
|
p1 = reinterpret_cast<T1*>(p2);
|
||||||
|
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||||
|
d2->noinit(p2);
|
||||||
|
return boost::shared_ptr<T>(s1, p1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
169
include/boost/smart_ptr/detail/allocate_array_helper.hpp
Normal file
169
include/boost/smart_ptr/detail/allocate_array_helper.hpp
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2012 Glen Joseph Fernandes
|
||||||
|
* glenfe at live dot com
|
||||||
|
*
|
||||||
|
* Distributed under the Boost Software License,
|
||||||
|
* Version 1.0. (See accompanying file LICENSE_1_0.txt
|
||||||
|
* or copy at http://boost.org/LICENSE_1_0.txt)
|
||||||
|
*/
|
||||||
|
#ifndef BOOST_SMART_PTR_DETAIL_ALLOCATE_ARRAY_HELPER_HPP
|
||||||
|
#define BOOST_SMART_PTR_DETAIL_ALLOCATE_ARRAY_HELPER_HPP
|
||||||
|
|
||||||
|
#include <boost/type_traits/alignment_of.hpp>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace detail {
|
||||||
|
template<typename A, typename T, typename Y = char>
|
||||||
|
class allocate_array_helper;
|
||||||
|
template<typename A, typename T, typename Y>
|
||||||
|
class allocate_array_helper<A, T[], Y> {
|
||||||
|
template<typename A9, typename T9, typename Y9>
|
||||||
|
friend class allocate_array_helper;
|
||||||
|
typedef typename A::template rebind<Y> ::other A2;
|
||||||
|
typedef typename A::template rebind<char>::other A3;
|
||||||
|
public:
|
||||||
|
typedef typename A2::value_type value_type;
|
||||||
|
typedef typename A2::pointer pointer;
|
||||||
|
typedef typename A2::const_pointer const_pointer;
|
||||||
|
typedef typename A2::reference reference;
|
||||||
|
typedef typename A2::const_reference const_reference;
|
||||||
|
typedef typename A2::size_type size_type;
|
||||||
|
typedef typename A2::difference_type difference_type;
|
||||||
|
template<typename U>
|
||||||
|
struct rebind {
|
||||||
|
typedef allocate_array_helper<A, T[], U> other;
|
||||||
|
};
|
||||||
|
allocate_array_helper(const A& allocator_, std::size_t size_, T** data_)
|
||||||
|
: allocator(allocator_),
|
||||||
|
size(sizeof(T) * size_),
|
||||||
|
data(data_) {
|
||||||
|
}
|
||||||
|
template<class U>
|
||||||
|
allocate_array_helper(const allocate_array_helper<A, T[], U>& other)
|
||||||
|
: allocator(other.allocator),
|
||||||
|
size(other.size),
|
||||||
|
data(other.data) {
|
||||||
|
}
|
||||||
|
pointer address(reference value) const {
|
||||||
|
return allocator.address(value);
|
||||||
|
}
|
||||||
|
const_pointer address(const_reference value) const {
|
||||||
|
return allocator.address(value);
|
||||||
|
}
|
||||||
|
size_type max_size() const {
|
||||||
|
return allocator.max_size();
|
||||||
|
}
|
||||||
|
pointer allocate(size_type count, const void* value = 0) {
|
||||||
|
std::size_t a1 = boost::alignment_of<T>::value;
|
||||||
|
std::size_t n1 = count * sizeof(Y) + a1 - 1;
|
||||||
|
char* p1 = A3(allocator).allocate(n1 + size, value);
|
||||||
|
char* p2 = p1 + n1;
|
||||||
|
while (std::size_t(p2) % a1 != 0) {
|
||||||
|
p2--;
|
||||||
|
}
|
||||||
|
*data = reinterpret_cast<T*>(p2);
|
||||||
|
return reinterpret_cast<Y*>(p1);
|
||||||
|
}
|
||||||
|
void deallocate(pointer memory, size_type count) {
|
||||||
|
std::size_t a1 = boost::alignment_of<T>::value;
|
||||||
|
std::size_t n1 = count * sizeof(Y) + a1 - 1;
|
||||||
|
char* p1 = reinterpret_cast<char*>(memory);
|
||||||
|
A3(allocator).deallocate(p1, n1 + size);
|
||||||
|
}
|
||||||
|
void construct(pointer memory, const Y& value) {
|
||||||
|
allocator.construct(memory, value);
|
||||||
|
}
|
||||||
|
void destroy(pointer memory) {
|
||||||
|
allocator.destroy(memory);
|
||||||
|
}
|
||||||
|
template<typename U>
|
||||||
|
bool operator==(const allocate_array_helper<A, T[], U>& other) const {
|
||||||
|
return allocator == other.allocator;
|
||||||
|
}
|
||||||
|
template<typename U>
|
||||||
|
bool operator!=(const allocate_array_helper<A, T[], U>& other) const {
|
||||||
|
return !(*this == other);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
A2 allocator;
|
||||||
|
std::size_t size;
|
||||||
|
T** data;
|
||||||
|
};
|
||||||
|
template<typename A, typename T, std::size_t N, typename Y>
|
||||||
|
class allocate_array_helper<A, T[N], Y> {
|
||||||
|
template<typename A9, typename T9, typename Y9>
|
||||||
|
friend class allocate_array_helper;
|
||||||
|
typedef typename A::template rebind<Y> ::other A2;
|
||||||
|
typedef typename A::template rebind<char>::other A3;
|
||||||
|
public:
|
||||||
|
typedef typename A2::value_type value_type;
|
||||||
|
typedef typename A2::pointer pointer;
|
||||||
|
typedef typename A2::const_pointer const_pointer;
|
||||||
|
typedef typename A2::reference reference;
|
||||||
|
typedef typename A2::const_reference const_reference;
|
||||||
|
typedef typename A2::size_type size_type;
|
||||||
|
typedef typename A2::difference_type difference_type;
|
||||||
|
template<typename U>
|
||||||
|
struct rebind {
|
||||||
|
typedef allocate_array_helper<A, T[N], U> other;
|
||||||
|
};
|
||||||
|
allocate_array_helper(const A& allocator_, T** data_)
|
||||||
|
: allocator(allocator_),
|
||||||
|
data(data_) {
|
||||||
|
}
|
||||||
|
template<class U>
|
||||||
|
allocate_array_helper(const allocate_array_helper<A, T[N], U>& other)
|
||||||
|
: allocator(other.allocator),
|
||||||
|
data(other.data) {
|
||||||
|
}
|
||||||
|
pointer address(reference value) const {
|
||||||
|
return allocator.address(value);
|
||||||
|
}
|
||||||
|
const_pointer address(const_reference value) const {
|
||||||
|
return allocator.address(value);
|
||||||
|
}
|
||||||
|
size_type max_size() const {
|
||||||
|
return allocator.max_size();
|
||||||
|
}
|
||||||
|
pointer allocate(size_type count, const void* value = 0) {
|
||||||
|
std::size_t a1 = boost::alignment_of<T>::value;
|
||||||
|
std::size_t n1 = count * sizeof(Y) + a1 - 1;
|
||||||
|
char* p1 = A3(allocator).allocate(n1 + N1, value);
|
||||||
|
char* p2 = p1 + n1;
|
||||||
|
while (std::size_t(p2) % a1 != 0) {
|
||||||
|
p2--;
|
||||||
|
}
|
||||||
|
*data = reinterpret_cast<T*>(p2);
|
||||||
|
return reinterpret_cast<Y*>(p1);
|
||||||
|
}
|
||||||
|
void deallocate(pointer memory, size_type count) {
|
||||||
|
std::size_t a1 = boost::alignment_of<T>::value;
|
||||||
|
std::size_t n1 = count * sizeof(Y) + a1 - 1;
|
||||||
|
char* p1 = reinterpret_cast<char*>(memory);
|
||||||
|
A3(allocator).deallocate(p1, n1 + N1);
|
||||||
|
}
|
||||||
|
void construct(pointer memory, const Y& value) {
|
||||||
|
allocator.construct(memory, value);
|
||||||
|
}
|
||||||
|
void destroy(pointer memory) {
|
||||||
|
allocator.destroy(memory);
|
||||||
|
}
|
||||||
|
template<typename U>
|
||||||
|
bool operator==(const allocate_array_helper<A, T[N], U>& other) const {
|
||||||
|
return allocator == other.allocator;
|
||||||
|
}
|
||||||
|
template<typename U>
|
||||||
|
bool operator!=(const allocate_array_helper<A, T[N], U>& other) const {
|
||||||
|
return !(*this == other);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
enum {
|
||||||
|
N1 = N * sizeof(T)
|
||||||
|
};
|
||||||
|
A2 allocator;
|
||||||
|
T** data;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
124
include/boost/smart_ptr/detail/array_deleter.hpp
Normal file
124
include/boost/smart_ptr/detail/array_deleter.hpp
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2012 Glen Joseph Fernandes
|
||||||
|
* glenfe at live dot com
|
||||||
|
*
|
||||||
|
* Distributed under the Boost Software License,
|
||||||
|
* Version 1.0. (See accompanying file LICENSE_1_0.txt
|
||||||
|
* or copy at http://boost.org/LICENSE_1_0.txt)
|
||||||
|
*/
|
||||||
|
#ifndef BOOST_SMART_PTR_DETAIL_ARRAY_DELETER_HPP
|
||||||
|
#define BOOST_SMART_PTR_DETAIL_ARRAY_DELETER_HPP
|
||||||
|
|
||||||
|
#include <boost/smart_ptr/detail/array_utility.hpp>
|
||||||
|
#include <boost/smart_ptr/detail/sp_forward.hpp>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace detail {
|
||||||
|
template<typename T>
|
||||||
|
class array_deleter;
|
||||||
|
template<typename T>
|
||||||
|
class array_deleter<T[]> {
|
||||||
|
public:
|
||||||
|
array_deleter(std::size_t size_)
|
||||||
|
: size(size_),
|
||||||
|
object(0) {
|
||||||
|
}
|
||||||
|
~array_deleter() {
|
||||||
|
if (object) {
|
||||||
|
array_destroy(object, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void init(T* memory) {
|
||||||
|
array_init(memory, size);
|
||||||
|
object = memory;
|
||||||
|
}
|
||||||
|
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||||
|
void init(T* memory, T&& value) {
|
||||||
|
array_init_value(memory, size, sp_forward<T>(value));
|
||||||
|
object = memory;
|
||||||
|
}
|
||||||
|
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||||
|
template<typename... Args>
|
||||||
|
void init(T* memory, Args&&... args) {
|
||||||
|
array_init_args(memory, size, sp_forward<Args>(args)...);
|
||||||
|
object = memory;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
void init_list(T* memory, const T* list) {
|
||||||
|
array_init_list(memory, size, list);
|
||||||
|
object = memory;
|
||||||
|
}
|
||||||
|
template<std::size_t M>
|
||||||
|
void init_list(T* memory, const T* list) {
|
||||||
|
array_init_list<T, M>(memory, size, list);
|
||||||
|
object = memory;
|
||||||
|
}
|
||||||
|
void noinit(T* memory) {
|
||||||
|
array_noinit(memory, size);
|
||||||
|
object = memory;
|
||||||
|
}
|
||||||
|
void operator()(const void*) {
|
||||||
|
if (object) {
|
||||||
|
array_destroy(object, size);
|
||||||
|
object = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
std::size_t size;
|
||||||
|
T* object;
|
||||||
|
};
|
||||||
|
template<typename T, std::size_t N>
|
||||||
|
class array_deleter<T[N]> {
|
||||||
|
public:
|
||||||
|
array_deleter()
|
||||||
|
: object(0) {
|
||||||
|
}
|
||||||
|
~array_deleter() {
|
||||||
|
if (object) {
|
||||||
|
array_destroy(object, N);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void init(T* memory) {
|
||||||
|
array_init(memory, N);
|
||||||
|
object = memory;
|
||||||
|
}
|
||||||
|
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||||
|
void init(T* memory, T&& value) {
|
||||||
|
array_init_value(memory, N, sp_forward<T>(value));
|
||||||
|
object = memory;
|
||||||
|
}
|
||||||
|
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||||
|
template<typename... Args>
|
||||||
|
void init(T* memory, Args&&... args) {
|
||||||
|
array_init_args(memory, N, sp_forward<Args>(args)...);
|
||||||
|
object = memory;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
void init_list(T* memory, const T* list) {
|
||||||
|
array_init_list(memory, N, list);
|
||||||
|
object = memory;
|
||||||
|
}
|
||||||
|
template<std::size_t M>
|
||||||
|
void init_list(T* memory, const T* list) {
|
||||||
|
array_init_list<T, M>(memory, N, list);
|
||||||
|
object = memory;
|
||||||
|
}
|
||||||
|
void noinit(T* memory) {
|
||||||
|
array_noinit(memory, N);
|
||||||
|
object = memory;
|
||||||
|
}
|
||||||
|
void operator()(const void*) {
|
||||||
|
if (object) {
|
||||||
|
array_destroy(object, N);
|
||||||
|
object = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
T* object;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
53
include/boost/smart_ptr/detail/array_traits.hpp
Normal file
53
include/boost/smart_ptr/detail/array_traits.hpp
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2012 Glen Joseph Fernandes
|
||||||
|
* glenfe at live dot com
|
||||||
|
*
|
||||||
|
* Distributed under the Boost Software License,
|
||||||
|
* Version 1.0. (See accompanying file LICENSE_1_0.txt
|
||||||
|
* or copy at http://boost.org/LICENSE_1_0.txt)
|
||||||
|
*/
|
||||||
|
#ifndef BOOST_SMART_PTR_DETAIL_ARRAY_TRAITS_HPP
|
||||||
|
#define BOOST_SMART_PTR_DETAIL_ARRAY_TRAITS_HPP
|
||||||
|
|
||||||
|
#include <boost/type_traits/remove_cv.hpp>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace detail {
|
||||||
|
template<typename T>
|
||||||
|
struct array_base {
|
||||||
|
typedef typename boost::remove_cv<T>::type type;
|
||||||
|
};
|
||||||
|
template<typename T>
|
||||||
|
struct array_base<T[]> {
|
||||||
|
typedef typename array_base<T>::type type;
|
||||||
|
};
|
||||||
|
template<typename T, std::size_t N>
|
||||||
|
struct array_base<T[N]> {
|
||||||
|
typedef typename array_base<T>::type type;
|
||||||
|
};
|
||||||
|
template<typename T>
|
||||||
|
struct array_total {
|
||||||
|
enum {
|
||||||
|
size = 1
|
||||||
|
};
|
||||||
|
};
|
||||||
|
template<typename T, std::size_t N>
|
||||||
|
struct array_total<T[N]> {
|
||||||
|
enum {
|
||||||
|
size = N * array_total<T>::size
|
||||||
|
};
|
||||||
|
};
|
||||||
|
template<typename T>
|
||||||
|
struct array_inner;
|
||||||
|
template<typename T>
|
||||||
|
struct array_inner<T[]> {
|
||||||
|
typedef T type;
|
||||||
|
};
|
||||||
|
template<typename T, std::size_t N>
|
||||||
|
struct array_inner<T[N]> {
|
||||||
|
typedef T type;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
178
include/boost/smart_ptr/detail/array_utility.hpp
Normal file
178
include/boost/smart_ptr/detail/array_utility.hpp
Normal file
@@ -0,0 +1,178 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2012 Glen Joseph Fernandes
|
||||||
|
* glenfe at live dot com
|
||||||
|
*
|
||||||
|
* Distributed under the Boost Software License,
|
||||||
|
* Version 1.0. (See accompanying file LICENSE_1_0.txt
|
||||||
|
* or copy at http://boost.org/LICENSE_1_0.txt)
|
||||||
|
*/
|
||||||
|
#ifndef BOOST_SMART_PTR_DETAIL_ARRAY_UTILITY_HPP
|
||||||
|
#define BOOST_SMART_PTR_DETAIL_ARRAY_UTILITY_HPP
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <boost/type_traits/has_trivial_constructor.hpp>
|
||||||
|
#include <boost/type_traits/has_trivial_destructor.hpp>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace detail {
|
||||||
|
template<typename T>
|
||||||
|
inline void array_destroy(T*, std::size_t, boost::true_type) {
|
||||||
|
}
|
||||||
|
template<typename T>
|
||||||
|
inline void array_destroy(T* memory, std::size_t size, boost::false_type) {
|
||||||
|
for (std::size_t i = size; i > 0; ) {
|
||||||
|
memory[--i].~T();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template<typename T>
|
||||||
|
inline void array_destroy(T* memory, std::size_t size) {
|
||||||
|
boost::has_trivial_destructor<T> type;
|
||||||
|
array_destroy(memory, size, type);
|
||||||
|
}
|
||||||
|
template<typename T>
|
||||||
|
inline void array_init(T* memory, std::size_t size, boost::true_type) {
|
||||||
|
for (std::size_t i = 0; i < size; i++) {
|
||||||
|
memory[i] = T();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template<typename T>
|
||||||
|
inline void array_init(T* memory, std::size_t size, boost::false_type) {
|
||||||
|
#if !defined(BOOST_NO_EXCEPTIONS)
|
||||||
|
std::size_t i = 0;
|
||||||
|
try {
|
||||||
|
for (; i < size; i++) {
|
||||||
|
void* p1 = memory + i;
|
||||||
|
::new(p1) T();
|
||||||
|
}
|
||||||
|
} catch (...) {
|
||||||
|
array_destroy(memory, i);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
for (std::size_t i = 0; i < size; i++) {
|
||||||
|
void* p1 = memory + i;
|
||||||
|
::new(p1) T();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
template<typename T>
|
||||||
|
inline void array_init(T* memory, std::size_t size) {
|
||||||
|
boost::has_trivial_default_constructor<T> type;
|
||||||
|
array_init(memory, size, type);
|
||||||
|
}
|
||||||
|
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||||
|
template<typename T>
|
||||||
|
inline void array_init_value(T* memory, std::size_t size, T&& value) {
|
||||||
|
#if !defined(BOOST_NO_EXCEPTIONS)
|
||||||
|
std::size_t i = 0;
|
||||||
|
try {
|
||||||
|
for (; i < size; i++) {
|
||||||
|
void* p1 = memory + i;
|
||||||
|
::new(p1) T(value);
|
||||||
|
}
|
||||||
|
} catch (...) {
|
||||||
|
array_destroy(memory, i);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
for (std::size_t i = 0; i < size; i++) {
|
||||||
|
void* p1 = memory + i;
|
||||||
|
::new(p1) T(value);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||||
|
template<typename T, typename... Args>
|
||||||
|
inline void array_init_args(T* memory, std::size_t size, Args&&... args) {
|
||||||
|
#if !defined(BOOST_NO_EXCEPTIONS)
|
||||||
|
std::size_t i = 0;
|
||||||
|
try {
|
||||||
|
for (; i < size; i++) {
|
||||||
|
void* p1 = memory + i;
|
||||||
|
::new(p1) T(args...);
|
||||||
|
}
|
||||||
|
} catch (...) {
|
||||||
|
array_destroy(memory, i);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
for (std::size_t i = 0; i < size; i++) {
|
||||||
|
void* p1 = memory + i;
|
||||||
|
::new(p1) T(args...);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
template<typename T>
|
||||||
|
inline void array_init_list(T* memory, std::size_t size, const T* list) {
|
||||||
|
#if !defined(BOOST_NO_EXCEPTIONS)
|
||||||
|
std::size_t i = 0;
|
||||||
|
try {
|
||||||
|
for (; i < size; i++) {
|
||||||
|
void* p1 = memory + i;
|
||||||
|
::new(p1) T(list[i]);
|
||||||
|
}
|
||||||
|
} catch (...) {
|
||||||
|
array_destroy(memory, i);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
for (std::size_t i = 0; i < size; i++) {
|
||||||
|
void* p1 = memory + i;
|
||||||
|
::new(p1) T(list[i]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
template<typename T, std::size_t N>
|
||||||
|
inline void array_init_list(T* memory, std::size_t size, const T* list) {
|
||||||
|
#if !defined(BOOST_NO_EXCEPTIONS)
|
||||||
|
std::size_t i = 0;
|
||||||
|
try {
|
||||||
|
for (; i < size; i++) {
|
||||||
|
void* p1 = memory + i;
|
||||||
|
::new(p1) T(list[i % N]);
|
||||||
|
}
|
||||||
|
} catch (...) {
|
||||||
|
array_destroy(memory, i);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
for (std::size_t i = 0; i < size; i++) {
|
||||||
|
void* p1 = memory + i;
|
||||||
|
::new(p1) T(list[i % N]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
template<typename T>
|
||||||
|
inline void array_noinit(T*, std::size_t, boost::true_type) {
|
||||||
|
}
|
||||||
|
template<typename T>
|
||||||
|
inline void array_noinit(T* memory, std::size_t size, boost::false_type) {
|
||||||
|
#if !defined(BOOST_NO_EXCEPTIONS)
|
||||||
|
std::size_t i = 0;
|
||||||
|
try {
|
||||||
|
for (; i < size; i++) {
|
||||||
|
void* p1 = memory + i;
|
||||||
|
::new(p1) T;
|
||||||
|
}
|
||||||
|
} catch (...) {
|
||||||
|
array_destroy(memory, i);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
for (std::size_t i = 0; i < size; i++) {
|
||||||
|
void* p1 = memory + i;
|
||||||
|
::new(p1) T;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
template<typename T>
|
||||||
|
inline void array_noinit(T* memory, std::size_t size) {
|
||||||
|
boost::has_trivial_default_constructor<T> type;
|
||||||
|
array_noinit(memory, size, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@@ -17,6 +17,7 @@
|
|||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include <boost/assert.hpp>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
@@ -42,15 +43,15 @@ public:
|
|||||||
// HPUX 10.20 / DCE has a nonstandard pthread_mutex_init
|
// HPUX 10.20 / DCE has a nonstandard pthread_mutex_init
|
||||||
|
|
||||||
#if defined(__hpux) && defined(_DECTHREADS_)
|
#if defined(__hpux) && defined(_DECTHREADS_)
|
||||||
pthread_mutex_init(&m_, pthread_mutexattr_default);
|
BOOST_VERIFY( pthread_mutex_init( &m_, pthread_mutexattr_default ) == 0 );
|
||||||
#else
|
#else
|
||||||
pthread_mutex_init(&m_, 0);
|
BOOST_VERIFY( pthread_mutex_init( &m_, 0 ) == 0 );
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
~lightweight_mutex()
|
~lightweight_mutex()
|
||||||
{
|
{
|
||||||
pthread_mutex_destroy(&m_);
|
BOOST_VERIFY( pthread_mutex_destroy( &m_ ) == 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
class scoped_lock;
|
class scoped_lock;
|
||||||
@@ -69,12 +70,12 @@ public:
|
|||||||
|
|
||||||
scoped_lock(lightweight_mutex & m): m_(m.m_)
|
scoped_lock(lightweight_mutex & m): m_(m.m_)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&m_);
|
BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
~scoped_lock()
|
~scoped_lock()
|
||||||
{
|
{
|
||||||
pthread_mutex_unlock(&m_);
|
BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
157
include/boost/smart_ptr/detail/make_array_helper.hpp
Normal file
157
include/boost/smart_ptr/detail/make_array_helper.hpp
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2012 Glen Joseph Fernandes
|
||||||
|
* glenfe at live dot com
|
||||||
|
*
|
||||||
|
* Distributed under the Boost Software License,
|
||||||
|
* Version 1.0. (See accompanying file LICENSE_1_0.txt
|
||||||
|
* or copy at http://boost.org/LICENSE_1_0.txt)
|
||||||
|
*/
|
||||||
|
#ifndef BOOST_SMART_PTR_DETAIL_MAKE_ARRAY_HELPER_HPP
|
||||||
|
#define BOOST_SMART_PTR_DETAIL_MAKE_ARRAY_HELPER_HPP
|
||||||
|
|
||||||
|
#include <boost/type_traits/alignment_of.hpp>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace detail {
|
||||||
|
template<typename T, typename Y = char>
|
||||||
|
class make_array_helper;
|
||||||
|
template<typename T, typename Y>
|
||||||
|
class make_array_helper<T[], Y> {
|
||||||
|
template<typename T2, typename Y2>
|
||||||
|
friend class make_array_helper;
|
||||||
|
public:
|
||||||
|
typedef Y value_type;
|
||||||
|
typedef Y* pointer;
|
||||||
|
typedef const Y* const_pointer;
|
||||||
|
typedef Y& reference;
|
||||||
|
typedef const Y& const_reference;
|
||||||
|
typedef std::size_t size_type;
|
||||||
|
typedef ptrdiff_t difference_type;
|
||||||
|
template<typename U>
|
||||||
|
struct rebind {
|
||||||
|
typedef make_array_helper<T[], U> other;
|
||||||
|
};
|
||||||
|
make_array_helper(std::size_t size_, T** data_)
|
||||||
|
: size(sizeof(T) * size_),
|
||||||
|
data(data_) {
|
||||||
|
}
|
||||||
|
template<class U>
|
||||||
|
make_array_helper(const make_array_helper<T[], U>& other)
|
||||||
|
: size(other.size),
|
||||||
|
data(other.data) {
|
||||||
|
}
|
||||||
|
pointer address(reference value) const {
|
||||||
|
return &value;
|
||||||
|
}
|
||||||
|
const_pointer address(const_reference value) const {
|
||||||
|
return &value;
|
||||||
|
}
|
||||||
|
size_type max_size() const {
|
||||||
|
return static_cast<std::size_t>(-1) / sizeof(Y);
|
||||||
|
}
|
||||||
|
pointer allocate(size_type count, const void* = 0) {
|
||||||
|
std::size_t a1 = boost::alignment_of<T>::value;
|
||||||
|
std::size_t n1 = count * sizeof(Y) + a1 - 1;
|
||||||
|
void* p1 = ::operator new(n1 + size);
|
||||||
|
char* p2 = static_cast<char*>(p1) + n1;
|
||||||
|
while (std::size_t(p2) % a1 != 0) {
|
||||||
|
p2--;
|
||||||
|
}
|
||||||
|
*data = reinterpret_cast<T*>(p2);
|
||||||
|
return reinterpret_cast<Y*>(p1);
|
||||||
|
}
|
||||||
|
void deallocate(pointer memory, size_type) {
|
||||||
|
void* p1 = memory;
|
||||||
|
::operator delete(p1);
|
||||||
|
}
|
||||||
|
void construct(pointer memory, const Y& value) {
|
||||||
|
void* p1 = memory;
|
||||||
|
::new(p1) Y(value);
|
||||||
|
}
|
||||||
|
void destroy(pointer memory) {
|
||||||
|
memory->~Y();
|
||||||
|
}
|
||||||
|
template<typename U>
|
||||||
|
bool operator==(const make_array_helper<T[], U>&) const {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
template<typename U>
|
||||||
|
bool operator!=(const make_array_helper<T[], U>& other) const {
|
||||||
|
return !(*this == other);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
std::size_t size;
|
||||||
|
T** data;
|
||||||
|
};
|
||||||
|
template<typename T, std::size_t N, typename Y>
|
||||||
|
class make_array_helper<T[N], Y> {
|
||||||
|
template<typename T2, typename Y2>
|
||||||
|
friend class make_array_helper;
|
||||||
|
public:
|
||||||
|
typedef Y value_type;
|
||||||
|
typedef Y* pointer;
|
||||||
|
typedef const Y* const_pointer;
|
||||||
|
typedef Y& reference;
|
||||||
|
typedef const Y& const_reference;
|
||||||
|
typedef std::size_t size_type;
|
||||||
|
typedef ptrdiff_t difference_type;
|
||||||
|
template<typename U>
|
||||||
|
struct rebind {
|
||||||
|
typedef make_array_helper<T[N], U> other;
|
||||||
|
};
|
||||||
|
make_array_helper(T** data_)
|
||||||
|
: data(data_) {
|
||||||
|
}
|
||||||
|
template<class U>
|
||||||
|
make_array_helper(const make_array_helper<T[N], U>& other)
|
||||||
|
: data(other.data) {
|
||||||
|
}
|
||||||
|
pointer address(reference value) const {
|
||||||
|
return &value;
|
||||||
|
}
|
||||||
|
const_pointer address(const_reference value) const {
|
||||||
|
return &value;
|
||||||
|
}
|
||||||
|
size_type max_size() const {
|
||||||
|
return static_cast<std::size_t>(-1) / sizeof(Y);
|
||||||
|
}
|
||||||
|
pointer allocate(size_type count, const void* = 0) {
|
||||||
|
std::size_t a1 = boost::alignment_of<T>::value;
|
||||||
|
std::size_t n1 = count * sizeof(Y) + a1 - 1;
|
||||||
|
void* p1 = ::operator new(n1 + N1);
|
||||||
|
char* p2 = static_cast<char*>(p1) + n1;
|
||||||
|
while (std::size_t(p2) % a1 != 0) {
|
||||||
|
p2--;
|
||||||
|
}
|
||||||
|
*data = reinterpret_cast<T*>(p2);
|
||||||
|
return reinterpret_cast<Y*>(p1);
|
||||||
|
}
|
||||||
|
void deallocate(pointer memory, size_type) {
|
||||||
|
void* p1 = memory;
|
||||||
|
::operator delete(p1);
|
||||||
|
}
|
||||||
|
void construct(pointer memory, const Y& value) {
|
||||||
|
void* p1 = memory;
|
||||||
|
::new(p1) Y(value);
|
||||||
|
}
|
||||||
|
void destroy(pointer memory) {
|
||||||
|
memory->~Y();
|
||||||
|
}
|
||||||
|
template<typename U>
|
||||||
|
bool operator==(const make_array_helper<T[N], U>&) const {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
template<typename U>
|
||||||
|
bool operator!=(const make_array_helper<T[N], U>& other) const {
|
||||||
|
return !(*this == other);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
enum {
|
||||||
|
N1 = N * sizeof(T)
|
||||||
|
};
|
||||||
|
T** data;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@@ -1,14 +1,21 @@
|
|||||||
// This header intentionally has no include guards.
|
// This header intentionally has no include guards.
|
||||||
//
|
//
|
||||||
// Copyright (c) 2001-2009 Peter Dimov
|
// Copyright (c) 2001-2009, 2012 Peter Dimov
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0.
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
// See accompanying file LICENSE_1_0.txt or copy at
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
// http://www.boost.org/LICENSE_1_0.txt
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
|
||||||
#if ( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, < 0x570) ) || defined(__CINT__)
|
#if !defined( BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS ) && !defined( BOOST_NO_CXX11_NULLPTR )
|
||||||
|
|
||||||
operator bool () const
|
explicit operator bool () const BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
return px != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif ( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, < 0x570) ) || defined(__CINT__)
|
||||||
|
|
||||||
|
operator bool () const BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
return px != 0;
|
return px != 0;
|
||||||
}
|
}
|
||||||
@@ -21,7 +28,7 @@
|
|||||||
|
|
||||||
typedef void (*unspecified_bool_type)( this_type*** );
|
typedef void (*unspecified_bool_type)( this_type*** );
|
||||||
|
|
||||||
operator unspecified_bool_type() const // never throws
|
operator unspecified_bool_type() const BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
return px == 0? 0: unspecified_bool;
|
return px == 0? 0: unspecified_bool;
|
||||||
}
|
}
|
||||||
@@ -31,18 +38,18 @@
|
|||||||
( defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 304) ) || \
|
( defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 304) ) || \
|
||||||
( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x590) )
|
( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x590) )
|
||||||
|
|
||||||
typedef T * (this_type::*unspecified_bool_type)() const;
|
typedef element_type * (this_type::*unspecified_bool_type)() const;
|
||||||
|
|
||||||
operator unspecified_bool_type() const // never throws
|
operator unspecified_bool_type() const BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
return px == 0? 0: &this_type::get;
|
return px == 0? 0: &this_type::get;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
typedef T * this_type::*unspecified_bool_type;
|
typedef element_type * this_type::*unspecified_bool_type;
|
||||||
|
|
||||||
operator unspecified_bool_type() const // never throws
|
operator unspecified_bool_type() const BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
return px == 0? 0: &this_type::px;
|
return px == 0? 0: &this_type::px;
|
||||||
}
|
}
|
||||||
@@ -50,7 +57,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// operator! is redundant, but some compilers need it
|
// operator! is redundant, but some compilers need it
|
||||||
bool operator! () const // never throws
|
bool operator! () const BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
return px == 0;
|
return px == 0;
|
||||||
}
|
}
|
||||||
|
@@ -74,8 +74,9 @@ template<unsigned size, unsigned align_> struct allocator_impl
|
|||||||
|
|
||||||
static lightweight_mutex & mutex()
|
static lightweight_mutex & mutex()
|
||||||
{
|
{
|
||||||
static lightweight_mutex m;
|
static freeblock< sizeof( lightweight_mutex ), boost::alignment_of< lightweight_mutex >::value > fbm;
|
||||||
return m;
|
static lightweight_mutex * pm = new( &fbm ) lightweight_mutex;
|
||||||
|
return *pm;
|
||||||
}
|
}
|
||||||
|
|
||||||
static lightweight_mutex * mutex_init;
|
static lightweight_mutex * mutex_init;
|
||||||
|
@@ -35,7 +35,14 @@
|
|||||||
// rather than including <memory> directly:
|
// rather than including <memory> directly:
|
||||||
#include <boost/config/no_tr1/memory.hpp> // std::auto_ptr
|
#include <boost/config/no_tr1/memory.hpp> // std::auto_ptr
|
||||||
#include <functional> // std::less
|
#include <functional> // std::less
|
||||||
#include <new> // std::bad_alloc
|
|
||||||
|
#ifdef BOOST_NO_EXCEPTIONS
|
||||||
|
# include <new> // std::bad_alloc
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined( BOOST_NO_CXX11_SMART_PTR )
|
||||||
|
# include <boost/utility/addressof.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
@@ -52,6 +59,42 @@ int const weak_count_id = 0x298C38A4;
|
|||||||
|
|
||||||
struct sp_nothrow_tag {};
|
struct sp_nothrow_tag {};
|
||||||
|
|
||||||
|
template< class D > struct sp_inplace_tag
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
#if !defined( BOOST_NO_CXX11_SMART_PTR )
|
||||||
|
|
||||||
|
template< class T > class sp_reference_wrapper
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
explicit sp_reference_wrapper( T & t): t_( boost::addressof( t ) )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class Y > void operator()( Y * p ) const
|
||||||
|
{
|
||||||
|
(*t_)( p );
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
T * t_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template< class D > struct sp_convert_reference
|
||||||
|
{
|
||||||
|
typedef D type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template< class D > struct sp_convert_reference< D& >
|
||||||
|
{
|
||||||
|
typedef sp_reference_wrapper< D > type;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
class weak_count;
|
class weak_count;
|
||||||
|
|
||||||
class shared_count
|
class shared_count
|
||||||
@@ -142,6 +185,40 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
|
||||||
|
|
||||||
|
template< class P, class D > shared_count( P p, sp_inplace_tag<D> ): pi_( 0 )
|
||||||
|
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||||
|
, id_(shared_count_id)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
#ifndef BOOST_NO_EXCEPTIONS
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
pi_ = new sp_counted_impl_pd< P, D >( p );
|
||||||
|
}
|
||||||
|
catch( ... )
|
||||||
|
{
|
||||||
|
D::operator_fn( p ); // delete p
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
pi_ = new sp_counted_impl_pd< P, D >( p );
|
||||||
|
|
||||||
|
if( pi_ == 0 )
|
||||||
|
{
|
||||||
|
D::operator_fn( p ); // delete p
|
||||||
|
boost::throw_exception( std::bad_alloc() );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_NO_EXCEPTIONS
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
|
||||||
|
|
||||||
template<class P, class D, class A> shared_count( P p, D d, A a ): pi_( 0 )
|
template<class P, class D, class A> shared_count( P p, D d, A a ): pi_( 0 )
|
||||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||||
, id_(shared_count_id)
|
, id_(shared_count_id)
|
||||||
@@ -188,6 +265,56 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
|
||||||
|
|
||||||
|
template< class P, class D, class A > shared_count( P p, sp_inplace_tag< D >, A a ): pi_( 0 )
|
||||||
|
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||||
|
, id_(shared_count_id)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
typedef sp_counted_impl_pda< P, D, A > impl_type;
|
||||||
|
typedef typename A::template rebind< impl_type >::other A2;
|
||||||
|
|
||||||
|
A2 a2( a );
|
||||||
|
|
||||||
|
#ifndef BOOST_NO_EXCEPTIONS
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
|
||||||
|
new( static_cast< void* >( pi_ ) ) impl_type( p, a );
|
||||||
|
}
|
||||||
|
catch(...)
|
||||||
|
{
|
||||||
|
D::operator_fn( p );
|
||||||
|
|
||||||
|
if( pi_ != 0 )
|
||||||
|
{
|
||||||
|
a2.deallocate( static_cast< impl_type* >( pi_ ), 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
|
||||||
|
|
||||||
|
if( pi_ != 0 )
|
||||||
|
{
|
||||||
|
new( static_cast< void* >( pi_ ) ) impl_type( p, a );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
D::operator_fn( p );
|
||||||
|
boost::throw_exception( std::bad_alloc() );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_NO_EXCEPTIONS
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
|
||||||
|
|
||||||
#ifndef BOOST_NO_AUTO_PTR
|
#ifndef BOOST_NO_AUTO_PTR
|
||||||
|
|
||||||
// auto_ptr<Y> is special cased to provide the strong guarantee
|
// auto_ptr<Y> is special cased to provide the strong guarantee
|
||||||
@@ -212,6 +339,33 @@ public:
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined( BOOST_NO_CXX11_SMART_PTR )
|
||||||
|
|
||||||
|
template<class Y, class D>
|
||||||
|
explicit shared_count( std::unique_ptr<Y, D> & r ): pi_( 0 )
|
||||||
|
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||||
|
, id_(shared_count_id)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
typedef typename sp_convert_reference<D>::type D2;
|
||||||
|
|
||||||
|
D2 d2( r.get_deleter() );
|
||||||
|
pi_ = new sp_counted_impl_pd< typename std::unique_ptr<Y, D>::pointer, D2 >( r.get(), d2 );
|
||||||
|
|
||||||
|
#ifdef BOOST_NO_EXCEPTIONS
|
||||||
|
|
||||||
|
if( pi_ == 0 )
|
||||||
|
{
|
||||||
|
boost::throw_exception( std::bad_alloc() );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
r.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
~shared_count() // nothrow
|
~shared_count() // nothrow
|
||||||
{
|
{
|
||||||
if( pi_ != 0 ) pi_->release();
|
if( pi_ != 0 ) pi_->release();
|
||||||
@@ -228,7 +382,7 @@ public:
|
|||||||
if( pi_ != 0 ) pi_->add_ref_copy();
|
if( pi_ != 0 ) pi_->add_ref_copy();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined( BOOST_HAS_RVALUE_REFS )
|
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||||
|
|
||||||
shared_count(shared_count && r): pi_(r.pi_) // nothrow
|
shared_count(shared_count && r): pi_(r.pi_) // nothrow
|
||||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||||
@@ -293,6 +447,11 @@ public:
|
|||||||
{
|
{
|
||||||
return pi_? pi_->get_deleter( ti ): 0;
|
return pi_? pi_->get_deleter( ti ): 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void * get_untyped_deleter() const
|
||||||
|
{
|
||||||
|
return pi_? pi_->get_untyped_deleter(): 0;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -335,7 +494,7 @@ public:
|
|||||||
|
|
||||||
// Move support
|
// Move support
|
||||||
|
|
||||||
#if defined( BOOST_HAS_RVALUE_REFS )
|
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||||
|
|
||||||
weak_count(weak_count && r): pi_(r.pi_) // nothrow
|
weak_count(weak_count && r): pi_(r.pi_) // nothrow
|
||||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||||
|
@@ -25,7 +25,7 @@
|
|||||||
# define BOOST_SP_NO_SP_CONVERTIBLE
|
# define BOOST_SP_NO_SP_CONVERTIBLE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( __BORLANDC__ ) && ( __BORLANDC__ <= 0x610 )
|
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( __BORLANDC__ ) && ( __BORLANDC__ < 0x630 )
|
||||||
# define BOOST_SP_NO_SP_CONVERTIBLE
|
# define BOOST_SP_NO_SP_CONVERTIBLE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -45,7 +45,22 @@ template< class Y, class T > struct sp_convertible
|
|||||||
static yes f( T* );
|
static yes f( T* );
|
||||||
static no f( ... );
|
static no f( ... );
|
||||||
|
|
||||||
enum _vt { value = sizeof( f( static_cast<Y*>(0) ) ) == sizeof(yes) };
|
enum _vt { value = sizeof( (f)( static_cast<Y*>(0) ) ) == sizeof(yes) };
|
||||||
|
};
|
||||||
|
|
||||||
|
template< class Y, class T > struct sp_convertible< Y, T[] >
|
||||||
|
{
|
||||||
|
enum _vt { value = false };
|
||||||
|
};
|
||||||
|
|
||||||
|
template< class Y, class T > struct sp_convertible< Y[], T[] >
|
||||||
|
{
|
||||||
|
enum _vt { value = sp_convertible< Y[1], T[1] >::value };
|
||||||
|
};
|
||||||
|
|
||||||
|
template< class Y, std::size_t N, class T > struct sp_convertible< Y[N], T[] >
|
||||||
|
{
|
||||||
|
enum _vt { value = sp_convertible< Y[1], T[1] >::value };
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sp_empty
|
struct sp_empty
|
||||||
|
@@ -32,22 +32,28 @@
|
|||||||
#elif defined( BOOST_DISABLE_THREADS ) && !defined( BOOST_SP_ENABLE_THREADS ) && !defined( BOOST_DISABLE_WIN32 )
|
#elif defined( BOOST_DISABLE_THREADS ) && !defined( BOOST_SP_ENABLE_THREADS ) && !defined( BOOST_DISABLE_WIN32 )
|
||||||
# include <boost/smart_ptr/detail/sp_counted_base_nt.hpp>
|
# include <boost/smart_ptr/detail/sp_counted_base_nt.hpp>
|
||||||
|
|
||||||
#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) )
|
#elif defined( __SNC__ )
|
||||||
# include <boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp>
|
# include <boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp>
|
||||||
|
|
||||||
#elif defined( __GNUC__ ) && defined( __ia64__ ) && !defined( __INTEL_COMPILER )
|
#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) && !defined(__PATHSCALE__)
|
||||||
# include <boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp>
|
# include <boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp>
|
||||||
|
|
||||||
#elif defined(__HP_aCC) && defined(__ia64)
|
#elif defined(__HP_aCC) && defined(__ia64)
|
||||||
# include <boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp>
|
# include <boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp>
|
||||||
|
|
||||||
|
#elif defined( __GNUC__ ) && defined( __ia64__ ) && !defined( __INTEL_COMPILER ) && !defined(__PATHSCALE__)
|
||||||
|
# include <boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp>
|
||||||
|
|
||||||
|
#elif defined( __IBMCPP__ ) && defined( __powerpc )
|
||||||
|
# include <boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp>
|
||||||
|
|
||||||
#elif defined( __MWERKS__ ) && defined( __POWERPC__ )
|
#elif defined( __MWERKS__ ) && defined( __POWERPC__ )
|
||||||
# include <boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp>
|
# include <boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp>
|
||||||
|
|
||||||
#elif defined( __GNUC__ ) && ( defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc ) )
|
#elif defined( __GNUC__ ) && ( defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc ) ) && !defined(__PATHSCALE__) && !defined( _AIX )
|
||||||
# include <boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp>
|
# include <boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp>
|
||||||
|
|
||||||
#elif defined( __GNUC__ ) && ( defined( __mips__ ) || defined( _mips ) )
|
#elif defined( __GNUC__ ) && ( defined( __mips__ ) || defined( _mips ) ) && !defined(__PATHSCALE__)
|
||||||
# include <boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp>
|
# include <boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp>
|
||||||
|
|
||||||
#elif defined( BOOST_SP_HAS_SYNC )
|
#elif defined( BOOST_SP_HAS_SYNC )
|
||||||
@@ -59,6 +65,9 @@
|
|||||||
#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined(__CYGWIN__)
|
#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined(__CYGWIN__)
|
||||||
# include <boost/smart_ptr/detail/sp_counted_base_w32.hpp>
|
# include <boost/smart_ptr/detail/sp_counted_base_w32.hpp>
|
||||||
|
|
||||||
|
#elif defined( _AIX )
|
||||||
|
# include <boost/smart_ptr/detail/sp_counted_base_aix.hpp>
|
||||||
|
|
||||||
#elif !defined( BOOST_HAS_THREADS )
|
#elif !defined( BOOST_HAS_THREADS )
|
||||||
# include <boost/smart_ptr/detail/sp_counted_base_nt.hpp>
|
# include <boost/smart_ptr/detail/sp_counted_base_nt.hpp>
|
||||||
|
|
||||||
|
@@ -104,6 +104,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||||
|
virtual void * get_untyped_deleter() = 0;
|
||||||
|
|
||||||
void add_ref_copy()
|
void add_ref_copy()
|
||||||
{
|
{
|
||||||
|
143
include/boost/smart_ptr/detail/sp_counted_base_aix.hpp
Normal file
143
include/boost/smart_ptr/detail/sp_counted_base_aix.hpp
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_AIX_HPP_INCLUDED
|
||||||
|
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_AIX_HPP_INCLUDED
|
||||||
|
|
||||||
|
//
|
||||||
|
// detail/sp_counted_base_aix.hpp
|
||||||
|
// based on: detail/sp_counted_base_w32.hpp
|
||||||
|
//
|
||||||
|
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
|
||||||
|
// Copyright 2004-2005 Peter Dimov
|
||||||
|
// Copyright 2006 Michael van der Westhuizen
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See
|
||||||
|
// accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Lock-free algorithm by Alexander Terekhov
|
||||||
|
//
|
||||||
|
// Thanks to Ben Hitchings for the #weak + (#shared != 0)
|
||||||
|
// formulation
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/detail/sp_typeinfo.hpp>
|
||||||
|
#include <builtins.h>
|
||||||
|
#include <sys/atomic_op.h>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
inline void atomic_increment( int32_t* pw )
|
||||||
|
{
|
||||||
|
// ++*pw;
|
||||||
|
|
||||||
|
fetch_and_add( pw, 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int32_t atomic_decrement( int32_t * pw )
|
||||||
|
{
|
||||||
|
// return --*pw;
|
||||||
|
|
||||||
|
int32_t originalValue;
|
||||||
|
|
||||||
|
__lwsync();
|
||||||
|
originalValue = fetch_and_add( pw, -1 );
|
||||||
|
__isync();
|
||||||
|
|
||||||
|
return (originalValue - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int32_t atomic_conditional_increment( int32_t * pw )
|
||||||
|
{
|
||||||
|
// if( *pw != 0 ) ++*pw;
|
||||||
|
// return *pw;
|
||||||
|
|
||||||
|
int32_t tmp = fetch_and_add( pw, 0 );
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
if( tmp == 0 ) return 0;
|
||||||
|
if( compare_and_swap( pw, &tmp, tmp + 1 ) ) return (tmp + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class sp_counted_base
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
sp_counted_base( sp_counted_base const & );
|
||||||
|
sp_counted_base & operator= ( sp_counted_base const & );
|
||||||
|
|
||||||
|
int32_t use_count_; // #shared
|
||||||
|
int32_t weak_count_; // #weak + (#shared != 0)
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~sp_counted_base() // nothrow
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// dispose() is called when use_count_ drops to zero, to release
|
||||||
|
// the resources managed by *this.
|
||||||
|
|
||||||
|
virtual void dispose() = 0; // nothrow
|
||||||
|
|
||||||
|
// destroy() is called when weak_count_ drops to zero.
|
||||||
|
|
||||||
|
virtual void destroy() // nothrow
|
||||||
|
{
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||||
|
virtual void * get_untyped_deleter() = 0;
|
||||||
|
|
||||||
|
void add_ref_copy()
|
||||||
|
{
|
||||||
|
atomic_increment( &use_count_ );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool add_ref_lock() // true on success
|
||||||
|
{
|
||||||
|
return atomic_conditional_increment( &use_count_ ) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void release() // nothrow
|
||||||
|
{
|
||||||
|
if( atomic_decrement( &use_count_ ) == 0 )
|
||||||
|
{
|
||||||
|
dispose();
|
||||||
|
weak_release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void weak_add_ref() // nothrow
|
||||||
|
{
|
||||||
|
atomic_increment( &weak_count_ );
|
||||||
|
}
|
||||||
|
|
||||||
|
void weak_release() // nothrow
|
||||||
|
{
|
||||||
|
if( atomic_decrement( &weak_count_ ) == 0 )
|
||||||
|
{
|
||||||
|
destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
long use_count() const // nothrow
|
||||||
|
{
|
||||||
|
return fetch_and_add( const_cast<int32_t*>(&use_count_), 0 );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_AIX_HPP_INCLUDED
|
@@ -124,6 +124,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||||
|
virtual void * get_untyped_deleter() = 0;
|
||||||
|
|
||||||
void add_ref_copy()
|
void add_ref_copy()
|
||||||
{
|
{
|
||||||
|
@@ -112,6 +112,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||||
|
virtual void * get_untyped_deleter() = 0;
|
||||||
|
|
||||||
void add_ref_copy()
|
void add_ref_copy()
|
||||||
{
|
{
|
||||||
|
@@ -111,6 +111,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||||
|
virtual void * get_untyped_deleter() = 0;
|
||||||
|
|
||||||
void add_ref_copy()
|
void add_ref_copy()
|
||||||
{
|
{
|
||||||
|
@@ -37,9 +37,12 @@ inline void atomic_increment( int * pw )
|
|||||||
__asm__ __volatile__
|
__asm__ __volatile__
|
||||||
(
|
(
|
||||||
"0:\n\t"
|
"0:\n\t"
|
||||||
|
".set push\n\t"
|
||||||
|
".set mips2\n\t"
|
||||||
"ll %0, %1\n\t"
|
"ll %0, %1\n\t"
|
||||||
"addiu %0, 1\n\t"
|
"addiu %0, 1\n\t"
|
||||||
"sc %0, %1\n\t"
|
"sc %0, %1\n\t"
|
||||||
|
".set pop\n\t"
|
||||||
"beqz %0, 0b":
|
"beqz %0, 0b":
|
||||||
"=&r"( tmp ), "=m"( *pw ):
|
"=&r"( tmp ), "=m"( *pw ):
|
||||||
"m"( *pw )
|
"m"( *pw )
|
||||||
@@ -55,9 +58,12 @@ inline int atomic_decrement( int * pw )
|
|||||||
__asm__ __volatile__
|
__asm__ __volatile__
|
||||||
(
|
(
|
||||||
"0:\n\t"
|
"0:\n\t"
|
||||||
|
".set push\n\t"
|
||||||
|
".set mips2\n\t"
|
||||||
"ll %1, %2\n\t"
|
"ll %1, %2\n\t"
|
||||||
"addiu %0, %1, -1\n\t"
|
"addiu %0, %1, -1\n\t"
|
||||||
"sc %0, %2\n\t"
|
"sc %0, %2\n\t"
|
||||||
|
".set pop\n\t"
|
||||||
"beqz %0, 0b\n\t"
|
"beqz %0, 0b\n\t"
|
||||||
"addiu %0, %1, -1":
|
"addiu %0, %1, -1":
|
||||||
"=&r"( rv ), "=&r"( tmp ), "=m"( *pw ):
|
"=&r"( rv ), "=&r"( tmp ), "=m"( *pw ):
|
||||||
@@ -78,10 +84,13 @@ inline int atomic_conditional_increment( int * pw )
|
|||||||
__asm__ __volatile__
|
__asm__ __volatile__
|
||||||
(
|
(
|
||||||
"0:\n\t"
|
"0:\n\t"
|
||||||
|
".set push\n\t"
|
||||||
|
".set mips2\n\t"
|
||||||
"ll %0, %2\n\t"
|
"ll %0, %2\n\t"
|
||||||
"beqz %0, 1f\n\t"
|
"beqz %0, 1f\n\t"
|
||||||
"addiu %1, %0, 1\n\t"
|
"addiu %1, %0, 1\n\t"
|
||||||
"sc %1, %2\n\t"
|
"sc %1, %2\n\t"
|
||||||
|
".set pop\n\t"
|
||||||
"beqz %1, 0b\n\t"
|
"beqz %1, 0b\n\t"
|
||||||
"addiu %0, %0, 1\n\t"
|
"addiu %0, %0, 1\n\t"
|
||||||
"1:":
|
"1:":
|
||||||
@@ -126,6 +135,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||||
|
virtual void * get_untyped_deleter() = 0;
|
||||||
|
|
||||||
void add_ref_copy()
|
void add_ref_copy()
|
||||||
{
|
{
|
||||||
|
@@ -135,6 +135,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||||
|
virtual void * get_untyped_deleter() = 0;
|
||||||
|
|
||||||
void add_ref_copy()
|
void add_ref_copy()
|
||||||
{
|
{
|
||||||
|
@@ -30,9 +30,9 @@ namespace detail
|
|||||||
|
|
||||||
inline int32_t compare_and_swap( int32_t * dest_, int32_t compare_, int32_t swap_ )
|
inline int32_t compare_and_swap( int32_t * dest_, int32_t compare_, int32_t swap_ )
|
||||||
{
|
{
|
||||||
__asm__ __volatile__( "cas %0, %2, %1"
|
__asm__ __volatile__( "cas [%1], %2, %0"
|
||||||
: "+m" (*dest_), "+r" (swap_)
|
: "+r" (swap_)
|
||||||
: "r" (compare_)
|
: "r" (dest_), "r" (compare_)
|
||||||
: "memory" );
|
: "memory" );
|
||||||
|
|
||||||
return swap_;
|
return swap_;
|
||||||
@@ -120,6 +120,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||||
|
virtual void * get_untyped_deleter() = 0;
|
||||||
|
|
||||||
void add_ref_copy()
|
void add_ref_copy()
|
||||||
{
|
{
|
||||||
|
@@ -127,6 +127,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||||
|
virtual void * get_untyped_deleter() = 0;
|
||||||
|
|
||||||
void add_ref_copy()
|
void add_ref_copy()
|
||||||
{
|
{
|
||||||
|
@@ -59,6 +59,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||||
|
virtual void * get_untyped_deleter() = 0;
|
||||||
|
|
||||||
void add_ref_copy()
|
void add_ref_copy()
|
||||||
{
|
{
|
||||||
|
@@ -70,6 +70,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||||
|
virtual void * get_untyped_deleter() = 0;
|
||||||
|
|
||||||
void add_ref_copy()
|
void add_ref_copy()
|
||||||
{
|
{
|
||||||
|
162
include/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp
Normal file
162
include/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp
Normal file
@@ -0,0 +1,162 @@
|
|||||||
|
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SNC_PS3_HPP_INCLUDED
|
||||||
|
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SNC_PS3_HPP_INCLUDED
|
||||||
|
|
||||||
|
// MS compatible compilers support #pragma once
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||||
|
# pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// detail/sp_counted_base_gcc_sparc.hpp - g++ on Sparc V8+
|
||||||
|
//
|
||||||
|
// Copyright (c) 2006 Piotr Wyderski
|
||||||
|
// Copyright (c) 2006 Tomas Puverle
|
||||||
|
// Copyright (c) 2006 Peter Dimov
|
||||||
|
// Copyright (c) 2011 Emil Dotchevski
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
//
|
||||||
|
// Thanks to Michael van der Westhuizen
|
||||||
|
|
||||||
|
#include <boost/detail/sp_typeinfo.hpp>
|
||||||
|
#include <inttypes.h> // uint32_t
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
inline uint32_t compare_and_swap( uint32_t * dest_, uint32_t compare_, uint32_t swap_ )
|
||||||
|
{
|
||||||
|
return __builtin_cellAtomicCompareAndSwap32(dest_,compare_,swap_);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint32_t atomic_fetch_and_add( uint32_t * pw, uint32_t dv )
|
||||||
|
{
|
||||||
|
// long r = *pw;
|
||||||
|
// *pw += dv;
|
||||||
|
// return r;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
uint32_t r = *pw;
|
||||||
|
|
||||||
|
if( __builtin_expect((compare_and_swap(pw, r, r + dv) == r), 1) )
|
||||||
|
{
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void atomic_increment( uint32_t * pw )
|
||||||
|
{
|
||||||
|
(void) __builtin_cellAtomicIncr32( pw );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint32_t atomic_decrement( uint32_t * pw )
|
||||||
|
{
|
||||||
|
return __builtin_cellAtomicDecr32( pw );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint32_t atomic_conditional_increment( uint32_t * pw )
|
||||||
|
{
|
||||||
|
// long r = *pw;
|
||||||
|
// if( r != 0 ) ++*pw;
|
||||||
|
// return r;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
uint32_t r = *pw;
|
||||||
|
|
||||||
|
if( r == 0 )
|
||||||
|
{
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( __builtin_expect( ( compare_and_swap( pw, r, r + 1 ) == r ), 1 ) )
|
||||||
|
{
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class sp_counted_base
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
sp_counted_base( sp_counted_base const & );
|
||||||
|
sp_counted_base & operator= ( sp_counted_base const & );
|
||||||
|
|
||||||
|
uint32_t use_count_; // #shared
|
||||||
|
uint32_t weak_count_; // #weak + (#shared != 0)
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~sp_counted_base() // nothrow
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// dispose() is called when use_count_ drops to zero, to release
|
||||||
|
// the resources managed by *this.
|
||||||
|
|
||||||
|
virtual void dispose() = 0; // nothrow
|
||||||
|
|
||||||
|
// destroy() is called when weak_count_ drops to zero.
|
||||||
|
|
||||||
|
virtual void destroy() // nothrow
|
||||||
|
{
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||||
|
virtual void * get_untyped_deleter() = 0;
|
||||||
|
|
||||||
|
void add_ref_copy()
|
||||||
|
{
|
||||||
|
atomic_increment( &use_count_ );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool add_ref_lock() // true on success
|
||||||
|
{
|
||||||
|
return atomic_conditional_increment( &use_count_ ) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void release() // nothrow
|
||||||
|
{
|
||||||
|
if( atomic_decrement( &use_count_ ) == 1 )
|
||||||
|
{
|
||||||
|
dispose();
|
||||||
|
weak_release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void weak_add_ref() // nothrow
|
||||||
|
{
|
||||||
|
atomic_increment( &weak_count_ );
|
||||||
|
}
|
||||||
|
|
||||||
|
void weak_release() // nothrow
|
||||||
|
{
|
||||||
|
if( atomic_decrement( &weak_count_ ) == 1 )
|
||||||
|
{
|
||||||
|
destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
long use_count() const // nothrow
|
||||||
|
{
|
||||||
|
return const_cast< uint32_t const volatile & >( use_count_ );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SNC_PS3_HPP_INCLUDED
|
@@ -62,6 +62,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||||
|
virtual void * get_untyped_deleter() = 0;
|
||||||
|
|
||||||
void add_ref_copy()
|
void add_ref_copy()
|
||||||
{
|
{
|
||||||
|
@@ -84,6 +84,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||||
|
virtual void * get_untyped_deleter() = 0;
|
||||||
|
|
||||||
void add_ref_copy()
|
void add_ref_copy()
|
||||||
{
|
{
|
||||||
|
@@ -109,6 +109,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||||
|
virtual void * get_untyped_deleter() = 0;
|
||||||
|
|
||||||
void add_ref_copy()
|
void add_ref_copy()
|
||||||
{
|
{
|
||||||
|
151
include/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp
Normal file
151
include/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_VACPP_PPC_HPP_INCLUDED
|
||||||
|
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_VACPP_PPC_HPP_INCLUDED
|
||||||
|
|
||||||
|
//
|
||||||
|
// detail/sp_counted_base_vacpp_ppc.hpp - xlC(vacpp) on POWER
|
||||||
|
// based on: detail/sp_counted_base_w32.hpp
|
||||||
|
//
|
||||||
|
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
|
||||||
|
// Copyright 2004-2005 Peter Dimov
|
||||||
|
// Copyright 2006 Michael van der Westhuizen
|
||||||
|
// Copyright 2012 IBM Corp.
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See
|
||||||
|
// accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Lock-free algorithm by Alexander Terekhov
|
||||||
|
//
|
||||||
|
// Thanks to Ben Hitchings for the #weak + (#shared != 0)
|
||||||
|
// formulation
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/detail/sp_typeinfo.hpp>
|
||||||
|
|
||||||
|
extern "builtin" void __lwsync(void);
|
||||||
|
extern "builtin" void __isync(void);
|
||||||
|
extern "builtin" int __fetch_and_add(volatile int* addr, int val);
|
||||||
|
extern "builtin" int __compare_and_swap(volatile int*, int*, int);
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
inline void atomic_increment( int *pw )
|
||||||
|
{
|
||||||
|
// ++*pw;
|
||||||
|
__lwsync();
|
||||||
|
__fetch_and_add(pw, 1);
|
||||||
|
__isync();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int atomic_decrement( int *pw )
|
||||||
|
{
|
||||||
|
// return --*pw;
|
||||||
|
__lwsync();
|
||||||
|
int originalValue = __fetch_and_add(pw, -1);
|
||||||
|
__isync();
|
||||||
|
|
||||||
|
return (originalValue - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int atomic_conditional_increment( int *pw )
|
||||||
|
{
|
||||||
|
// if( *pw != 0 ) ++*pw;
|
||||||
|
// return *pw;
|
||||||
|
|
||||||
|
__lwsync();
|
||||||
|
int v = *const_cast<volatile int*>(pw);
|
||||||
|
for (;;)
|
||||||
|
// loop until state is known
|
||||||
|
{
|
||||||
|
if (v == 0) return 0;
|
||||||
|
if (__compare_and_swap(pw, &v, v + 1))
|
||||||
|
{
|
||||||
|
__isync(); return (v + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
char pad[64] __attribute__((__aligned__(64)));
|
||||||
|
// pad to prevent false sharing
|
||||||
|
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;
|
||||||
|
virtual void * get_untyped_deleter() = 0;
|
||||||
|
|
||||||
|
void add_ref_copy()
|
||||||
|
{
|
||||||
|
atomic_increment( &use_count_ );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool add_ref_lock() // true on success
|
||||||
|
{
|
||||||
|
return atomic_conditional_increment( &use_count_ ) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void release() // nothrow
|
||||||
|
{
|
||||||
|
if( atomic_decrement( &use_count_ ) == 0 )
|
||||||
|
{
|
||||||
|
dispose();
|
||||||
|
weak_release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void weak_add_ref() // nothrow
|
||||||
|
{
|
||||||
|
atomic_increment( &weak_count_ );
|
||||||
|
}
|
||||||
|
|
||||||
|
void weak_release() // nothrow
|
||||||
|
{
|
||||||
|
if( atomic_decrement( &weak_count_ ) == 0 )
|
||||||
|
{
|
||||||
|
destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
long use_count() const // nothrow
|
||||||
|
{
|
||||||
|
return *const_cast<volatile int*>(&use_count_);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_VACPP_PPC_HPP_INCLUDED
|
@@ -67,6 +67,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||||
|
virtual void * get_untyped_deleter() = 0;
|
||||||
|
|
||||||
void add_ref_copy()
|
void add_ref_copy()
|
||||||
{
|
{
|
||||||
|
@@ -83,6 +83,11 @@ public:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void * get_untyped_deleter()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(BOOST_SP_USE_STD_ALLOCATOR)
|
#if defined(BOOST_SP_USE_STD_ALLOCATOR)
|
||||||
|
|
||||||
void * operator new( std::size_t )
|
void * operator new( std::size_t )
|
||||||
@@ -135,7 +140,11 @@ public:
|
|||||||
|
|
||||||
// pre: d(p) must not throw
|
// pre: d(p) must not throw
|
||||||
|
|
||||||
sp_counted_impl_pd( P p, D d ): ptr(p), del(d)
|
sp_counted_impl_pd( P p, D & d ): ptr( p ), del( d )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
sp_counted_impl_pd( P p ): ptr( p ), del()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,6 +158,11 @@ public:
|
|||||||
return ti == BOOST_SP_TYPEID(D)? &reinterpret_cast<char&>( del ): 0;
|
return ti == BOOST_SP_TYPEID(D)? &reinterpret_cast<char&>( del ): 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void * get_untyped_deleter()
|
||||||
|
{
|
||||||
|
return &reinterpret_cast<char&>( del );
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(BOOST_SP_USE_STD_ALLOCATOR)
|
#if defined(BOOST_SP_USE_STD_ALLOCATOR)
|
||||||
|
|
||||||
void * operator new( std::size_t )
|
void * operator new( std::size_t )
|
||||||
@@ -195,7 +209,11 @@ public:
|
|||||||
|
|
||||||
// pre: d( p ) must not throw
|
// pre: d( p ) must not throw
|
||||||
|
|
||||||
sp_counted_impl_pda( P p, D d, A a ): p_( p ), d_( d ), a_( a )
|
sp_counted_impl_pda( P p, D & d, A a ): p_( p ), d_( d ), a_( a )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
sp_counted_impl_pda( P p, A a ): p_( p ), d_(), a_( a )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -218,6 +236,11 @@ public:
|
|||||||
{
|
{
|
||||||
return ti == BOOST_SP_TYPEID( D )? &reinterpret_cast<char&>( d_ ): 0;
|
return ti == BOOST_SP_TYPEID( D )? &reinterpret_cast<char&>( d_ ): 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void * get_untyped_deleter()
|
||||||
|
{
|
||||||
|
return &reinterpret_cast<char&>( d_ );
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef __CODEGUARD__
|
#ifdef __CODEGUARD__
|
||||||
|
39
include/boost/smart_ptr/detail/sp_forward.hpp
Normal file
39
include/boost/smart_ptr/detail/sp_forward.hpp
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
#ifndef BOOST_SMART_PTR_DETAIL_SP_FORWARD_HPP_INCLUDED
|
||||||
|
#define BOOST_SMART_PTR_DETAIL_SP_FORWARD_HPP_INCLUDED
|
||||||
|
|
||||||
|
// MS compatible compilers support #pragma once
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||||
|
# pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// detail/sp_forward.hpp
|
||||||
|
//
|
||||||
|
// Copyright 2008,2012 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||||
|
|
||||||
|
template< class T > T&& sp_forward( T & t ) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
return static_cast< T&& >( t );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_FORWARD_HPP_INCLUDED
|
@@ -20,7 +20,17 @@
|
|||||||
// are available.
|
// are available.
|
||||||
//
|
//
|
||||||
|
|
||||||
#if defined(__GNUC__) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 )
|
#ifndef BOOST_SP_NO_SYNC
|
||||||
|
|
||||||
|
#if defined( __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 )
|
||||||
|
|
||||||
|
# define BOOST_SP_HAS_SYNC
|
||||||
|
|
||||||
|
#elif defined( __IBMCPP__ ) && ( __IBMCPP__ >= 1210 )
|
||||||
|
|
||||||
|
# define BOOST_SP_HAS_SYNC
|
||||||
|
|
||||||
|
#elif defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 )
|
||||||
|
|
||||||
#define BOOST_SP_HAS_SYNC
|
#define BOOST_SP_HAS_SYNC
|
||||||
|
|
||||||
@@ -36,14 +46,24 @@
|
|||||||
#undef BOOST_SP_HAS_SYNC
|
#undef BOOST_SP_HAS_SYNC
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined( __sh__ )
|
||||||
|
#undef BOOST_SP_HAS_SYNC
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined( __sparc__ )
|
#if defined( __sparc__ )
|
||||||
#undef BOOST_SP_HAS_SYNC
|
#undef BOOST_SP_HAS_SYNC
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined( __INTEL_COMPILER ) && !defined( __ia64__ )
|
#if defined( __INTEL_COMPILER ) && !defined( __ia64__ ) && ( __INTEL_COMPILER < 1110 )
|
||||||
#undef BOOST_SP_HAS_SYNC
|
#undef BOOST_SP_HAS_SYNC
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // __GNUC__ * 100 + __GNUC_MINOR__ >= 401
|
#if defined(__PATHSCALE__) && ((__PATHCC__ == 4) && (__PATHCC_MINOR__ < 9))
|
||||||
|
#undef BOOST_SP_HAS_SYNC
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_SP_NO_SYNC
|
||||||
|
|
||||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_HPP_INCLUDED
|
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_HPP_INCLUDED
|
||||||
|
31
include/boost/smart_ptr/detail/sp_if_array.hpp
Normal file
31
include/boost/smart_ptr/detail/sp_if_array.hpp
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2012 Glen Joseph Fernandes
|
||||||
|
* glenfe at live dot com
|
||||||
|
*
|
||||||
|
* Distributed under the Boost Software License,
|
||||||
|
* Version 1.0. (See accompanying file LICENSE_1_0.txt
|
||||||
|
* or copy at http://boost.org/LICENSE_1_0.txt)
|
||||||
|
*/
|
||||||
|
#ifndef BOOST_SMART_PTR_DETAIL_SP_IF_ARRAY_HPP
|
||||||
|
#define BOOST_SMART_PTR_DETAIL_SP_IF_ARRAY_HPP
|
||||||
|
|
||||||
|
#include <boost/smart_ptr/shared_ptr.hpp>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace detail {
|
||||||
|
template<typename T>
|
||||||
|
struct sp_if_array;
|
||||||
|
template<typename T>
|
||||||
|
struct sp_if_array<T[]> {
|
||||||
|
typedef boost::shared_ptr<T[]> type;
|
||||||
|
};
|
||||||
|
template<typename T>
|
||||||
|
struct sp_if_size_array;
|
||||||
|
template<typename T, std::size_t N>
|
||||||
|
struct sp_if_size_array<T[N]> {
|
||||||
|
typedef boost::shared_ptr<T[N]> type;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
45
include/boost/smart_ptr/detail/sp_nullptr_t.hpp
Normal file
45
include/boost/smart_ptr/detail/sp_nullptr_t.hpp
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
#ifndef BOOST_SMART_PTR_DETAIL_SP_NULLPTR_T_HPP_INCLUDED
|
||||||
|
#define BOOST_SMART_PTR_DETAIL_SP_NULLPTR_T_HPP_INCLUDED
|
||||||
|
|
||||||
|
// MS compatible compilers support #pragma once
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||||
|
# pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// detail/sp_nullptr_t.hpp
|
||||||
|
//
|
||||||
|
// Copyright 2013 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
#if !defined( BOOST_NO_CXX11_NULLPTR )
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
#if defined( __clang__ ) && !defined( _LIBCPP_VERSION ) && !defined( BOOST_NO_CXX11_DECLTYPE )
|
||||||
|
|
||||||
|
typedef decltype(nullptr) sp_nullptr_t;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
typedef std::nullptr_t sp_nullptr_t;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // !defined( BOOST_NO_CXX11_NULLPTR )
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_NULLPTR_T_HPP_INCLUDED
|
@@ -31,7 +31,10 @@
|
|||||||
#include <boost/config.hpp>
|
#include <boost/config.hpp>
|
||||||
#include <boost/smart_ptr/detail/sp_has_sync.hpp>
|
#include <boost/smart_ptr/detail/sp_has_sync.hpp>
|
||||||
|
|
||||||
#if defined(__GNUC__) && defined( __arm__ ) && !defined( __thumb__ )
|
#if defined( BOOST_SP_USE_PTHREADS )
|
||||||
|
# include <boost/smart_ptr/detail/spinlock_pt.hpp>
|
||||||
|
|
||||||
|
#elif defined(__GNUC__) && defined( __arm__ ) && !defined( __thumb__ )
|
||||||
# include <boost/smart_ptr/detail/spinlock_gcc_arm.hpp>
|
# include <boost/smart_ptr/detail/spinlock_gcc_arm.hpp>
|
||||||
|
|
||||||
#elif defined( BOOST_SP_HAS_SYNC )
|
#elif defined( BOOST_SP_HAS_SYNC )
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
#define BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
|
#define BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
|
||||||
|
|
||||||
//
|
//
|
||||||
// Copyright (c) 2008 Peter Dimov
|
// Copyright (c) 2008, 2011 Peter Dimov
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0.
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
// See accompanying file LICENSE_1_0.txt or copy at
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
@@ -11,6 +11,22 @@
|
|||||||
|
|
||||||
#include <boost/smart_ptr/detail/yield_k.hpp>
|
#include <boost/smart_ptr/detail/yield_k.hpp>
|
||||||
|
|
||||||
|
#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_7S__)
|
||||||
|
|
||||||
|
# define BOOST_SP_ARM_BARRIER "dmb"
|
||||||
|
# define BOOST_SP_ARM_HAS_LDREX
|
||||||
|
|
||||||
|
#elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__)
|
||||||
|
|
||||||
|
# define BOOST_SP_ARM_BARRIER "mcr p15, 0, r0, c7, c10, 5"
|
||||||
|
# define BOOST_SP_ARM_HAS_LDREX
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
# define BOOST_SP_ARM_BARRIER ""
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -29,12 +45,28 @@ public:
|
|||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
#ifdef BOOST_SP_ARM_HAS_LDREX
|
||||||
|
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
"swp %0, %1, [%2]":
|
"ldrex %0, [%2]; \n"
|
||||||
|
"cmp %0, %1; \n"
|
||||||
|
"strexne %0, %1, [%2]; \n"
|
||||||
|
BOOST_SP_ARM_BARRIER :
|
||||||
"=&r"( r ): // outputs
|
"=&r"( r ): // outputs
|
||||||
"r"( 1 ), "r"( &v_ ): // inputs
|
"r"( 1 ), "r"( &v_ ): // inputs
|
||||||
"memory", "cc" );
|
"memory", "cc" );
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
__asm__ __volatile__(
|
||||||
|
"swp %0, %1, [%2];\n"
|
||||||
|
BOOST_SP_ARM_BARRIER :
|
||||||
|
"=&r"( r ): // outputs
|
||||||
|
"r"( 1 ), "r"( &v_ ): // inputs
|
||||||
|
"memory", "cc" );
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
return r == 0;
|
return r == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,7 +80,7 @@ public:
|
|||||||
|
|
||||||
void unlock()
|
void unlock()
|
||||||
{
|
{
|
||||||
__asm__ __volatile__( "" ::: "memory" );
|
__asm__ __volatile__( BOOST_SP_ARM_BARRIER ::: "memory" );
|
||||||
*const_cast< int volatile* >( &v_ ) = 0;
|
*const_cast< int volatile* >( &v_ ) = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,4 +114,7 @@ public:
|
|||||||
|
|
||||||
#define BOOST_DETAIL_SPINLOCK_INIT {0}
|
#define BOOST_DETAIL_SPINLOCK_INIT {0}
|
||||||
|
|
||||||
|
#undef BOOST_SP_ARM_BARRIER
|
||||||
|
#undef BOOST_SP_ARM_HAS_LDREX
|
||||||
|
|
||||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
|
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
|
||||||
|
@@ -41,7 +41,11 @@ public:
|
|||||||
|
|
||||||
static spinlock & spinlock_for( void const * pv )
|
static spinlock & spinlock_for( void const * pv )
|
||||||
{
|
{
|
||||||
|
#if defined(__VMS) && __INITIAL_POINTER_SIZE == 64
|
||||||
|
std::size_t i = reinterpret_cast< unsigned long long >( pv ) % 41;
|
||||||
|
#else
|
||||||
std::size_t i = reinterpret_cast< std::size_t >( pv ) % 41;
|
std::size_t i = reinterpret_cast< std::size_t >( pv ) % 41;
|
||||||
|
#endif
|
||||||
return pool_[ i ];
|
return pool_[ i ];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -30,7 +30,6 @@
|
|||||||
#if defined(_MSC_VER) && _MSC_VER >= 1310 && ( defined(_M_IX86) || defined(_M_X64) )
|
#if defined(_MSC_VER) && _MSC_VER >= 1310 && ( defined(_M_IX86) || defined(_M_X64) )
|
||||||
|
|
||||||
extern "C" void _mm_pause();
|
extern "C" void _mm_pause();
|
||||||
#pragma intrinsic( _mm_pause )
|
|
||||||
|
|
||||||
#define BOOST_SMT_PAUSE _mm_pause();
|
#define BOOST_SMT_PAUSE _mm_pause();
|
||||||
|
|
||||||
@@ -55,7 +54,7 @@ namespace detail
|
|||||||
{
|
{
|
||||||
|
|
||||||
#if !defined( BOOST_USE_WINDOWS_H )
|
#if !defined( BOOST_USE_WINDOWS_H )
|
||||||
extern "C" void __stdcall Sleep( unsigned ms );
|
extern "C" void __stdcall Sleep( unsigned long ms );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
inline void yield( unsigned k )
|
inline void yield( unsigned k )
|
||||||
|
144
include/boost/smart_ptr/enable_shared_from_raw.hpp
Normal file
144
include/boost/smart_ptr/enable_shared_from_raw.hpp
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
#ifndef BOOST_ENABLE_SHARED_FROM_RAW_HPP_INCLUDED
|
||||||
|
#define BOOST_ENABLE_SHARED_FROM_RAW_HPP_INCLUDED
|
||||||
|
|
||||||
|
//
|
||||||
|
// enable_shared_from_raw.hpp
|
||||||
|
//
|
||||||
|
// Copyright 2002, 2009 Peter Dimov
|
||||||
|
// Copyright 2008-2009 Frank Mori Hess
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
#include <boost/weak_ptr.hpp>
|
||||||
|
#include <boost/assert.hpp>
|
||||||
|
#include <boost/detail/workaround.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
template<typename T> boost::shared_ptr<T> shared_from_raw(T *);
|
||||||
|
template<typename T> boost::weak_ptr<T> weak_from_raw(T *);
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
template< class X, class Y > inline void sp_enable_shared_from_this( boost::shared_ptr<X> * ppx, Y const * py, boost::enable_shared_from_raw const * pe );
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
class enable_shared_from_raw
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
enable_shared_from_raw()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
enable_shared_from_raw( enable_shared_from_raw const & )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
enable_shared_from_raw & operator=( enable_shared_from_raw const & )
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
~enable_shared_from_raw()
|
||||||
|
{
|
||||||
|
BOOST_ASSERT( shared_this_.use_count() <= 1 ); // make sure no dangling shared_ptr objects exist
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void init_weak_once() const
|
||||||
|
{
|
||||||
|
if( weak_this_.expired() )
|
||||||
|
{
|
||||||
|
shared_this_.reset( static_cast<void*>(0), detail::esft2_deleter_wrapper() );
|
||||||
|
weak_this_ = shared_this_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
|
||||||
|
public:
|
||||||
|
#else
|
||||||
|
private:
|
||||||
|
template<class Y> friend class shared_ptr;
|
||||||
|
template<typename T> friend boost::shared_ptr<T> shared_from_raw(T *);
|
||||||
|
template<typename T> friend boost::weak_ptr<T> weak_from_raw(T *);
|
||||||
|
template< class X, class Y > friend inline void detail::sp_enable_shared_from_this( boost::shared_ptr<X> * ppx, Y const * py, boost::enable_shared_from_raw const * pe );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
shared_ptr<void> shared_from_this()
|
||||||
|
{
|
||||||
|
init_weak_once();
|
||||||
|
return shared_ptr<void>( weak_this_ );
|
||||||
|
}
|
||||||
|
|
||||||
|
shared_ptr<const void> shared_from_this() const
|
||||||
|
{
|
||||||
|
init_weak_once();
|
||||||
|
return shared_ptr<const void>( weak_this_ );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: invoked automatically by shared_ptr; do not call
|
||||||
|
template<class X, class Y> void _internal_accept_owner( shared_ptr<X> * ppx, Y * py ) const
|
||||||
|
{
|
||||||
|
BOOST_ASSERT( ppx != 0 );
|
||||||
|
|
||||||
|
if( weak_this_.expired() )
|
||||||
|
{
|
||||||
|
weak_this_ = *ppx;
|
||||||
|
}
|
||||||
|
else if( shared_this_.use_count() != 0 )
|
||||||
|
{
|
||||||
|
BOOST_ASSERT( ppx->unique() ); // no weak_ptrs should exist either, but there's no way to check that
|
||||||
|
|
||||||
|
detail::esft2_deleter_wrapper * pd = boost::get_deleter<detail::esft2_deleter_wrapper>( shared_this_ );
|
||||||
|
BOOST_ASSERT( pd != 0 );
|
||||||
|
|
||||||
|
pd->set_deleter( *ppx );
|
||||||
|
|
||||||
|
ppx->reset( shared_this_, ppx->get() );
|
||||||
|
shared_this_.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutable weak_ptr<void> weak_this_;
|
||||||
|
private:
|
||||||
|
mutable shared_ptr<void> shared_this_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
boost::shared_ptr<T> shared_from_raw(T *p)
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(p != 0);
|
||||||
|
return boost::shared_ptr<T>(p->enable_shared_from_raw::shared_from_this(), p);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
boost::weak_ptr<T> weak_from_raw(T *p)
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(p != 0);
|
||||||
|
boost::weak_ptr<T> result;
|
||||||
|
result._internal_aliasing_assign(p->enable_shared_from_raw::weak_this_, p);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
template< class X, class Y > inline void sp_enable_shared_from_this( boost::shared_ptr<X> * ppx, Y const * py, boost::enable_shared_from_raw const * pe )
|
||||||
|
{
|
||||||
|
if( pe != 0 )
|
||||||
|
{
|
||||||
|
pe->_internal_accept_owner( ppx, const_cast< Y* >( py ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namepsace detail
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_ENABLE_SHARED_FROM_RAW_HPP_INCLUDED
|
@@ -25,20 +25,20 @@ template<class T> class enable_shared_from_this
|
|||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
enable_shared_from_this()
|
enable_shared_from_this() BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
enable_shared_from_this(enable_shared_from_this const &)
|
enable_shared_from_this(enable_shared_from_this const &) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
enable_shared_from_this & operator=(enable_shared_from_this const &)
|
enable_shared_from_this & operator=(enable_shared_from_this const &) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
~enable_shared_from_this()
|
~enable_shared_from_this() BOOST_NOEXCEPT // ~weak_ptr<T> newer throws, so this call also must not throw
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,132 +0,0 @@
|
|||||||
#ifndef BOOST_ENABLE_SHARED_FROM_THIS2_HPP_INCLUDED
|
|
||||||
#define BOOST_ENABLE_SHARED_FROM_THIS2_HPP_INCLUDED
|
|
||||||
|
|
||||||
//
|
|
||||||
// enable_shared_from_this2.hpp
|
|
||||||
//
|
|
||||||
// Copyright 2002, 2009 Peter Dimov
|
|
||||||
// Copyright 2008 Frank Mori Hess
|
|
||||||
//
|
|
||||||
// Distributed under the Boost Software License, Version 1.0.
|
|
||||||
// See accompanying file LICENSE_1_0.txt or copy at
|
|
||||||
// http://www.boost.org/LICENSE_1_0.txt
|
|
||||||
//
|
|
||||||
|
|
||||||
#include <boost/config.hpp>
|
|
||||||
#include <boost/shared_ptr.hpp>
|
|
||||||
#include <boost/assert.hpp>
|
|
||||||
#include <boost/detail/workaround.hpp>
|
|
||||||
|
|
||||||
namespace boost
|
|
||||||
{
|
|
||||||
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
|
|
||||||
class esft2_deleter_wrapper
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
|
|
||||||
shared_ptr<void> deleter_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
esft2_deleter_wrapper()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template< class T > void set_deleter( shared_ptr<T> const & deleter )
|
|
||||||
{
|
|
||||||
deleter_ = deleter;
|
|
||||||
}
|
|
||||||
|
|
||||||
template< class T> void operator()( T* )
|
|
||||||
{
|
|
||||||
BOOST_ASSERT( deleter_.use_count() <= 1 );
|
|
||||||
deleter_.reset();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
template< class T > class enable_shared_from_this2
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
|
|
||||||
enable_shared_from_this2()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
enable_shared_from_this2( enable_shared_from_this2 const & )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
enable_shared_from_this2 & operator=( enable_shared_from_this2 const & )
|
|
||||||
{
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
~enable_shared_from_this2()
|
|
||||||
{
|
|
||||||
BOOST_ASSERT( shared_this_.use_count() <= 1 ); // make sure no dangling shared_ptr objects exist
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
mutable weak_ptr<T> weak_this_;
|
|
||||||
mutable shared_ptr<T> shared_this_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
shared_ptr<T> shared_from_this()
|
|
||||||
{
|
|
||||||
init_weak_once();
|
|
||||||
return shared_ptr<T>( weak_this_ );
|
|
||||||
}
|
|
||||||
|
|
||||||
shared_ptr<T const> shared_from_this() const
|
|
||||||
{
|
|
||||||
init_weak_once();
|
|
||||||
return shared_ptr<T>( weak_this_ );
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
void init_weak_once() const
|
|
||||||
{
|
|
||||||
if( weak_this_._empty() )
|
|
||||||
{
|
|
||||||
shared_this_.reset( static_cast< T* >( 0 ), detail::esft2_deleter_wrapper() );
|
|
||||||
weak_this_ = shared_this_;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public: // actually private, but avoids compiler template friendship issues
|
|
||||||
|
|
||||||
// Note: invoked automatically by shared_ptr; do not call
|
|
||||||
template<class X, class Y> void _internal_accept_owner( shared_ptr<X> * ppx, Y * py ) const
|
|
||||||
{
|
|
||||||
BOOST_ASSERT( ppx != 0 );
|
|
||||||
|
|
||||||
if( weak_this_.use_count() == 0 )
|
|
||||||
{
|
|
||||||
weak_this_ = shared_ptr<T>( *ppx, py );
|
|
||||||
}
|
|
||||||
else if( shared_this_.use_count() != 0 )
|
|
||||||
{
|
|
||||||
BOOST_ASSERT( ppx->unique() ); // no weak_ptrs should exist either, but there's no way to check that
|
|
||||||
|
|
||||||
detail::esft2_deleter_wrapper * pd = boost::get_deleter<detail::esft2_deleter_wrapper>( shared_this_ );
|
|
||||||
BOOST_ASSERT( pd != 0 );
|
|
||||||
|
|
||||||
pd->set_deleter( *ppx );
|
|
||||||
|
|
||||||
ppx->reset( shared_this_, ppx->get() );
|
|
||||||
shared_this_.reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace boost
|
|
||||||
|
|
||||||
#endif // #ifndef BOOST_ENABLE_SHARED_FROM_THIS2_HPP_INCLUDED
|
|
@@ -15,14 +15,10 @@
|
|||||||
|
|
||||||
#include <boost/config.hpp>
|
#include <boost/config.hpp>
|
||||||
|
|
||||||
#ifdef BOOST_MSVC // moved here to work around VC++ compiler crash
|
|
||||||
# pragma warning(push)
|
|
||||||
# pragma warning(disable:4284) // odd return type for operator->
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
#include <boost/detail/workaround.hpp>
|
#include <boost/detail/workaround.hpp>
|
||||||
#include <boost/smart_ptr/detail/sp_convertible.hpp>
|
#include <boost/smart_ptr/detail/sp_convertible.hpp>
|
||||||
|
#include <boost/smart_ptr/detail/sp_nullptr_t.hpp>
|
||||||
|
|
||||||
#include <boost/config/no_tr1/functional.hpp> // for std::less
|
#include <boost/config/no_tr1/functional.hpp> // for std::less
|
||||||
|
|
||||||
@@ -63,7 +59,7 @@ public:
|
|||||||
|
|
||||||
typedef T element_type;
|
typedef T element_type;
|
||||||
|
|
||||||
intrusive_ptr(): px( 0 )
|
intrusive_ptr() BOOST_NOEXCEPT : px( 0 )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,7 +73,7 @@ public:
|
|||||||
template<class U>
|
template<class U>
|
||||||
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
|
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
|
||||||
|
|
||||||
intrusive_ptr( intrusive_ptr<U> const & rhs, typename detail::sp_enable_if_convertible<U,T>::type = detail::sp_empty() )
|
intrusive_ptr( intrusive_ptr<U> const & rhs, typename boost::detail::sp_enable_if_convertible<U,T>::type = boost::detail::sp_empty() )
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
@@ -113,16 +109,16 @@ public:
|
|||||||
|
|
||||||
// Move support
|
// Move support
|
||||||
|
|
||||||
#if defined( BOOST_HAS_RVALUE_REFS )
|
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||||
|
|
||||||
intrusive_ptr(intrusive_ptr && rhs): px( rhs.px )
|
intrusive_ptr(intrusive_ptr && rhs) BOOST_NOEXCEPT : px( rhs.px )
|
||||||
{
|
{
|
||||||
rhs.px = 0;
|
rhs.px = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
intrusive_ptr & operator=(intrusive_ptr && rhs)
|
intrusive_ptr & operator=(intrusive_ptr && rhs) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
this_type(std::move(rhs)).swap(*this);
|
this_type( static_cast< intrusive_ptr && >( rhs ) ).swap(*this);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,7 +136,7 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset()
|
void reset() BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
this_type().swap( *this );
|
this_type().swap( *this );
|
||||||
}
|
}
|
||||||
@@ -150,7 +146,7 @@ public:
|
|||||||
this_type( rhs ).swap( *this );
|
this_type( rhs ).swap( *this );
|
||||||
}
|
}
|
||||||
|
|
||||||
T * get() const
|
T * get() const BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
return px;
|
return px;
|
||||||
}
|
}
|
||||||
@@ -170,7 +166,7 @@ public:
|
|||||||
// implicit conversion to "bool"
|
// implicit conversion to "bool"
|
||||||
#include <boost/smart_ptr/detail/operator_bool.hpp>
|
#include <boost/smart_ptr/detail/operator_bool.hpp>
|
||||||
|
|
||||||
void swap(intrusive_ptr & rhs)
|
void swap(intrusive_ptr & rhs) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
T * tmp = px;
|
T * tmp = px;
|
||||||
px = rhs.px;
|
px = rhs.px;
|
||||||
@@ -223,6 +219,30 @@ template<class T> inline bool operator!=(intrusive_ptr<T> const & a, intrusive_p
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined( BOOST_NO_CXX11_NULLPTR )
|
||||||
|
|
||||||
|
template<class T> inline bool operator==( intrusive_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
return p.get() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> inline bool operator==( boost::detail::sp_nullptr_t, intrusive_ptr<T> const & p ) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
return p.get() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> inline bool operator!=( intrusive_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
return p.get() != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, intrusive_ptr<T> const & p ) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
return p.get() != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
template<class T> inline bool operator<(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b)
|
template<class T> inline bool operator<(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b)
|
||||||
{
|
{
|
||||||
return std::less<T *>()(a.get(), b.get());
|
return std::less<T *>()(a.get(), b.get());
|
||||||
@@ -290,10 +310,15 @@ template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::
|
|||||||
|
|
||||||
#endif // !defined(BOOST_NO_IOSTREAM)
|
#endif // !defined(BOOST_NO_IOSTREAM)
|
||||||
|
|
||||||
|
// hash_value
|
||||||
|
|
||||||
|
template< class T > struct hash;
|
||||||
|
|
||||||
|
template< class T > std::size_t hash_value( boost::intrusive_ptr<T> const & p )
|
||||||
|
{
|
||||||
|
return boost::hash< T* >()( p.get() );
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
#ifdef BOOST_MSVC
|
|
||||||
# pragma warning(pop)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // #ifndef BOOST_SMART_PTR_INTRUSIVE_PTR_HPP_INCLUDED
|
#endif // #ifndef BOOST_SMART_PTR_INTRUSIVE_PTR_HPP_INCLUDED
|
||||||
|
187
include/boost/smart_ptr/intrusive_ref_counter.hpp
Normal file
187
include/boost/smart_ptr/intrusive_ref_counter.hpp
Normal file
@@ -0,0 +1,187 @@
|
|||||||
|
/*
|
||||||
|
* Copyright Andrey Semashev 2007 - 2013.
|
||||||
|
* 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)
|
||||||
|
*/
|
||||||
|
/*!
|
||||||
|
* \file intrusive_ref_counter.hpp
|
||||||
|
* \author Andrey Semashev
|
||||||
|
* \date 12.03.2009
|
||||||
|
*
|
||||||
|
* This header contains a reference counter class for \c intrusive_ptr.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BOOST_SMART_PTR_INTRUSIVE_REF_COUNTER_HPP_INCLUDED_
|
||||||
|
#define BOOST_SMART_PTR_INTRUSIVE_REF_COUNTER_HPP_INCLUDED_
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <boost/smart_ptr/detail/atomic_count.hpp>
|
||||||
|
|
||||||
|
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma warning(push)
|
||||||
|
// This is a bogus MSVC warning, which is flagged by friend declarations of intrusive_ptr_add_ref and intrusive_ptr_release in intrusive_ref_counter:
|
||||||
|
// 'name' : the inline specifier cannot be used when a friend declaration refers to a specialization of a function template
|
||||||
|
// Note that there is no inline specifier in the declarations.
|
||||||
|
#pragma warning(disable: 4396)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
|
||||||
|
namespace sp_adl_block {
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Thread unsafe reference counter policy for \c intrusive_ref_counter
|
||||||
|
*
|
||||||
|
* The policy instructs the \c intrusive_ref_counter base class to implement
|
||||||
|
* a reference counter suitable for single threaded use only. Pointers to the same
|
||||||
|
* object with this kind of reference counter must not be used by different threads.
|
||||||
|
*/
|
||||||
|
struct thread_unsafe_counter
|
||||||
|
{
|
||||||
|
typedef unsigned int type;
|
||||||
|
|
||||||
|
static unsigned int load(unsigned int const& counter) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
return counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void increment(unsigned int& counter) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
++counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int decrement(unsigned int& counter) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
return --counter;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Thread safe reference counter policy for \c intrusive_ref_counter
|
||||||
|
*
|
||||||
|
* The policy instructs the \c intrusive_ref_counter base class to implement
|
||||||
|
* a thread-safe reference counter, if the target platform supports multithreading.
|
||||||
|
*/
|
||||||
|
struct thread_safe_counter
|
||||||
|
{
|
||||||
|
typedef boost::detail::atomic_count type;
|
||||||
|
|
||||||
|
static unsigned int load(boost::detail::atomic_count const& counter) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
return static_cast< unsigned int >(static_cast< long >(counter));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void increment(boost::detail::atomic_count& counter) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
++counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int decrement(boost::detail::atomic_count& counter) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
return --counter;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template< typename DerivedT, typename CounterPolicyT = thread_safe_counter >
|
||||||
|
class intrusive_ref_counter;
|
||||||
|
|
||||||
|
template< typename DerivedT, typename CounterPolicyT >
|
||||||
|
void intrusive_ptr_add_ref(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT;
|
||||||
|
template< typename DerivedT, typename CounterPolicyT >
|
||||||
|
void intrusive_ptr_release(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief A reference counter base class
|
||||||
|
*
|
||||||
|
* This base class can be used with user-defined classes to add support
|
||||||
|
* for \c intrusive_ptr. The class contains a reference counter defined by the \c CounterPolicyT.
|
||||||
|
* Upon releasing the last \c intrusive_ptr referencing the object
|
||||||
|
* derived from the \c intrusive_ref_counter class, operator \c delete
|
||||||
|
* is automatically called on the pointer to the object.
|
||||||
|
*
|
||||||
|
* The other template parameter, \c DerivedT, is the user's class that derives from \c intrusive_ref_counter.
|
||||||
|
*/
|
||||||
|
template< typename DerivedT, typename CounterPolicyT >
|
||||||
|
class intrusive_ref_counter
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
//! Reference counter type
|
||||||
|
typedef typename CounterPolicyT::type counter_type;
|
||||||
|
//! Reference counter
|
||||||
|
mutable counter_type m_ref_counter;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/*!
|
||||||
|
* Default constructor
|
||||||
|
*
|
||||||
|
* \post <tt>use_count() == 0</tt>
|
||||||
|
*/
|
||||||
|
intrusive_ref_counter() BOOST_NOEXCEPT : m_ref_counter(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Copy constructor
|
||||||
|
*
|
||||||
|
* \post <tt>use_count() == 0</tt>
|
||||||
|
*/
|
||||||
|
intrusive_ref_counter(intrusive_ref_counter const&) BOOST_NOEXCEPT : m_ref_counter(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Assignment
|
||||||
|
*
|
||||||
|
* \post The reference counter is not modified after assignment
|
||||||
|
*/
|
||||||
|
intrusive_ref_counter& operator= (intrusive_ref_counter const&) BOOST_NOEXCEPT { return *this; }
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \return The reference counter
|
||||||
|
*/
|
||||||
|
unsigned int use_count() const BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
return CounterPolicyT::load(m_ref_counter);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/*!
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
BOOST_DEFAULTED_FUNCTION(~intrusive_ref_counter(), {})
|
||||||
|
|
||||||
|
friend void intrusive_ptr_add_ref< DerivedT, CounterPolicyT >(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT;
|
||||||
|
friend void intrusive_ptr_release< DerivedT, CounterPolicyT >(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT;
|
||||||
|
};
|
||||||
|
|
||||||
|
template< typename DerivedT, typename CounterPolicyT >
|
||||||
|
inline void intrusive_ptr_add_ref(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
CounterPolicyT::increment(p->m_ref_counter);
|
||||||
|
}
|
||||||
|
|
||||||
|
template< typename DerivedT, typename CounterPolicyT >
|
||||||
|
inline void intrusive_ptr_release(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
if (CounterPolicyT::decrement(p->m_ref_counter) == 0)
|
||||||
|
delete static_cast< const DerivedT* >(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace sp_adl_block
|
||||||
|
|
||||||
|
using sp_adl_block::intrusive_ref_counter;
|
||||||
|
using sp_adl_block::thread_unsafe_counter;
|
||||||
|
using sp_adl_block::thread_safe_counter;
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // BOOST_SMART_PTR_INTRUSIVE_REF_COUNTER_HPP_INCLUDED_
|
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
// make_shared.hpp
|
// make_shared.hpp
|
||||||
//
|
//
|
||||||
// Copyright (c) 2007, 2008 Peter Dimov
|
// Copyright (c) 2007, 2008, 2012 Peter Dimov
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0.
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
// See accompanying file LICENSE_1_0.txt or copy at
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
@@ -12,493 +12,11 @@
|
|||||||
// See http://www.boost.org/libs/smart_ptr/make_shared.html
|
// See http://www.boost.org/libs/smart_ptr/make_shared.html
|
||||||
// for documentation.
|
// for documentation.
|
||||||
|
|
||||||
#include <boost/config.hpp>
|
#include <boost/smart_ptr/make_shared_object.hpp>
|
||||||
#include <boost/smart_ptr/shared_ptr.hpp>
|
|
||||||
#include <boost/type_traits/type_with_alignment.hpp>
|
|
||||||
#include <boost/type_traits/alignment_of.hpp>
|
|
||||||
#include <cstddef>
|
|
||||||
#include <new>
|
|
||||||
|
|
||||||
namespace boost
|
|
||||||
{
|
|
||||||
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
|
|
||||||
template< std::size_t N, std::size_t A > struct sp_aligned_storage
|
|
||||||
{
|
|
||||||
union type
|
|
||||||
{
|
|
||||||
char data_[ N ];
|
|
||||||
typename boost::type_with_alignment< A >::type align_;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template< class T > class sp_ms_deleter
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
|
|
||||||
typedef typename sp_aligned_storage< sizeof( T ), ::boost::alignment_of< T >::value >::type storage_type;
|
|
||||||
|
|
||||||
bool initialized_;
|
|
||||||
storage_type storage_;
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
void destroy()
|
|
||||||
{
|
|
||||||
if( initialized_ )
|
|
||||||
{
|
|
||||||
reinterpret_cast< T* >( storage_.data_ )->~T();
|
|
||||||
initialized_ = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
sp_ms_deleter(): initialized_( false )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// optimization: do not copy storage_
|
|
||||||
sp_ms_deleter( sp_ms_deleter const & ): 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();
|
|
||||||
|
|
||||||
T * pt2 = static_cast< T* >( pv );
|
|
||||||
|
|
||||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
|
||||||
return boost::shared_ptr< T >( pt, pt2 );
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
T * pt2 = static_cast< T* >( pv );
|
|
||||||
|
|
||||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
|
||||||
return boost::shared_ptr< T >( pt, pt2 );
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined( BOOST_HAS_VARIADIC_TMPL ) && defined( BOOST_HAS_RVALUE_REFS )
|
|
||||||
|
|
||||||
// Variadic templates, rvalue reference
|
|
||||||
|
|
||||||
template< class T, class... Args > boost::shared_ptr< T > make_shared( Args && ... args )
|
|
||||||
{
|
|
||||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
|
|
||||||
|
|
||||||
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
|
||||||
|
|
||||||
void * pv = pd->address();
|
|
||||||
|
|
||||||
::new( pv ) T( detail::forward<Args>( args )... );
|
|
||||||
pd->set_initialized();
|
|
||||||
|
|
||||||
T * pt2 = static_cast< T* >( pv );
|
|
||||||
|
|
||||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
|
||||||
return boost::shared_ptr< T >( pt, pt2 );
|
|
||||||
}
|
|
||||||
|
|
||||||
template< class T, class A, class... Args > boost::shared_ptr< T > allocate_shared( A const & a, Args && ... args )
|
|
||||||
{
|
|
||||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
|
|
||||||
|
|
||||||
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
|
|
||||||
|
|
||||||
void * pv = pd->address();
|
|
||||||
|
|
||||||
::new( pv ) T( detail::forward<Args>( args )... );
|
|
||||||
pd->set_initialized();
|
|
||||||
|
|
||||||
T * pt2 = static_cast< T* >( pv );
|
|
||||||
|
|
||||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
|
||||||
return boost::shared_ptr< T >( pt, pt2 );
|
|
||||||
}
|
|
||||||
|
|
||||||
#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();
|
|
||||||
|
|
||||||
T * pt2 = static_cast< T* >( pv );
|
|
||||||
|
|
||||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
|
||||||
return boost::shared_ptr< T >( pt, pt2 );
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
T * pt2 = static_cast< T* >( pv );
|
|
||||||
|
|
||||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
|
||||||
return boost::shared_ptr< T >( pt, pt2 );
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
T * pt2 = static_cast< T* >( pv );
|
|
||||||
|
|
||||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
|
||||||
return boost::shared_ptr< T >( pt, pt2 );
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
T * pt2 = static_cast< T* >( pv );
|
|
||||||
|
|
||||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
|
||||||
return boost::shared_ptr< T >( pt, pt2 );
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
T * pt2 = static_cast< T* >( pv );
|
|
||||||
|
|
||||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
|
||||||
return boost::shared_ptr< T >( pt, pt2 );
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
T * pt2 = static_cast< T* >( pv );
|
|
||||||
|
|
||||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
|
||||||
return boost::shared_ptr< T >( pt, pt2 );
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
T * pt2 = static_cast< T* >( pv );
|
|
||||||
|
|
||||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
|
||||||
return boost::shared_ptr< T >( pt, pt2 );
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
T * pt2 = static_cast< T* >( pv );
|
|
||||||
|
|
||||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
|
||||||
return boost::shared_ptr< T >( pt, pt2 );
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
T * pt2 = static_cast< T* >( pv );
|
|
||||||
|
|
||||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
|
||||||
return boost::shared_ptr< T >( pt, pt2 );
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
T * pt2 = static_cast< T* >( pv );
|
|
||||||
|
|
||||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
|
||||||
return boost::shared_ptr< T >( pt, pt2 );
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
T * pt2 = static_cast< T* >( pv );
|
|
||||||
|
|
||||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
|
||||||
return boost::shared_ptr< T >( pt, pt2 );
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
T * pt2 = static_cast< T* >( pv );
|
|
||||||
|
|
||||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
|
||||||
return boost::shared_ptr< T >( pt, pt2 );
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
T * pt2 = static_cast< T* >( pv );
|
|
||||||
|
|
||||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
|
||||||
return boost::shared_ptr< T >( pt, pt2 );
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
T * pt2 = static_cast< T* >( pv );
|
|
||||||
|
|
||||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
|
||||||
return boost::shared_ptr< T >( pt, pt2 );
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
T * pt2 = static_cast< T* >( pv );
|
|
||||||
|
|
||||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
|
||||||
return boost::shared_ptr< T >( pt, pt2 );
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
T * pt2 = static_cast< T* >( pv );
|
|
||||||
|
|
||||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
|
||||||
return boost::shared_ptr< T >( pt, pt2 );
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
T * pt2 = static_cast< T* >( pv );
|
|
||||||
|
|
||||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
|
||||||
return boost::shared_ptr< T >( pt, pt2 );
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
T * pt2 = static_cast< T* >( pv );
|
|
||||||
|
|
||||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
|
||||||
return boost::shared_ptr< T >( pt, pt2 );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) && !defined( BOOST_NO_SFINAE )
|
||||||
|
# include <boost/smart_ptr/make_shared_array.hpp>
|
||||||
|
# include <boost/smart_ptr/allocate_shared_array.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} // namespace boost
|
|
||||||
|
|
||||||
#endif // #ifndef BOOST_SMART_PTR_MAKE_SHARED_HPP_INCLUDED
|
#endif // #ifndef BOOST_SMART_PTR_MAKE_SHARED_HPP_INCLUDED
|
||||||
|
247
include/boost/smart_ptr/make_shared_array.hpp
Normal file
247
include/boost/smart_ptr/make_shared_array.hpp
Normal file
@@ -0,0 +1,247 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2012 Glen Joseph Fernandes
|
||||||
|
* glenfe at live dot com
|
||||||
|
*
|
||||||
|
* Distributed under the Boost Software License,
|
||||||
|
* Version 1.0. (See accompanying file LICENSE_1_0.txt
|
||||||
|
* or copy at http://boost.org/LICENSE_1_0.txt)
|
||||||
|
*/
|
||||||
|
#ifndef BOOST_SMART_PTR_MAKE_SHARED_ARRAY_HPP
|
||||||
|
#define BOOST_SMART_PTR_MAKE_SHARED_ARRAY_HPP
|
||||||
|
|
||||||
|
#include <boost/smart_ptr/shared_ptr.hpp>
|
||||||
|
#include <boost/smart_ptr/detail/array_deleter.hpp>
|
||||||
|
#include <boost/smart_ptr/detail/array_traits.hpp>
|
||||||
|
#include <boost/smart_ptr/detail/make_array_helper.hpp>
|
||||||
|
#include <boost/smart_ptr/detail/sp_if_array.hpp>
|
||||||
|
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||||
|
#include <initializer_list>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
template<typename T>
|
||||||
|
inline typename boost::detail::sp_if_array<T>::type
|
||||||
|
make_shared(std::size_t size) {
|
||||||
|
typedef typename boost::detail::array_inner<T>::type T1;
|
||||||
|
typedef typename boost::detail::array_base<T1>::type T2;
|
||||||
|
T1* p1 = 0;
|
||||||
|
T2* p2 = 0;
|
||||||
|
std::size_t n1 = size * boost::detail::array_total<T1>::size;
|
||||||
|
boost::detail::make_array_helper<T2[]> a1(n1, &p2);
|
||||||
|
boost::detail::array_deleter<T2[]> d1(n1);
|
||||||
|
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||||
|
typedef boost::detail::array_deleter<T2[]>* D2;
|
||||||
|
p1 = reinterpret_cast<T1*>(p2);
|
||||||
|
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||||
|
d2->init(p2);
|
||||||
|
return boost::shared_ptr<T>(s1, p1);
|
||||||
|
}
|
||||||
|
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||||
|
template<typename T, typename... Args>
|
||||||
|
inline typename boost::detail::sp_if_array<T>::type
|
||||||
|
make_shared(std::size_t size, Args&&... args) {
|
||||||
|
typedef typename boost::detail::array_inner<T>::type T1;
|
||||||
|
typedef typename boost::detail::array_base<T1>::type T2;
|
||||||
|
T1* p1 = 0;
|
||||||
|
T2* p2 = 0;
|
||||||
|
std::size_t n1 = size * boost::detail::array_total<T1>::size;
|
||||||
|
boost::detail::make_array_helper<T2[]> a1(n1, &p2);
|
||||||
|
boost::detail::array_deleter<T2[]> d1(n1);
|
||||||
|
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||||
|
typedef boost::detail::array_deleter<T2[]>* D2;
|
||||||
|
p1 = reinterpret_cast<T1*>(p2);
|
||||||
|
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||||
|
d2->init(p2, boost::detail::sp_forward<Args>(args)...);
|
||||||
|
return boost::shared_ptr<T>(s1, p1);
|
||||||
|
}
|
||||||
|
template<typename T, typename... Args>
|
||||||
|
inline typename boost::detail::sp_if_size_array<T>::type
|
||||||
|
make_shared(Args&&... args) {
|
||||||
|
typedef typename boost::detail::array_inner<T>::type T1;
|
||||||
|
typedef typename boost::detail::array_base<T1>::type T2;
|
||||||
|
enum {
|
||||||
|
N = boost::detail::array_total<T>::size
|
||||||
|
};
|
||||||
|
T1* p1 = 0;
|
||||||
|
T2* p2 = 0;
|
||||||
|
boost::detail::make_array_helper<T2[N]> a1(&p2);
|
||||||
|
boost::detail::array_deleter<T2[N]> d1;
|
||||||
|
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||||
|
typedef boost::detail::array_deleter<T2[N]>* D2;
|
||||||
|
p1 = reinterpret_cast<T1*>(p2);
|
||||||
|
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||||
|
d2->init(p2, boost::detail::sp_forward<Args>(args)...);
|
||||||
|
return boost::shared_ptr<T>(s1, p1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
|
||||||
|
template<typename T>
|
||||||
|
inline typename boost::detail::sp_if_size_array<T>::type
|
||||||
|
make_shared(const T& list) {
|
||||||
|
typedef typename boost::detail::array_inner<T>::type T1;
|
||||||
|
typedef typename boost::detail::array_base<T1>::type T2;
|
||||||
|
typedef const T2 T3;
|
||||||
|
enum {
|
||||||
|
N = boost::detail::array_total<T>::size
|
||||||
|
};
|
||||||
|
T1* p1 = 0;
|
||||||
|
T2* p2 = 0;
|
||||||
|
T3* p3 = 0;
|
||||||
|
boost::detail::make_array_helper<T2[N]> a1(&p2);
|
||||||
|
boost::detail::array_deleter<T2[N]> d1;
|
||||||
|
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||||
|
typedef boost::detail::array_deleter<T2[N]>* D2;
|
||||||
|
p3 = reinterpret_cast<T3*>(list);
|
||||||
|
p1 = reinterpret_cast<T1*>(p2);
|
||||||
|
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||||
|
d2->init_list(p2, p3);
|
||||||
|
return boost::shared_ptr<T>(s1, p1);
|
||||||
|
}
|
||||||
|
template<typename T>
|
||||||
|
inline typename boost::detail::sp_if_array<T>::type
|
||||||
|
make_shared(std::size_t size,
|
||||||
|
const typename boost::detail::array_inner<T>::type& list) {
|
||||||
|
typedef typename boost::detail::array_inner<T>::type T1;
|
||||||
|
typedef typename boost::detail::array_base<T1>::type T2;
|
||||||
|
typedef const T2 T3;
|
||||||
|
enum {
|
||||||
|
M = boost::detail::array_total<T1>::size
|
||||||
|
};
|
||||||
|
T1* p1 = 0;
|
||||||
|
T2* p2 = 0;
|
||||||
|
T3* p3 = 0;
|
||||||
|
std::size_t n1 = M * size;
|
||||||
|
boost::detail::make_array_helper<T2[]> a1(n1, &p2);
|
||||||
|
boost::detail::array_deleter<T2[]> d1(n1);
|
||||||
|
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||||
|
typedef boost::detail::array_deleter<T2[]>* D2;
|
||||||
|
p3 = reinterpret_cast<T3*>(list);
|
||||||
|
p1 = reinterpret_cast<T1*>(p2);
|
||||||
|
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||||
|
d2->template init_list<M>(p2, p3);
|
||||||
|
return boost::shared_ptr<T>(s1, p1);
|
||||||
|
}
|
||||||
|
template<typename T>
|
||||||
|
inline typename boost::detail::sp_if_size_array<T>::type
|
||||||
|
make_shared(const typename boost::detail::array_inner<T>::type& list) {
|
||||||
|
typedef typename boost::detail::array_inner<T>::type T1;
|
||||||
|
typedef typename boost::detail::array_base<T1>::type T2;
|
||||||
|
typedef const T2 T3;
|
||||||
|
enum {
|
||||||
|
M = boost::detail::array_total<T1>::size,
|
||||||
|
N = boost::detail::array_total<T>::size
|
||||||
|
};
|
||||||
|
T1* p1 = 0;
|
||||||
|
T2* p2 = 0;
|
||||||
|
T3* p3 = 0;
|
||||||
|
boost::detail::make_array_helper<T2[N]> a1(&p2);
|
||||||
|
boost::detail::array_deleter<T2[N]> d1;
|
||||||
|
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||||
|
typedef boost::detail::array_deleter<T2[N]>* D2;
|
||||||
|
p3 = reinterpret_cast<T3*>(list);
|
||||||
|
p1 = reinterpret_cast<T1*>(p2);
|
||||||
|
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||||
|
d2->template init_list<M>(p2, p3);
|
||||||
|
return boost::shared_ptr<T>(s1, p1);
|
||||||
|
}
|
||||||
|
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||||
|
template<typename T>
|
||||||
|
inline typename boost::detail::sp_if_array<T>::type
|
||||||
|
make_shared(std::initializer_list<typename boost::detail::array_inner<T>::type> list) {
|
||||||
|
typedef typename boost::detail::array_inner<T>::type T1;
|
||||||
|
typedef typename boost::detail::array_base<T1>::type T2;
|
||||||
|
typedef const T2 T3;
|
||||||
|
T1* p1 = 0;
|
||||||
|
T2* p2 = 0;
|
||||||
|
T3* p3 = 0;
|
||||||
|
std::size_t n1 = list.size() * boost::detail::array_total<T1>::size;
|
||||||
|
boost::detail::make_array_helper<T2[]> a1(n1, &p2);
|
||||||
|
boost::detail::array_deleter<T2[]> d1(n1);
|
||||||
|
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||||
|
typedef boost::detail::array_deleter<T2[]>* D2;
|
||||||
|
p3 = reinterpret_cast<T3*>(list.begin());
|
||||||
|
p1 = reinterpret_cast<T1*>(p2);
|
||||||
|
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||||
|
d2->init_list(p2, p3);
|
||||||
|
return boost::shared_ptr<T>(s1, p1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||||
|
template<typename T>
|
||||||
|
inline typename boost::detail::sp_if_array<T>::type
|
||||||
|
make_shared(std::size_t size,
|
||||||
|
typename boost::detail::array_base<T>::type&& value) {
|
||||||
|
typedef typename boost::detail::array_inner<T>::type T1;
|
||||||
|
typedef typename boost::detail::array_base<T1>::type T2;
|
||||||
|
T1* p1 = 0;
|
||||||
|
T2* p2 = 0;
|
||||||
|
std::size_t n1 = size * boost::detail::array_total<T1>::size;
|
||||||
|
boost::detail::make_array_helper<T2[]> a1(n1, &p2);
|
||||||
|
boost::detail::array_deleter<T2[]> d1(n1);
|
||||||
|
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||||
|
typedef boost::detail::array_deleter<T2[]>* D2;
|
||||||
|
p1 = reinterpret_cast<T1*>(p2);
|
||||||
|
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||||
|
d2->init(p2, boost::detail::sp_forward<T2>(value));
|
||||||
|
return boost::shared_ptr<T>(s1, p1);
|
||||||
|
}
|
||||||
|
template<typename T>
|
||||||
|
inline typename boost::detail::sp_if_size_array<T>::type
|
||||||
|
make_shared(typename boost::detail::array_base<T>::type&& value) {
|
||||||
|
typedef typename boost::detail::array_inner<T>::type T1;
|
||||||
|
typedef typename boost::detail::array_base<T1>::type T2;
|
||||||
|
enum {
|
||||||
|
N = boost::detail::array_total<T>::size
|
||||||
|
};
|
||||||
|
T1* p1 = 0;
|
||||||
|
T2* p2 = 0;
|
||||||
|
boost::detail::make_array_helper<T2[N]> a1(&p2);
|
||||||
|
boost::detail::array_deleter<T2[N]> d1;
|
||||||
|
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||||
|
typedef boost::detail::array_deleter<T2[N]>* D2;
|
||||||
|
p1 = reinterpret_cast<T1*>(p2);
|
||||||
|
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||||
|
d2->init(p2, boost::detail::sp_forward<T2>(value));
|
||||||
|
return boost::shared_ptr<T>(s1, p1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
template<typename T>
|
||||||
|
inline typename boost::detail::sp_if_array<T>::type
|
||||||
|
make_shared_noinit(std::size_t size) {
|
||||||
|
typedef typename boost::detail::array_inner<T>::type T1;
|
||||||
|
typedef typename boost::detail::array_base<T1>::type T2;
|
||||||
|
T1* p1 = 0;
|
||||||
|
T2* p2 = 0;
|
||||||
|
std::size_t n1 = size * boost::detail::array_total<T1>::size;
|
||||||
|
boost::detail::make_array_helper<T2[]> a1(n1, &p2);
|
||||||
|
boost::detail::array_deleter<T2[]> d1(n1);
|
||||||
|
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||||
|
typedef boost::detail::array_deleter<T2[]>* D2;
|
||||||
|
p1 = reinterpret_cast<T1*>(p2);
|
||||||
|
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||||
|
d2->noinit(p2);
|
||||||
|
return boost::shared_ptr<T>(s1, p1);
|
||||||
|
}
|
||||||
|
template<typename T>
|
||||||
|
inline typename boost::detail::sp_if_size_array<T>::type
|
||||||
|
make_shared_noinit() {
|
||||||
|
typedef typename boost::detail::array_inner<T>::type T1;
|
||||||
|
typedef typename boost::detail::array_base<T1>::type T2;
|
||||||
|
enum {
|
||||||
|
N = boost::detail::array_total<T>::size
|
||||||
|
};
|
||||||
|
T1* p1 = 0;
|
||||||
|
T2* p2 = 0;
|
||||||
|
boost::detail::make_array_helper<T2[N]> a1(&p2);
|
||||||
|
boost::detail::array_deleter<T2[N]> d1;
|
||||||
|
boost::shared_ptr<T> s1(p1, d1, a1);
|
||||||
|
typedef boost::detail::array_deleter<T2[N]>* D2;
|
||||||
|
p1 = reinterpret_cast<T1*>(p2);
|
||||||
|
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
|
||||||
|
d2->noinit(p2);
|
||||||
|
return boost::shared_ptr<T>(s1, p1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
1032
include/boost/smart_ptr/make_shared_object.hpp
Normal file
1032
include/boost/smart_ptr/make_shared_object.hpp
Normal file
File diff suppressed because it is too large
Load Diff
57
include/boost/smart_ptr/owner_less.hpp
Normal file
57
include/boost/smart_ptr/owner_less.hpp
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
#ifndef BOOST_SMART_PTR_OWNER_LESS_HPP_INCLUDED
|
||||||
|
#define BOOST_SMART_PTR_OWNER_LESS_HPP_INCLUDED
|
||||||
|
|
||||||
|
//
|
||||||
|
// owner_less.hpp
|
||||||
|
//
|
||||||
|
// Copyright (c) 2008 Frank Mori Hess
|
||||||
|
//
|
||||||
|
// 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/smart_ptr.htm for documentation.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
template<typename T> class shared_ptr;
|
||||||
|
template<typename T> class weak_ptr;
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
template<typename T, typename U>
|
||||||
|
struct generic_owner_less : public std::binary_function<T, T, bool>
|
||||||
|
{
|
||||||
|
bool operator()(const T &lhs, const T &rhs) const
|
||||||
|
{
|
||||||
|
return lhs.owner_before(rhs);
|
||||||
|
}
|
||||||
|
bool operator()(const T &lhs, const U &rhs) const
|
||||||
|
{
|
||||||
|
return lhs.owner_before(rhs);
|
||||||
|
}
|
||||||
|
bool operator()(const U &lhs, const T &rhs) const
|
||||||
|
{
|
||||||
|
return lhs.owner_before(rhs);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<typename T> struct owner_less;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct owner_less<shared_ptr<T> >:
|
||||||
|
public detail::generic_owner_less<shared_ptr<T>, weak_ptr<T> >
|
||||||
|
{};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct owner_less<weak_ptr<T> >:
|
||||||
|
public detail::generic_owner_less<weak_ptr<T>, shared_ptr<T> >
|
||||||
|
{};
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_SMART_PTR_OWNER_LESS_HPP_INCLUDED
|
@@ -11,9 +11,10 @@
|
|||||||
// http://www.boost.org/libs/smart_ptr/scoped_array.htm
|
// http://www.boost.org/libs/smart_ptr/scoped_array.htm
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
#include <boost/checked_delete.hpp>
|
#include <boost/checked_delete.hpp>
|
||||||
#include <boost/config.hpp> // in case ptrdiff_t not in std
|
#include <boost/smart_ptr/detail/sp_nullptr_t.hpp>
|
||||||
|
|
||||||
#include <boost/detail/workaround.hpp>
|
#include <boost/detail/workaround.hpp>
|
||||||
|
|
||||||
@@ -53,7 +54,7 @@ public:
|
|||||||
|
|
||||||
typedef T element_type;
|
typedef T element_type;
|
||||||
|
|
||||||
explicit scoped_array( T * p = 0 ) : px( p ) // never throws
|
explicit scoped_array( T * p = 0 ) BOOST_NOEXCEPT : px( p )
|
||||||
{
|
{
|
||||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||||
boost::sp_array_constructor_hook( px );
|
boost::sp_array_constructor_hook( px );
|
||||||
@@ -68,20 +69,20 @@ public:
|
|||||||
boost::checked_array_delete( px );
|
boost::checked_array_delete( px );
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset(T * p = 0) // never throws
|
void reset(T * p = 0) // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT)
|
||||||
{
|
{
|
||||||
BOOST_ASSERT( p == 0 || p != px ); // catch self-reset errors
|
BOOST_ASSERT( p == 0 || p != px ); // catch self-reset errors
|
||||||
this_type(p).swap(*this);
|
this_type(p).swap(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
T & operator[](std::ptrdiff_t i) const // never throws
|
T & operator[](std::ptrdiff_t i) const // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT)
|
||||||
{
|
{
|
||||||
BOOST_ASSERT( px != 0 );
|
BOOST_ASSERT( px != 0 );
|
||||||
BOOST_ASSERT( i >= 0 );
|
BOOST_ASSERT( i >= 0 );
|
||||||
return px[i];
|
return px[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
T * get() const // never throws
|
T * get() const BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
return px;
|
return px;
|
||||||
}
|
}
|
||||||
@@ -89,7 +90,7 @@ public:
|
|||||||
// implicit conversion to "bool"
|
// implicit conversion to "bool"
|
||||||
#include <boost/smart_ptr/detail/operator_bool.hpp>
|
#include <boost/smart_ptr/detail/operator_bool.hpp>
|
||||||
|
|
||||||
void swap(scoped_array & b) // never throws
|
void swap(scoped_array & b) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
T * tmp = b.px;
|
T * tmp = b.px;
|
||||||
b.px = px;
|
b.px = px;
|
||||||
@@ -97,7 +98,31 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class T> inline void swap(scoped_array<T> & a, scoped_array<T> & b) // never throws
|
#if !defined( BOOST_NO_CXX11_NULLPTR )
|
||||||
|
|
||||||
|
template<class T> inline bool operator==( scoped_array<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
return p.get() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> inline bool operator==( boost::detail::sp_nullptr_t, scoped_array<T> const & p ) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
return p.get() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> inline bool operator!=( scoped_array<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
return p.get() != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, scoped_array<T> const & p ) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
return p.get() != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<class T> inline void swap(scoped_array<T> & a, scoped_array<T> & b) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
a.swap(b);
|
a.swap(b);
|
||||||
}
|
}
|
||||||
|
@@ -11,8 +11,10 @@
|
|||||||
// http://www.boost.org/libs/smart_ptr/scoped_ptr.htm
|
// http://www.boost.org/libs/smart_ptr/scoped_ptr.htm
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
#include <boost/checked_delete.hpp>
|
#include <boost/checked_delete.hpp>
|
||||||
|
#include <boost/smart_ptr/detail/sp_nullptr_t.hpp>
|
||||||
#include <boost/detail/workaround.hpp>
|
#include <boost/detail/workaround.hpp>
|
||||||
|
|
||||||
#ifndef BOOST_NO_AUTO_PTR
|
#ifndef BOOST_NO_AUTO_PTR
|
||||||
@@ -63,7 +65,7 @@ public:
|
|||||||
|
|
||||||
#ifndef BOOST_NO_AUTO_PTR
|
#ifndef BOOST_NO_AUTO_PTR
|
||||||
|
|
||||||
explicit scoped_ptr( std::auto_ptr<T> p ): px( p.release() ) // never throws
|
explicit scoped_ptr( std::auto_ptr<T> p ) BOOST_NOEXCEPT : px( p.release() )
|
||||||
{
|
{
|
||||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||||
boost::sp_scalar_constructor_hook( px );
|
boost::sp_scalar_constructor_hook( px );
|
||||||
@@ -98,7 +100,7 @@ public:
|
|||||||
return px;
|
return px;
|
||||||
}
|
}
|
||||||
|
|
||||||
T * get() const // never throws
|
T * get() const BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
return px;
|
return px;
|
||||||
}
|
}
|
||||||
@@ -106,7 +108,7 @@ public:
|
|||||||
// implicit conversion to "bool"
|
// implicit conversion to "bool"
|
||||||
#include <boost/smart_ptr/detail/operator_bool.hpp>
|
#include <boost/smart_ptr/detail/operator_bool.hpp>
|
||||||
|
|
||||||
void swap(scoped_ptr & b) // never throws
|
void swap(scoped_ptr & b) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
T * tmp = b.px;
|
T * tmp = b.px;
|
||||||
b.px = px;
|
b.px = px;
|
||||||
@@ -114,14 +116,38 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class T> inline void swap(scoped_ptr<T> & a, scoped_ptr<T> & b) // never throws
|
#if !defined( BOOST_NO_CXX11_NULLPTR )
|
||||||
|
|
||||||
|
template<class T> inline bool operator==( scoped_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
return p.get() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> inline bool operator==( boost::detail::sp_nullptr_t, scoped_ptr<T> const & p ) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
return p.get() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> inline bool operator!=( scoped_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
return p.get() != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, scoped_ptr<T> const & p ) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
return p.get() != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<class T> inline void swap(scoped_ptr<T> & a, scoped_ptr<T> & b) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
a.swap(b);
|
a.swap(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
// get_pointer(p) is a generic way to say p.get()
|
// get_pointer(p) is a generic way to say p.get()
|
||||||
|
|
||||||
template<class T> inline T * get_pointer(scoped_ptr<T> const & p)
|
template<class T> inline T * get_pointer(scoped_ptr<T> const & p) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
return p.get();
|
return p.get();
|
||||||
}
|
}
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
// shared_array.hpp
|
// shared_array.hpp
|
||||||
//
|
//
|
||||||
// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
|
// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
|
||||||
// Copyright (c) 2001, 2002 Peter Dimov
|
// Copyright (c) 2001, 2002, 2012 Peter Dimov
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See
|
// Distributed under the Boost Software License, Version 1.0. (See
|
||||||
// accompanying file LICENSE_1_0.txt or copy at
|
// accompanying file LICENSE_1_0.txt or copy at
|
||||||
@@ -25,7 +25,9 @@
|
|||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
#include <boost/checked_delete.hpp>
|
#include <boost/checked_delete.hpp>
|
||||||
|
|
||||||
|
#include <boost/smart_ptr/shared_ptr.hpp>
|
||||||
#include <boost/smart_ptr/detail/shared_count.hpp>
|
#include <boost/smart_ptr/detail/shared_count.hpp>
|
||||||
|
#include <boost/smart_ptr/detail/sp_nullptr_t.hpp>
|
||||||
#include <boost/detail/workaround.hpp>
|
#include <boost/detail/workaround.hpp>
|
||||||
|
|
||||||
#include <cstddef> // for std::ptrdiff_t
|
#include <cstddef> // for std::ptrdiff_t
|
||||||
@@ -55,41 +57,146 @@ public:
|
|||||||
|
|
||||||
typedef T element_type;
|
typedef T element_type;
|
||||||
|
|
||||||
explicit shared_array(T * p = 0): px(p), pn(p, deleter())
|
shared_array() BOOST_NOEXCEPT : px( 0 ), pn()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class Y>
|
||||||
|
explicit shared_array( Y * p ): px( p ), pn( p, checked_array_deleter<Y>() )
|
||||||
|
{
|
||||||
|
boost::detail::sp_assert_convertible< Y[], T[] >();
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Requirements: D's copy constructor must not throw
|
// Requirements: D's copy constructor must not throw
|
||||||
//
|
//
|
||||||
// shared_array will release p by calling d(p)
|
// shared_array will release p by calling d(p)
|
||||||
//
|
//
|
||||||
|
|
||||||
template<class D> shared_array(T * p, D d): px(p), pn(p, d)
|
template<class Y, class D> shared_array( Y * p, D d ): px( p ), pn( p, d )
|
||||||
|
{
|
||||||
|
boost::detail::sp_assert_convertible< Y[], T[] >();
|
||||||
|
}
|
||||||
|
|
||||||
|
// As above, but with allocator. A's copy constructor shall not throw.
|
||||||
|
|
||||||
|
template<class Y, class D, class A> shared_array( Y * p, D d, A a ): px( p ), pn( p, d, a )
|
||||||
|
{
|
||||||
|
boost::detail::sp_assert_convertible< Y[], T[] >();
|
||||||
|
}
|
||||||
|
|
||||||
|
// generated copy constructor, destructor are fine...
|
||||||
|
|
||||||
|
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||||
|
|
||||||
|
// ... except in C++0x, move disables the implicit copy
|
||||||
|
|
||||||
|
shared_array( shared_array const & r ) BOOST_NOEXCEPT : px( r.px ), pn( r.pn )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// generated copy constructor, assignment, destructor are fine
|
shared_array( shared_array && r ) BOOST_NOEXCEPT : px( r.px ), pn()
|
||||||
|
|
||||||
void reset(T * p = 0)
|
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(p == 0 || p != px);
|
pn.swap( r.pn );
|
||||||
this_type(p).swap(*this);
|
r.px = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class D> void reset(T * p, D d)
|
#endif
|
||||||
|
|
||||||
|
// conversion
|
||||||
|
|
||||||
|
template<class Y>
|
||||||
|
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
|
||||||
|
|
||||||
|
shared_array( shared_array<Y> const & r, typename boost::detail::sp_enable_if_convertible< Y[], T[] >::type = boost::detail::sp_empty() )
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
shared_array( shared_array<Y> const & r )
|
||||||
|
|
||||||
|
#endif
|
||||||
|
BOOST_NOEXCEPT : px( r.px ), pn( r.pn ) // never throws
|
||||||
{
|
{
|
||||||
this_type(p, d).swap(*this);
|
boost::detail::sp_assert_convertible< Y[], T[] >();
|
||||||
}
|
}
|
||||||
|
|
||||||
T & operator[] (std::ptrdiff_t i) const // never throws
|
// aliasing
|
||||||
|
|
||||||
|
template< class Y >
|
||||||
|
shared_array( shared_array<Y> const & r, element_type * p ) BOOST_NOEXCEPT : px( p ), pn( r.pn )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// assignment
|
||||||
|
|
||||||
|
shared_array & operator=( shared_array const & r ) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
this_type( r ).swap( *this );
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1400)
|
||||||
|
|
||||||
|
template<class Y>
|
||||||
|
shared_array & operator=( shared_array<Y> const & r ) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
this_type( r ).swap( *this );
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||||
|
|
||||||
|
shared_array & operator=( shared_array && r ) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
this_type( static_cast< shared_array && >( r ) ).swap( *this );
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Y>
|
||||||
|
shared_array & operator=( shared_array<Y> && r ) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
this_type( static_cast< shared_array<Y> && >( r ) ).swap( *this );
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void reset() BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
this_type().swap( *this );
|
||||||
|
}
|
||||||
|
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Y, class D> void reset( Y * p, D d )
|
||||||
|
{
|
||||||
|
this_type( p, d ).swap( *this );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Y, class D, class A> void reset( Y * p, D d, A a )
|
||||||
|
{
|
||||||
|
this_type( p, d, a ).swap( *this );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Y> void reset( shared_array<Y> const & r, element_type * p )
|
||||||
|
{
|
||||||
|
this_type( r, p ).swap( *this );
|
||||||
|
}
|
||||||
|
|
||||||
|
T & operator[] (std::ptrdiff_t i) const // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT)
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(px != 0);
|
BOOST_ASSERT(px != 0);
|
||||||
BOOST_ASSERT(i >= 0);
|
BOOST_ASSERT(i >= 0);
|
||||||
return px[i];
|
return px[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
T * get() const // never throws
|
T * get() const BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
return px;
|
return px;
|
||||||
}
|
}
|
||||||
@@ -97,49 +204,85 @@ public:
|
|||||||
// implicit conversion to "bool"
|
// implicit conversion to "bool"
|
||||||
#include <boost/smart_ptr/detail/operator_bool.hpp>
|
#include <boost/smart_ptr/detail/operator_bool.hpp>
|
||||||
|
|
||||||
bool unique() const // never throws
|
bool unique() const BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
return pn.unique();
|
return pn.unique();
|
||||||
}
|
}
|
||||||
|
|
||||||
long use_count() const // never throws
|
long use_count() const BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
return pn.use_count();
|
return pn.use_count();
|
||||||
}
|
}
|
||||||
|
|
||||||
void swap(shared_array<T> & other) // never throws
|
void swap(shared_array<T> & other) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
std::swap(px, other.px);
|
std::swap(px, other.px);
|
||||||
pn.swap(other.pn);
|
pn.swap(other.pn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void * _internal_get_deleter( boost::detail::sp_typeinfo const & ti ) const
|
||||||
|
{
|
||||||
|
return pn.get_deleter( ti );
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
template<class Y> friend class shared_array;
|
||||||
|
|
||||||
T * px; // contained pointer
|
T * px; // contained pointer
|
||||||
detail::shared_count pn; // reference counter
|
detail::shared_count pn; // reference counter
|
||||||
|
|
||||||
}; // shared_array
|
}; // shared_array
|
||||||
|
|
||||||
template<class T> inline bool operator==(shared_array<T> const & a, shared_array<T> const & b) // never throws
|
template<class T> inline bool operator==(shared_array<T> const & a, shared_array<T> const & b) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
return a.get() == b.get();
|
return a.get() == b.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T> inline bool operator!=(shared_array<T> const & a, shared_array<T> const & b) // never throws
|
template<class T> inline bool operator!=(shared_array<T> const & a, shared_array<T> const & b) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
return a.get() != b.get();
|
return a.get() != b.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T> inline bool operator<(shared_array<T> const & a, shared_array<T> const & b) // never throws
|
#if !defined( BOOST_NO_CXX11_NULLPTR )
|
||||||
|
|
||||||
|
template<class T> inline bool operator==( shared_array<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
return p.get() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> inline bool operator==( boost::detail::sp_nullptr_t, shared_array<T> const & p ) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
return p.get() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> inline bool operator!=( shared_array<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
return p.get() != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, shared_array<T> const & p ) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
return p.get() != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<class T> inline bool operator<(shared_array<T> const & a, shared_array<T> const & b) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
return std::less<T*>()(a.get(), b.get());
|
return std::less<T*>()(a.get(), b.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T> void swap(shared_array<T> & a, shared_array<T> & b) // never throws
|
template<class T> void swap(shared_array<T> & a, shared_array<T> & b) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
a.swap(b);
|
a.swap(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template< class D, class T > D * get_deleter( shared_array<T> const & p )
|
||||||
|
{
|
||||||
|
return static_cast< D * >( p._internal_get_deleter( BOOST_SP_TYPEID(D) ) );
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
#endif // #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
|
#endif // #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
|
||||||
|
@@ -32,6 +32,7 @@
|
|||||||
#include <boost/smart_ptr/detail/shared_count.hpp>
|
#include <boost/smart_ptr/detail/shared_count.hpp>
|
||||||
#include <boost/detail/workaround.hpp>
|
#include <boost/detail/workaround.hpp>
|
||||||
#include <boost/smart_ptr/detail/sp_convertible.hpp>
|
#include <boost/smart_ptr/detail/sp_convertible.hpp>
|
||||||
|
#include <boost/smart_ptr/detail/sp_nullptr_t.hpp>
|
||||||
|
|
||||||
#if !defined(BOOST_SP_NO_ATOMIC_ACCESS)
|
#if !defined(BOOST_SP_NO_ATOMIC_ACCESS)
|
||||||
#include <boost/smart_ptr/detail/spinlock_pool.hpp>
|
#include <boost/smart_ptr/detail/spinlock_pool.hpp>
|
||||||
@@ -41,6 +42,7 @@
|
|||||||
#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
|
||||||
|
#include <cstddef> // for std::size_t
|
||||||
|
|
||||||
#if !defined(BOOST_NO_IOSTREAM)
|
#if !defined(BOOST_NO_IOSTREAM)
|
||||||
#if !defined(BOOST_NO_IOSFWD)
|
#if !defined(BOOST_NO_IOSFWD)
|
||||||
@@ -50,56 +52,157 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef BOOST_MSVC // moved here to work around VC++ compiler crash
|
|
||||||
# pragma warning(push)
|
|
||||||
# pragma warning(disable:4284) // odd return type for operator->
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
|
|
||||||
template<class T> class shared_ptr;
|
template<class T> class shared_ptr;
|
||||||
template<class T> class weak_ptr;
|
template<class T> class weak_ptr;
|
||||||
template<class T> class enable_shared_from_this;
|
template<class T> class enable_shared_from_this;
|
||||||
template<class T> class enable_shared_from_this2;
|
class enable_shared_from_raw;
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
|
|
||||||
struct static_cast_tag {};
|
// sp_element, element_type
|
||||||
struct const_cast_tag {};
|
|
||||||
struct dynamic_cast_tag {};
|
|
||||||
struct polymorphic_cast_tag {};
|
|
||||||
|
|
||||||
template<class T> struct shared_ptr_traits
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if !defined( __BORLANDC__ ) || !BOOST_WORKAROUND( __BORLANDC__, < 0x600 )
|
||||||
|
|
||||||
|
template< class T, std::size_t N > struct sp_element< T[N] >
|
||||||
|
{
|
||||||
|
typedef T type;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#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)
|
#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 // !defined(BOOST_NO_CV_VOID_SPECIALIZATIONS)
|
||||||
|
|
||||||
|
#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
|
||||||
|
|
||||||
|
template< class T > struct sp_dereference< T[] >
|
||||||
|
{
|
||||||
|
typedef void type;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if !defined( __BORLANDC__ ) || !BOOST_WORKAROUND( __BORLANDC__, < 0x600 )
|
||||||
|
|
||||||
|
template< class T, std::size_t N > struct sp_dereference< T[N] >
|
||||||
|
{
|
||||||
|
typedef void type;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#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;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if !defined( __BORLANDC__ ) || !BOOST_WORKAROUND( __BORLANDC__, < 0x600 )
|
||||||
|
|
||||||
|
template< class T, std::size_t N > struct sp_member_access< T[N] >
|
||||||
|
{
|
||||||
|
typedef void type;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#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;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if !defined( __BORLANDC__ ) || !BOOST_WORKAROUND( __BORLANDC__, < 0x600 )
|
||||||
|
|
||||||
|
template< class T, std::size_t N > struct sp_array_access< T[N] >
|
||||||
|
{
|
||||||
|
typedef T & type;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#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
|
// enable_shared_from_this support
|
||||||
|
|
||||||
template< class X, class Y, class T > inline void sp_enable_shared_from_this( boost::shared_ptr<X> const * ppx, Y const * py, boost::enable_shared_from_this< T > const * pe )
|
template< class X, class Y, class T > inline void sp_enable_shared_from_this( boost::shared_ptr<X> const * ppx, Y const * py, boost::enable_shared_from_this< T > const * pe )
|
||||||
@@ -110,13 +213,7 @@ template< class X, class Y, class T > inline void sp_enable_shared_from_this( bo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template< class X, class Y, class T > inline void sp_enable_shared_from_this( boost::shared_ptr<X> * ppx, Y const * py, boost::enable_shared_from_this2< T > const * pe )
|
template< class X, class Y > inline void sp_enable_shared_from_this( boost::shared_ptr<X> * ppx, Y const * py, boost::enable_shared_from_raw const * pe );
|
||||||
{
|
|
||||||
if( pe != 0 )
|
|
||||||
{
|
|
||||||
pe->_internal_accept_owner( ppx, const_cast< Y* >( py ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _MANAGED
|
#ifdef _MANAGED
|
||||||
|
|
||||||
@@ -154,6 +251,69 @@ template< class T, class R > struct sp_enable_if_auto_ptr< std::auto_ptr< T >, R
|
|||||||
|
|
||||||
#endif
|
#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
|
} // namespace detail
|
||||||
|
|
||||||
|
|
||||||
@@ -174,19 +334,24 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef T element_type;
|
typedef typename boost::detail::sp_element< T >::type element_type;
|
||||||
typedef T value_type;
|
|
||||||
typedef T * pointer;
|
|
||||||
typedef typename boost::detail::shared_ptr_traits<T>::reference reference;
|
|
||||||
|
|
||||||
shared_ptr(): px(0), pn() // never throws in 1.30+
|
shared_ptr() BOOST_NOEXCEPT : px( 0 ), pn() // never throws in 1.30+
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Y>
|
#if !defined( BOOST_NO_CXX11_NULLPTR )
|
||||||
explicit shared_ptr( Y * p ): px( p ), pn( p ) // Y must be complete
|
|
||||||
|
shared_ptr( boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT : px( 0 ), pn() // never throws
|
||||||
{
|
{
|
||||||
boost::detail::sp_enable_shared_from_this( this, p, p );
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<class Y>
|
||||||
|
explicit shared_ptr( Y * p ): px( p ), pn() // Y must be complete
|
||||||
|
{
|
||||||
|
boost::detail::sp_pointer_construct( this, p, pn );
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -195,29 +360,58 @@ public:
|
|||||||
// shared_ptr will release p by calling d(p)
|
// 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 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined( BOOST_NO_CXX11_NULLPTR )
|
||||||
|
|
||||||
|
template<class D> shared_ptr( boost::detail::sp_nullptr_t p, D d ): px( p ), pn( p, d )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
// As above, but with allocator. A's copy constructor shall not throw.
|
// 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 )
|
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
|
#if !defined( BOOST_NO_CXX11_NULLPTR )
|
||||||
|
|
||||||
|
template<class D, class A> shared_ptr( boost::detail::sp_nullptr_t p, D d, A a ): px( p ), pn( p, d, a )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// generated copy constructor, destructor are fine...
|
||||||
|
|
||||||
|
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||||
|
|
||||||
|
// ... except in C++0x, move disables the implicit copy
|
||||||
|
|
||||||
|
shared_ptr( shared_ptr const & r ) BOOST_NOEXCEPT : px( r.px ), pn( r.pn )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
template<class Y>
|
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
|
// it is now safe to copy r.px, as pn(r.pn) did not throw
|
||||||
px = r.px;
|
px = r.px;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Y>
|
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
|
shared_ptr( weak_ptr<Y> const & r, boost::detail::sp_nothrow_tag )
|
||||||
|
BOOST_NOEXCEPT : px( 0 ), pn( r.pn, boost::detail::sp_nothrow_tag() )
|
||||||
{
|
{
|
||||||
if( !pn.empty() )
|
if( !pn.empty() )
|
||||||
{
|
{
|
||||||
@@ -228,79 +422,87 @@ public:
|
|||||||
template<class Y>
|
template<class Y>
|
||||||
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
|
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
|
||||||
|
|
||||||
shared_ptr( shared_ptr<Y> const & r, typename detail::sp_enable_if_convertible<Y,T>::type = detail::sp_empty() )
|
shared_ptr( shared_ptr<Y> const & r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() )
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
shared_ptr( shared_ptr<Y> const & r )
|
shared_ptr( shared_ptr<Y> const & r )
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
: px( r.px ), pn( r.pn ) // never throws
|
BOOST_NOEXCEPT : px( r.px ), pn( r.pn )
|
||||||
{
|
{
|
||||||
|
boost::detail::sp_assert_convertible< Y, T >();
|
||||||
}
|
}
|
||||||
|
|
||||||
// aliasing
|
// aliasing
|
||||||
template< class Y >
|
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 ) BOOST_NOEXCEPT : px( p ), pn( r.pn )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Y>
|
|
||||||
shared_ptr(shared_ptr<Y> const & r, boost::detail::static_cast_tag): px(static_cast<element_type *>(r.px)), pn(r.pn)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Y>
|
|
||||||
shared_ptr(shared_ptr<Y> const & r, boost::detail::const_cast_tag): px(const_cast<element_type *>(r.px)), pn(r.pn)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Y>
|
|
||||||
shared_ptr(shared_ptr<Y> const & r, boost::detail::dynamic_cast_tag): px(dynamic_cast<element_type *>(r.px)), pn(r.pn)
|
|
||||||
{
|
|
||||||
if(px == 0) // need to allocate new counter -- the cast failed
|
|
||||||
{
|
|
||||||
pn = boost::detail::shared_count();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Y>
|
|
||||||
shared_ptr(shared_ptr<Y> const & r, boost::detail::polymorphic_cast_tag): px(dynamic_cast<element_type *>(r.px)), pn(r.pn)
|
|
||||||
{
|
|
||||||
if(px == 0)
|
|
||||||
{
|
|
||||||
boost::throw_exception(std::bad_cast());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef BOOST_NO_AUTO_PTR
|
#ifndef BOOST_NO_AUTO_PTR
|
||||||
|
|
||||||
template<class Y>
|
template<class Y>
|
||||||
explicit shared_ptr(std::auto_ptr<Y> & r): px(r.get()), pn()
|
explicit shared_ptr( std::auto_ptr<Y> & r ): px(r.get()), pn()
|
||||||
{
|
{
|
||||||
|
boost::detail::sp_assert_convertible< Y, T >();
|
||||||
|
|
||||||
Y * tmp = r.get();
|
Y * tmp = r.get();
|
||||||
pn = boost::detail::shared_count(r);
|
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 )
|
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||||
|
|
||||||
|
template<class Y>
|
||||||
|
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_deleter_construct( this, tmp );
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
|
||||||
|
|
||||||
template<class Ap>
|
template<class Ap>
|
||||||
explicit shared_ptr( Ap r, typename boost::detail::sp_enable_if_auto_ptr<Ap, int>::type = 0 ): px( r.get() ), pn()
|
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();
|
typedef typename Ap::element_type Y;
|
||||||
pn = boost::detail::shared_count( r );
|
|
||||||
boost::detail::sp_enable_shared_from_this( this, tmp, tmp );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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
|
#endif // BOOST_NO_SFINAE, BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
|
|
||||||
#endif // BOOST_NO_AUTO_PTR
|
#endif // BOOST_NO_AUTO_PTR
|
||||||
|
|
||||||
|
#if !defined( BOOST_NO_CXX11_SMART_PTR ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||||
|
|
||||||
|
template< class Y, class D >
|
||||||
|
shared_ptr( std::unique_ptr< Y, D > && r ): px( r.get() ), pn()
|
||||||
|
{
|
||||||
|
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_deleter_construct( this, tmp );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
// assignment
|
// assignment
|
||||||
|
|
||||||
shared_ptr & operator=( shared_ptr const & r ) // never throws
|
shared_ptr & operator=( shared_ptr const & r ) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
this_type(r).swap(*this);
|
this_type(r).swap(*this);
|
||||||
return *this;
|
return *this;
|
||||||
@@ -309,7 +511,7 @@ public:
|
|||||||
#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1400)
|
#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1400)
|
||||||
|
|
||||||
template<class Y>
|
template<class Y>
|
||||||
shared_ptr & operator=(shared_ptr<Y> const & r) // never throws
|
shared_ptr & operator=(shared_ptr<Y> const & r) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
this_type(r).swap(*this);
|
this_type(r).swap(*this);
|
||||||
return *this;
|
return *this;
|
||||||
@@ -322,11 +524,20 @@ public:
|
|||||||
template<class Y>
|
template<class Y>
|
||||||
shared_ptr & operator=( std::auto_ptr<Y> & r )
|
shared_ptr & operator=( std::auto_ptr<Y> & r )
|
||||||
{
|
{
|
||||||
this_type(r).swap(*this);
|
this_type( r ).swap( *this );
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
|
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||||
|
|
||||||
|
template<class Y>
|
||||||
|
shared_ptr & operator=( std::auto_ptr<Y> && r )
|
||||||
|
{
|
||||||
|
this_type( static_cast< std::auto_ptr<Y> && >( r ) ).swap( *this );
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
|
||||||
|
|
||||||
template<class Ap>
|
template<class Ap>
|
||||||
typename boost::detail::sp_enable_if_auto_ptr< Ap, shared_ptr & >::type operator=( Ap r )
|
typename boost::detail::sp_enable_if_auto_ptr< Ap, shared_ptr & >::type operator=( Ap r )
|
||||||
@@ -335,16 +546,26 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif // BOOST_NO_SFINAE, BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
#endif // BOOST_NO_SFINAE, BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
|
|
||||||
#endif // BOOST_NO_AUTO_PTR
|
#endif // BOOST_NO_AUTO_PTR
|
||||||
|
|
||||||
|
#if !defined( BOOST_NO_CXX11_SMART_PTR ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||||
|
|
||||||
|
template<class Y, class D>
|
||||||
|
shared_ptr & operator=( std::unique_ptr<Y, D> && r )
|
||||||
|
{
|
||||||
|
this_type( static_cast< std::unique_ptr<Y, D> && >( r ) ).swap(*this);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
// Move support
|
// Move support
|
||||||
|
|
||||||
#if defined( BOOST_HAS_RVALUE_REFS )
|
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||||
|
|
||||||
shared_ptr( shared_ptr && r ): px( r.px ), pn() // never throws
|
shared_ptr( shared_ptr && r ) BOOST_NOEXCEPT : px( r.px ), pn()
|
||||||
{
|
{
|
||||||
pn.swap( r.pn );
|
pn.swap( r.pn );
|
||||||
r.px = 0;
|
r.px = 0;
|
||||||
@@ -353,43 +574,55 @@ public:
|
|||||||
template<class Y>
|
template<class Y>
|
||||||
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
|
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
|
||||||
|
|
||||||
shared_ptr( shared_ptr<Y> && r, typename detail::sp_enable_if_convertible<Y,T>::type = detail::sp_empty() )
|
shared_ptr( shared_ptr<Y> && r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() )
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
shared_ptr( shared_ptr<Y> && r )
|
shared_ptr( shared_ptr<Y> && r )
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
: px( r.px ), pn() // never throws
|
BOOST_NOEXCEPT : px( r.px ), pn()
|
||||||
{
|
{
|
||||||
|
boost::detail::sp_assert_convertible< Y, T >();
|
||||||
|
|
||||||
pn.swap( r.pn );
|
pn.swap( r.pn );
|
||||||
r.px = 0;
|
r.px = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr & operator=( shared_ptr && r ) // never throws
|
shared_ptr & operator=( shared_ptr && r ) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
this_type( std::move( r ) ).swap( *this );
|
this_type( static_cast< shared_ptr && >( r ) ).swap( *this );
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Y>
|
template<class Y>
|
||||||
shared_ptr & operator=( shared_ptr<Y> && r ) // never throws
|
shared_ptr & operator=( shared_ptr<Y> && r ) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
this_type( std::move( r ) ).swap( *this );
|
this_type( static_cast< shared_ptr<Y> && >( r ) ).swap( *this );
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void reset() // never throws in 1.30+
|
#if !defined( BOOST_NO_CXX11_NULLPTR )
|
||||||
|
|
||||||
|
shared_ptr & operator=( boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT // never throws
|
||||||
|
{
|
||||||
|
this_type().swap(*this);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void reset() BOOST_NOEXCEPT // never throws in 1.30+
|
||||||
{
|
{
|
||||||
this_type().swap(*this);
|
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
|
BOOST_ASSERT( p == 0 || p != px ); // catch self-reset errors
|
||||||
this_type(p).swap(*this);
|
this_type( p ).swap( *this );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Y, class D> void reset( Y * p, D d )
|
template<class Y, class D> void reset( Y * p, D d )
|
||||||
@@ -402,24 +635,35 @@ public:
|
|||||||
this_type( p, d, a ).swap( *this );
|
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 );
|
this_type( r, p ).swap( *this );
|
||||||
}
|
}
|
||||||
|
|
||||||
reference operator* () const // never throws
|
// never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT)
|
||||||
|
typename boost::detail::sp_dereference< T >::type operator* () const
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(px != 0);
|
BOOST_ASSERT( px != 0 );
|
||||||
return *px;
|
return *px;
|
||||||
}
|
}
|
||||||
|
|
||||||
T * operator-> () const // never throws
|
// never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT)
|
||||||
|
typename boost::detail::sp_member_access< T >::type operator-> () const
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(px != 0);
|
BOOST_ASSERT( px != 0 );
|
||||||
return px;
|
return px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT)
|
||||||
|
typename boost::detail::sp_array_access< T >::type operator[] ( std::ptrdiff_t i ) const
|
||||||
|
{
|
||||||
|
BOOST_ASSERT( px != 0 );
|
||||||
|
BOOST_ASSERT( i >= 0 && ( i < boost::detail::sp_extent< T >::value || boost::detail::sp_extent< T >::value == 0 ) );
|
||||||
|
|
||||||
T * get() const // never throws
|
return px[ i ];
|
||||||
|
}
|
||||||
|
|
||||||
|
element_type * get() const BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
return px;
|
return px;
|
||||||
}
|
}
|
||||||
@@ -427,33 +671,43 @@ public:
|
|||||||
// implicit conversion to "bool"
|
// implicit conversion to "bool"
|
||||||
#include <boost/smart_ptr/detail/operator_bool.hpp>
|
#include <boost/smart_ptr/detail/operator_bool.hpp>
|
||||||
|
|
||||||
bool unique() const // never throws
|
bool unique() const BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
return pn.unique();
|
return pn.unique();
|
||||||
}
|
}
|
||||||
|
|
||||||
long use_count() const // never throws
|
long use_count() const BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
return pn.use_count();
|
return pn.use_count();
|
||||||
}
|
}
|
||||||
|
|
||||||
void swap(shared_ptr<T> & other) // never throws
|
void swap( shared_ptr & other ) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
std::swap(px, other.px);
|
std::swap(px, other.px);
|
||||||
pn.swap(other.pn);
|
pn.swap(other.pn);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Y> bool _internal_less(shared_ptr<Y> const & rhs) const
|
template<class Y> bool owner_before( shared_ptr<Y> const & rhs ) const BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
return pn < rhs.pn;
|
return pn < rhs.pn;
|
||||||
}
|
}
|
||||||
|
|
||||||
void * _internal_get_deleter( detail::sp_typeinfo const & ti ) const
|
template<class Y> bool owner_before( weak_ptr<Y> const & rhs ) const BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
return pn < rhs.pn;
|
||||||
|
}
|
||||||
|
|
||||||
|
void * _internal_get_deleter( boost::detail::sp_typeinfo const & ti ) const BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
return pn.get_deleter( ti );
|
return pn.get_deleter( ti );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _internal_equiv( shared_ptr const & r ) const
|
void * _internal_get_untyped_deleter() const BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
return pn.get_untyped_deleter();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _internal_equiv( shared_ptr const & r ) const BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
return px == r.px && pn == r.pn;
|
return px == r.px && pn == r.pn;
|
||||||
}
|
}
|
||||||
@@ -471,17 +725,17 @@ private:
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
T * px; // contained pointer
|
element_type * px; // contained pointer
|
||||||
boost::detail::shared_count pn; // reference counter
|
boost::detail::shared_count pn; // reference counter
|
||||||
|
|
||||||
}; // shared_ptr
|
}; // shared_ptr
|
||||||
|
|
||||||
template<class T, class U> inline bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b)
|
template<class T, class U> inline bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
return a.get() == b.get();
|
return a.get() == b.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T, class U> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b)
|
template<class T, class U> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
return a.get() != b.get();
|
return a.get() != b.get();
|
||||||
}
|
}
|
||||||
@@ -490,64 +744,90 @@ template<class T, class U> inline bool operator!=(shared_ptr<T> const & a, share
|
|||||||
|
|
||||||
// Resolve the ambiguity between our op!= and the one in rel_ops
|
// Resolve the ambiguity between our op!= and the one in rel_ops
|
||||||
|
|
||||||
template<class T> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<T> const & b)
|
template<class T> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<T> const & b) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
return a.get() != b.get();
|
return a.get() != b.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template<class T, class U> inline bool operator<(shared_ptr<T> const & a, shared_ptr<U> const & b)
|
#if !defined( BOOST_NO_CXX11_NULLPTR )
|
||||||
|
|
||||||
|
template<class T> inline bool operator==( shared_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
return a._internal_less(b);
|
return p.get() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T> inline void swap(shared_ptr<T> & a, shared_ptr<T> & b)
|
template<class T> inline bool operator==( boost::detail::sp_nullptr_t, shared_ptr<T> const & p ) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
return p.get() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> inline bool operator!=( shared_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
return p.get() != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, shared_ptr<T> const & p ) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
return p.get() != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<class T, class U> inline bool operator<(shared_ptr<T> const & a, shared_ptr<U> const & b) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
return a.owner_before( b );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> inline void swap(shared_ptr<T> & a, shared_ptr<T> & b) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
a.swap(b);
|
a.swap(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T, class U> shared_ptr<T> static_pointer_cast(shared_ptr<U> const & r)
|
template<class T, class U> shared_ptr<T> static_pointer_cast( shared_ptr<U> const & r ) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
return shared_ptr<T>(r, boost::detail::static_cast_tag());
|
(void) static_cast< T* >( static_cast< U* >( 0 ) );
|
||||||
|
|
||||||
|
typedef typename shared_ptr<T>::element_type E;
|
||||||
|
|
||||||
|
E * p = static_cast< E* >( r.get() );
|
||||||
|
return shared_ptr<T>( r, p );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T, class U> shared_ptr<T> const_pointer_cast(shared_ptr<U> const & r)
|
template<class T, class U> shared_ptr<T> const_pointer_cast( shared_ptr<U> const & r ) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
return shared_ptr<T>(r, boost::detail::const_cast_tag());
|
(void) const_cast< T* >( static_cast< U* >( 0 ) );
|
||||||
|
|
||||||
|
typedef typename shared_ptr<T>::element_type E;
|
||||||
|
|
||||||
|
E * p = const_cast< E* >( r.get() );
|
||||||
|
return shared_ptr<T>( r, p );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T, class U> shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const & r)
|
template<class T, class U> shared_ptr<T> dynamic_pointer_cast( shared_ptr<U> const & r ) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
return shared_ptr<T>(r, boost::detail::dynamic_cast_tag());
|
(void) dynamic_cast< T* >( static_cast< U* >( 0 ) );
|
||||||
|
|
||||||
|
typedef typename shared_ptr<T>::element_type E;
|
||||||
|
|
||||||
|
E * p = dynamic_cast< E* >( r.get() );
|
||||||
|
return p? shared_ptr<T>( r, p ): shared_ptr<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
// shared_*_cast names are deprecated. Use *_pointer_cast instead.
|
template<class T, class U> shared_ptr<T> reinterpret_pointer_cast( shared_ptr<U> const & r ) BOOST_NOEXCEPT
|
||||||
|
|
||||||
template<class T, class U> shared_ptr<T> shared_static_cast(shared_ptr<U> const & r)
|
|
||||||
{
|
{
|
||||||
return shared_ptr<T>(r, boost::detail::static_cast_tag());
|
(void) reinterpret_cast< T* >( static_cast< U* >( 0 ) );
|
||||||
}
|
|
||||||
|
|
||||||
template<class T, class U> shared_ptr<T> shared_dynamic_cast(shared_ptr<U> const & r)
|
typedef typename shared_ptr<T>::element_type E;
|
||||||
{
|
|
||||||
return shared_ptr<T>(r, boost::detail::dynamic_cast_tag());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T, class U> shared_ptr<T> shared_polymorphic_cast(shared_ptr<U> const & r)
|
E * p = reinterpret_cast< E* >( r.get() );
|
||||||
{
|
return shared_ptr<T>( r, p );
|
||||||
return shared_ptr<T>(r, boost::detail::polymorphic_cast_tag());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T, class U> shared_ptr<T> shared_polymorphic_downcast(shared_ptr<U> const & r)
|
|
||||||
{
|
|
||||||
BOOST_ASSERT(dynamic_cast<T *>(r.get()) == r.get());
|
|
||||||
return shared_static_cast<T>(r);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// get_pointer() enables boost::mem_fn to recognize shared_ptr
|
// get_pointer() enables boost::mem_fn to recognize shared_ptr
|
||||||
|
|
||||||
template<class T> inline T * get_pointer(shared_ptr<T> const & p)
|
template<class T> inline typename shared_ptr<T>::element_type * get_pointer(shared_ptr<T> const & p) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
return p.get();
|
return p.get();
|
||||||
}
|
}
|
||||||
@@ -589,6 +869,9 @@ template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::
|
|||||||
|
|
||||||
// get_deleter
|
// get_deleter
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
#if ( defined(__GNUC__) && BOOST_WORKAROUND(__GNUC__, < 3) ) || \
|
#if ( defined(__GNUC__) && BOOST_WORKAROUND(__GNUC__, < 3) ) || \
|
||||||
( defined(__EDG_VERSION__) && BOOST_WORKAROUND(__EDG_VERSION__, <= 238) ) || \
|
( defined(__EDG_VERSION__) && BOOST_WORKAROUND(__EDG_VERSION__, <= 238) ) || \
|
||||||
( defined(__HP_aCC) && BOOST_WORKAROUND(__HP_aCC, <= 33500) )
|
( defined(__HP_aCC) && BOOST_WORKAROUND(__HP_aCC, <= 33500) )
|
||||||
@@ -596,7 +879,7 @@ template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::
|
|||||||
// g++ 2.9x doesn't allow static_cast<X const *>(void *)
|
// g++ 2.9x doesn't allow static_cast<X const *>(void *)
|
||||||
// apparently EDG 2.38 and HP aCC A.03.35 also don't accept it
|
// apparently EDG 2.38 and HP aCC A.03.35 also don't accept it
|
||||||
|
|
||||||
template<class D, class T> D * get_deleter(shared_ptr<T> const & p)
|
template<class D, class T> D * basic_get_deleter(shared_ptr<T> const & p)
|
||||||
{
|
{
|
||||||
void const * q = p._internal_get_deleter(BOOST_SP_TYPEID(D));
|
void const * q = p._internal_get_deleter(BOOST_SP_TYPEID(D));
|
||||||
return const_cast<D *>(static_cast<D const *>(q));
|
return const_cast<D *>(static_cast<D const *>(q));
|
||||||
@@ -604,18 +887,64 @@ template<class D, class T> D * get_deleter(shared_ptr<T> const & p)
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
template<class D, class T> D * get_deleter(shared_ptr<T> const & p)
|
template<class D, class T> D * basic_get_deleter( shared_ptr<T> const & p ) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
return static_cast<D *>(p._internal_get_deleter(BOOST_SP_TYPEID(D)));
|
return static_cast<D *>( p._internal_get_deleter(BOOST_SP_TYPEID(D)) );
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
class esft2_deleter_wrapper
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
shared_ptr<void> deleter_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
esft2_deleter_wrapper()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class T > void set_deleter( shared_ptr<T> const & deleter )
|
||||||
|
{
|
||||||
|
deleter_ = deleter;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename D> D* get_deleter() const BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
return boost::detail::basic_get_deleter<D>( deleter_ );
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class T> void operator()( T* )
|
||||||
|
{
|
||||||
|
BOOST_ASSERT( deleter_.use_count() <= 1 );
|
||||||
|
deleter_.reset();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class D, class T> D * get_deleter( shared_ptr<T> const & p ) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
D *del = boost::detail::basic_get_deleter<D>(p);
|
||||||
|
|
||||||
|
if(del == 0)
|
||||||
|
{
|
||||||
|
boost::detail::esft2_deleter_wrapper *del_wrapper = boost::detail::basic_get_deleter<boost::detail::esft2_deleter_wrapper>(p);
|
||||||
|
// The following get_deleter method call is fully qualified because
|
||||||
|
// older versions of gcc (2.95, 3.2.3) fail to compile it when written del_wrapper->get_deleter<D>()
|
||||||
|
if(del_wrapper) del = del_wrapper->::boost::detail::esft2_deleter_wrapper::get_deleter<D>();
|
||||||
|
}
|
||||||
|
|
||||||
|
return del;
|
||||||
|
}
|
||||||
|
|
||||||
// atomic access
|
// atomic access
|
||||||
|
|
||||||
#if !defined(BOOST_SP_NO_ATOMIC_ACCESS)
|
#if !defined(BOOST_SP_NO_ATOMIC_ACCESS)
|
||||||
|
|
||||||
template<class T> inline bool atomic_is_lock_free( shared_ptr<T> const * /*p*/ )
|
template<class T> inline bool atomic_is_lock_free( shared_ptr<T> const * /*p*/ ) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -688,14 +1017,19 @@ template<class T> inline bool atomic_compare_exchange_explicit( shared_ptr<T> *
|
|||||||
return atomic_compare_exchange( p, v, w ); // std::move( w )
|
return atomic_compare_exchange( p, v, w ); // std::move( w )
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif // !defined(BOOST_SP_NO_ATOMIC_ACCESS)
|
||||||
|
|
||||||
|
// hash_value
|
||||||
|
|
||||||
|
template< class T > struct hash;
|
||||||
|
|
||||||
|
template< class T > std::size_t hash_value( boost::shared_ptr<T> const & p ) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
return boost::hash< T* >()( p.get() );
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
#ifdef BOOST_MSVC
|
|
||||||
# pragma warning(pop)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
|
#endif // #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
|
||||||
|
|
||||||
#endif // #ifndef BOOST_SMART_PTR_SHARED_PTR_HPP_INCLUDED
|
#endif // #ifndef BOOST_SMART_PTR_SHARED_PTR_HPP_INCLUDED
|
||||||
|
@@ -17,11 +17,6 @@
|
|||||||
#include <boost/smart_ptr/detail/shared_count.hpp>
|
#include <boost/smart_ptr/detail/shared_count.hpp>
|
||||||
#include <boost/smart_ptr/shared_ptr.hpp>
|
#include <boost/smart_ptr/shared_ptr.hpp>
|
||||||
|
|
||||||
#ifdef BOOST_MSVC // moved here to work around VC++ compiler crash
|
|
||||||
# pragma warning(push)
|
|
||||||
# pragma warning(disable:4284) // odd return type for operator->
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -34,14 +29,30 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef T element_type;
|
typedef typename boost::detail::sp_element< T >::type element_type;
|
||||||
|
|
||||||
weak_ptr(): px(0), pn() // never throws in 1.30+
|
weak_ptr() BOOST_NOEXCEPT : px(0), pn() // never throws in 1.30+
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// generated copy constructor, assignment, destructor are fine
|
// generated copy constructor, assignment, destructor are fine...
|
||||||
|
|
||||||
|
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||||
|
|
||||||
|
// ... except in C++0x, move disables the implicit copy
|
||||||
|
|
||||||
|
weak_ptr( weak_ptr const & r ) BOOST_NOEXCEPT : px( r.px ), pn( r.pn )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
weak_ptr & operator=( weak_ptr const & r ) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
px = r.px;
|
||||||
|
pn = r.pn;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// The "obvious" converting constructor implementation:
|
// The "obvious" converting constructor implementation:
|
||||||
@@ -63,44 +74,47 @@ public:
|
|||||||
template<class Y>
|
template<class Y>
|
||||||
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
|
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
|
||||||
|
|
||||||
weak_ptr( weak_ptr<Y> const & r, typename detail::sp_enable_if_convertible<Y,T>::type = detail::sp_empty() )
|
weak_ptr( weak_ptr<Y> const & r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() )
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
weak_ptr( weak_ptr<Y> const & r )
|
weak_ptr( weak_ptr<Y> const & r )
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
: px(r.lock().get()), pn(r.pn) // never throws
|
BOOST_NOEXCEPT : px(r.lock().get()), pn(r.pn)
|
||||||
{
|
{
|
||||||
|
boost::detail::sp_assert_convertible< Y, T >();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined( BOOST_HAS_RVALUE_REFS )
|
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||||
|
|
||||||
template<class Y>
|
template<class Y>
|
||||||
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
|
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
|
||||||
|
|
||||||
weak_ptr( weak_ptr<Y> && r, typename detail::sp_enable_if_convertible<Y,T>::type = detail::sp_empty() )
|
weak_ptr( weak_ptr<Y> && r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() )
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
weak_ptr( weak_ptr<Y> && r )
|
weak_ptr( weak_ptr<Y> && r )
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
: px(r.lock().get()), pn(std::move(r.pn)) // never throws
|
BOOST_NOEXCEPT : px( r.lock().get() ), pn( static_cast< boost::detail::weak_count && >( r.pn ) )
|
||||||
|
{
|
||||||
|
boost::detail::sp_assert_convertible< Y, T >();
|
||||||
|
r.px = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// for better efficiency in the T == Y case
|
||||||
|
weak_ptr( weak_ptr && r )
|
||||||
|
BOOST_NOEXCEPT : px( r.px ), pn( static_cast< boost::detail::weak_count && >( r.pn ) )
|
||||||
{
|
{
|
||||||
r.px = 0;
|
r.px = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// for better efficiency in the T == Y case
|
// for better efficiency in the T == Y case
|
||||||
weak_ptr( weak_ptr && r ): px( r.px ), pn(std::move(r.pn)) // never throws
|
weak_ptr & operator=( weak_ptr && r ) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
r.px = 0;
|
this_type( static_cast< weak_ptr && >( r ) ).swap( *this );
|
||||||
}
|
|
||||||
|
|
||||||
// for better efficiency in the T == Y case
|
|
||||||
weak_ptr & operator=( weak_ptr && r ) // never throws
|
|
||||||
{
|
|
||||||
this_type( std::move( r ) ).swap( *this );
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,59 +124,66 @@ public:
|
|||||||
template<class Y>
|
template<class Y>
|
||||||
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
|
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
|
||||||
|
|
||||||
weak_ptr( shared_ptr<Y> const & r, typename detail::sp_enable_if_convertible<Y,T>::type = detail::sp_empty() )
|
weak_ptr( shared_ptr<Y> const & r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() )
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
weak_ptr( shared_ptr<Y> const & r )
|
weak_ptr( shared_ptr<Y> const & r )
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
: px( r.px ), pn( r.pn ) // never throws
|
BOOST_NOEXCEPT : px( r.px ), pn( r.pn )
|
||||||
{
|
{
|
||||||
|
boost::detail::sp_assert_convertible< Y, T >();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300)
|
#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300)
|
||||||
|
|
||||||
template<class Y>
|
template<class Y>
|
||||||
weak_ptr & operator=(weak_ptr<Y> const & r) // never throws
|
weak_ptr & operator=( weak_ptr<Y> const & r ) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
|
boost::detail::sp_assert_convertible< Y, T >();
|
||||||
|
|
||||||
px = r.lock().get();
|
px = r.lock().get();
|
||||||
pn = r.pn;
|
pn = r.pn;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined( BOOST_HAS_RVALUE_REFS )
|
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||||
|
|
||||||
template<class Y>
|
template<class Y>
|
||||||
weak_ptr & operator=(weak_ptr<Y> && r)
|
weak_ptr & operator=( weak_ptr<Y> && r ) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
this_type( std::move( r ) ).swap( *this );
|
this_type( static_cast< weak_ptr<Y> && >( r ) ).swap( *this );
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template<class Y>
|
template<class Y>
|
||||||
weak_ptr & operator=(shared_ptr<Y> const & r) // never throws
|
weak_ptr & operator=( shared_ptr<Y> const & r ) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
|
boost::detail::sp_assert_convertible< Y, T >();
|
||||||
|
|
||||||
px = r.px;
|
px = r.px;
|
||||||
pn = r.pn;
|
pn = r.pn;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
shared_ptr<T> lock() const // never throws
|
shared_ptr<T> lock() const BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
return shared_ptr<element_type>( *this, boost::detail::sp_nothrow_tag() );
|
return shared_ptr<T>( *this, boost::detail::sp_nothrow_tag() );
|
||||||
}
|
}
|
||||||
|
|
||||||
long use_count() const // never throws
|
long use_count() const BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
return pn.use_count();
|
return pn.use_count();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool expired() const // never throws
|
bool expired() const BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
return pn.use_count() == 0;
|
return pn.use_count() == 0;
|
||||||
}
|
}
|
||||||
@@ -172,24 +193,30 @@ public:
|
|||||||
return pn.empty();
|
return pn.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset() // never throws in 1.30+
|
void reset() BOOST_NOEXCEPT // never throws in 1.30+
|
||||||
{
|
{
|
||||||
this_type().swap(*this);
|
this_type().swap(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void swap(this_type & other) // never throws
|
void swap(this_type & other) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
std::swap(px, other.px);
|
std::swap(px, other.px);
|
||||||
pn.swap(other.pn);
|
pn.swap(other.pn);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _internal_assign(T * px2, boost::detail::shared_count const & pn2)
|
template<typename Y>
|
||||||
|
void _internal_aliasing_assign(weak_ptr<Y> const & r, element_type * px2)
|
||||||
{
|
{
|
||||||
px = px2;
|
px = px2;
|
||||||
pn = pn2;
|
pn = r.pn;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Y> bool _internal_less(weak_ptr<Y> const & rhs) const
|
template<class Y> bool owner_before( weak_ptr<Y> const & rhs ) const BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
return pn < rhs.pn;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Y> bool owner_before( shared_ptr<Y> const & rhs ) const BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
return pn < rhs.pn;
|
return pn < rhs.pn;
|
||||||
}
|
}
|
||||||
@@ -206,25 +233,21 @@ private:
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
T * px; // contained pointer
|
element_type * px; // contained pointer
|
||||||
boost::detail::weak_count pn; // reference counter
|
boost::detail::weak_count pn; // reference counter
|
||||||
|
|
||||||
}; // weak_ptr
|
}; // weak_ptr
|
||||||
|
|
||||||
template<class T, class U> inline bool operator<(weak_ptr<T> const & a, weak_ptr<U> const & b)
|
template<class T, class U> inline bool operator<(weak_ptr<T> const & a, weak_ptr<U> const & b) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
return a._internal_less(b);
|
return a.owner_before( b );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T> void swap(weak_ptr<T> & a, weak_ptr<T> & b)
|
template<class T> void swap(weak_ptr<T> & a, weak_ptr<T> & b) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
a.swap(b);
|
a.swap(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
#ifdef BOOST_MSVC
|
|
||||||
# pragma warning(pop)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // #ifndef BOOST_SMART_PTR_WEAK_PTR_HPP_INCLUDED
|
#endif // #ifndef BOOST_SMART_PTR_WEAK_PTR_HPP_INCLUDED
|
||||||
|
@@ -24,7 +24,9 @@
|
|||||||
compilers that support argument-dependent lookup, <STRONG>intrusive_ptr_add_ref</STRONG>
|
compilers that support argument-dependent lookup, <STRONG>intrusive_ptr_add_ref</STRONG>
|
||||||
and <STRONG>intrusive_ptr_release</STRONG> should be defined in the namespace
|
and <STRONG>intrusive_ptr_release</STRONG> should be defined in the namespace
|
||||||
that corresponds to their parameter; otherwise, the definitions need to go in
|
that corresponds to their parameter; otherwise, the definitions need to go in
|
||||||
namespace <STRONG>boost</STRONG>.</p>
|
namespace <STRONG>boost</STRONG>. The library provides a helper base class template
|
||||||
|
<STRONG><a href="intrusive_ref_counter.html">intrusive_ref_counter</a></STRONG> which may
|
||||||
|
help adding support for <STRONG>intrusive_ptr</STRONG> to user's types.</p>
|
||||||
<p>The class template is parameterized on <b>T</b>, the type of the object pointed
|
<p>The class template is parameterized on <b>T</b>, the type of the object pointed
|
||||||
to. <STRONG>intrusive_ptr<T></STRONG> can be implicitly converted to <STRONG>intrusive_ptr<U></STRONG>
|
to. <STRONG>intrusive_ptr<T></STRONG> can be implicitly converted to <STRONG>intrusive_ptr<U></STRONG>
|
||||||
whenever <STRONG>T*</STRONG> can be implicitly converted to <STRONG>U*</STRONG>.</p>
|
whenever <STRONG>T*</STRONG> can be implicitly converted to <STRONG>U*</STRONG>.</p>
|
||||||
|
95
intrusive_ref_counter.html
Normal file
95
intrusive_ref_counter.html
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>intrusive_ref_counter</title>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||||
|
</head>
|
||||||
|
<body text="#000000" bgColor="#ffffff">
|
||||||
|
<h1><A href="../../index.htm"><IMG height="86" alt="boost.png (6897 bytes)" src="../../boost.png" width="277" align="middle"
|
||||||
|
border="0"></A>basic_intrusive_ref_counter class template</h1>
|
||||||
|
<p>
|
||||||
|
<A href="#Introduction">Introduction</A><br>
|
||||||
|
<A href="#Synopsis">Synopsis</A><br>
|
||||||
|
<A href="#Members">Members</A><br>
|
||||||
|
</p>
|
||||||
|
<h2><a name="Introduction">Introduction</a></h2>
|
||||||
|
<p>The <STRONG>intrusive_ref_counter</STRONG> class template implements a reference counter for a derived
|
||||||
|
user's class that is intended to be used with <STRONG><a href="intrusive_ptr.html">intrusive_ptr</a></STRONG>.
|
||||||
|
The base class has associated <STRONG>intrusive_ptr_add_ref</STRONG> and <STRONG>intrusive_ptr_release</STRONG> functions
|
||||||
|
which modify the reference counter as needed and destroy the user's object when the counter drops to zero.</p>
|
||||||
|
<p>The class template is parameterized on <STRONG>DerivedT</STRONG> and <STRONG>CounterPolicyT</STRONG> parameters.
|
||||||
|
The first parameter is the user's class that derives from <STRONG>intrusive_ref_counter</STRONG>. This type
|
||||||
|
is needed in order to destroy the object correctly when there are no references to it left.</p>
|
||||||
|
<p>The second parameter is a policy that defines the nature of the reference counter.
|
||||||
|
Boost.SmartPtr provides two such policies: <STRONG>thread_unsafe_counter</STRONG> and <STRONG>thread_safe_counter</STRONG>. The former
|
||||||
|
instructs the <STRONG>intrusive_ref_counter</STRONG> base class to use a counter only suitable for a single-threaded use.
|
||||||
|
Pointers to a single object that uses this kind of reference counter must not be used in different threads. The latter policy
|
||||||
|
makes the reference counter thread-safe, unless the target platform doesn't support threading. Since in modern systems support for
|
||||||
|
threading is common, the default counter policy is <STRONG>thread_safe_counter</STRONG>.</p>
|
||||||
|
<h2><a name="Synopsis">Synopsis</a></h2>
|
||||||
|
<pre>namespace boost {
|
||||||
|
|
||||||
|
struct thread_unsafe_counter;
|
||||||
|
struct thread_safe_counter;
|
||||||
|
|
||||||
|
template<class DerivedT, class CounterPolicyT = thread_safe_counter>
|
||||||
|
class intrusive_ref_counter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
<A href="#constructors" >intrusive_ref_counter</A>() = noexcept;
|
||||||
|
<A href="#constructors" >intrusive_ref_counter</A>(intrusive_ref_counter const & r) = noexcept;
|
||||||
|
|
||||||
|
intrusive_ref_counter & <A href="#assignment" >operator=</A>(intrusive_ref_counter const & r) noexcept;
|
||||||
|
|
||||||
|
unsigned int <a href="#use_count" >use_count</a>() const noexcept;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
<A href="#destructor" >~intrusive_ref_counter</A>() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
}</pre>
|
||||||
|
<h2><a name="Members">Members</a></h2>
|
||||||
|
<h3><a name="constructors">constructors</a></h3>
|
||||||
|
<pre>intrusive_ref_counter();</pre>
|
||||||
|
<blockquote>
|
||||||
|
<p><b>Postconditions:</b> <code>use_count() == 0</code>.</p>
|
||||||
|
<p><b>Throws:</b> nothing.</p>
|
||||||
|
<P><B>Notes:</B> The pointer to the constructed object is expected to be passed to <STRONG>intrusive_ptr</STRONG>
|
||||||
|
constructor, assignment operator or <STRONG>reset()</STRONG> method, which would increment the reference counter.</P>
|
||||||
|
</blockquote>
|
||||||
|
<pre>intrusive_ref_counter(intrusive_ref_counter const &);</pre>
|
||||||
|
<blockquote>
|
||||||
|
<p><b>Postconditions:</b> <code>use_count() == 0</code>.</p>
|
||||||
|
<p><b>Throws:</b> nothing.</p>
|
||||||
|
<P><B>Notes:</B> The pointer to the constructed object is expected to be passed to <STRONG>intrusive_ptr</STRONG>
|
||||||
|
constructor, assignment operator or <STRONG>reset()</STRONG> method, which would increment the reference counter.</P>
|
||||||
|
</blockquote>
|
||||||
|
<h3><a name="destructor">destructor</a></h3>
|
||||||
|
<pre>~intrusive_ref_counter();</pre>
|
||||||
|
<BLOCKQUOTE>
|
||||||
|
<p><b>Throws:</b> nothing.</p>
|
||||||
|
<P><B>Effects:</B> Destroys the counter object.</P>
|
||||||
|
<P><B>Notes:</B> The destructor is protected so that the object can only be destroyed through the <STRONG>DerivedT</STRONG> class.</P>
|
||||||
|
</BLOCKQUOTE>
|
||||||
|
<H3><a name="assignment">assignment</a></H3>
|
||||||
|
<pre>intrusive_ref_counter & operator=(intrusive_ref_counter const & r) noexcept;</pre>
|
||||||
|
<BLOCKQUOTE>
|
||||||
|
<P><B>Effects:</B> Does nothing, reference counter is not modified.</P>
|
||||||
|
<P><B>Returns:</B> <code>*this</code>.</P>
|
||||||
|
</BLOCKQUOTE>
|
||||||
|
<H3><a name="use_count">use_count</a></H3>
|
||||||
|
<pre>unsigned int use_count() const noexcept;</pre>
|
||||||
|
<BLOCKQUOTE>
|
||||||
|
<p><b>Returns:</b> The current value of the reference counter.</p>
|
||||||
|
<p><b>Throws:</b> nothing.</p>
|
||||||
|
<P><B>Notes:</B> The returned value may not be actual in multi-threaded applications.</P>
|
||||||
|
</BLOCKQUOTE>
|
||||||
|
<hr>
|
||||||
|
<p>
|
||||||
|
$Date$</p>
|
||||||
|
<p>
|
||||||
|
<small>Copyright <20> 2013 Andrey Semashev. Distributed under the Boost Software License, Version
|
||||||
|
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or
|
||||||
|
copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
|
||||||
|
</body>
|
||||||
|
</html>
|
@@ -41,7 +41,7 @@
|
|||||||
template<typename T, typename A>
|
template<typename T, typename A>
|
||||||
shared_ptr<T> <a href="#functions">allocate_shared</a>( A const & );
|
shared_ptr<T> <a href="#functions">allocate_shared</a>( A const & );
|
||||||
|
|
||||||
#if defined( BOOST_HAS_VARIADIC_TMPL ) && defined( BOOST_HAS_RVALUE_REFS ) // C++0x prototypes
|
#if !defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) // C++0x prototypes
|
||||||
|
|
||||||
template<typename T, typename... Args>
|
template<typename T, typename... Args>
|
||||||
shared_ptr<T> <a href="#functions">make_shared</a>( Args && ... args );
|
shared_ptr<T> <a href="#functions">make_shared</a>( Args && ... args );
|
||||||
|
257
make_shared_array.html
Normal file
257
make_shared_array.html
Normal file
@@ -0,0 +1,257 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>make_shared and allocate_shared</title>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||||
|
</head>
|
||||||
|
<body text="#000000" bgColor="#ffffff" link="#0000ff" vlink="#0000ff">
|
||||||
|
<h1><IMG height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
|
||||||
|
width="277" align="middle" border="0">make_shared and allocate_shared
|
||||||
|
for arrays</h1>
|
||||||
|
<p><A href="#Introduction">Introduction</A><br>
|
||||||
|
<A href="#Synopsis">Synopsis</A><br>
|
||||||
|
<A href="#functions">Free Functions</A><br>
|
||||||
|
<A href="#example">Example</A><br>
|
||||||
|
<A href="#history">History</A><br></p>
|
||||||
|
<h2><a name="Introduction">Introduction</a></h2>
|
||||||
|
<p>Originally the Boost function templates <code>make_shared</code> and
|
||||||
|
<code>allocate_shared</code> were for efficient allocation of single
|
||||||
|
objects only. There was a need to have efficient, single, allocation of
|
||||||
|
arrays. One criticism of <a href="shared_array.htm">shared_array</a> was
|
||||||
|
always the lack of a <a href="make_shared.html">make_shared</a> utility
|
||||||
|
which ensures only a single allocation for an array.</p>
|
||||||
|
<p>The header files <boost/smart_ptr/make_shared_array.hpp> and
|
||||||
|
<boost/smart_ptr/allocate_shared_array.hpp> provide new function
|
||||||
|
templates, <code>make_shared</code> and <code>allocate_shared</code>,
|
||||||
|
to address this need. <code>make_shared</code> uses the global
|
||||||
|
operator <code>new</code> to allocate memory, whereas
|
||||||
|
<code>allocate_shared</code> uses an user-supplied allocator,
|
||||||
|
allowing finer control.</p>
|
||||||
|
<h2><a name="Synopsis">Synopsis</a></h2>
|
||||||
|
<pre>namespace boost {
|
||||||
|
template<typename U> // U = T[]
|
||||||
|
shared_ptr<U> <a href="#functions">make_shared</a>(size_t size);
|
||||||
|
|
||||||
|
template<typename U, typename A> // U = T[]
|
||||||
|
shared_ptr<U> <a href="#functions">allocate_shared</a>(const A& allocator, size_t size);
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||||
|
template<typename U, typename... Args> // U = T[]
|
||||||
|
shared_ptr<U> <a href="#functions">make_shared</a>(size_t size, Args&&... args);
|
||||||
|
|
||||||
|
template<typename U, typename... Args> // U = T[N]
|
||||||
|
shared_ptr<U> <a href="#functions">make_shared</a>(Args&&... args);
|
||||||
|
|
||||||
|
template<typename U, typename A, typename... Args> // U = T[]
|
||||||
|
shared_ptr<U> <a href="#functions">allocate_shared</a>(const A& allocator, size_t size, Args&&... args);
|
||||||
|
|
||||||
|
template<typename U, typename A, typename... Args> // U = T[N]
|
||||||
|
shared_ptr<U> <a href="#functions">allocate_shared</a>(const A& allocator, Args&&... args);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
|
||||||
|
template<typename U, typename... Args> // U = T[N]
|
||||||
|
shared_ptr<U> <a href="#functions">make_shared</a>(const T (&list)[N]);
|
||||||
|
|
||||||
|
template<typename U, typename... Args> // U = T[][N]
|
||||||
|
shared_ptr<U> <a href="#functions">make_shared</a>(size_t size, const T (&list)[N]);
|
||||||
|
|
||||||
|
template<typename U, typename... Args> // U = T[M][N]
|
||||||
|
shared_ptr<U> <a href="#functions">make_shared</a>(const T (&list)[N]);
|
||||||
|
|
||||||
|
template<typename U, typename A, typename... Args> // U = T[N]
|
||||||
|
shared_ptr<T[> <a href="#functions">allocate_shared</a>(const A& allocator, const T (&list)[N]);
|
||||||
|
|
||||||
|
template<typename U, typename A, typename... Args> // U = T[][N]
|
||||||
|
shared_ptr<U> <a href="#functions">allocate_shared</a>(const A& allocator, size_t size, const T (&list)[N]);
|
||||||
|
|
||||||
|
template<typename U, typename A, typename... Args> // U = T[M][N]
|
||||||
|
shared_ptr<U> <a href="#functions">allocate_shared</a>(const A& allocator, const T (&list)[N]);
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||||
|
template<typename U, typename... Args> // U = T[]
|
||||||
|
shared_ptr<U> <a href="#functions">make_shared</a>(initializer_list<T> list);
|
||||||
|
|
||||||
|
template<typename U, typename A, typename... Args> // U = T[]
|
||||||
|
shared_ptr<U> <a href="#functions">allocate_shared</a>(const A& allocator, initializer_list<T> list);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||||
|
template<typename U> // U = T[]
|
||||||
|
shared_ptr<U> <a href="#functions">make_shared</a>(size_t size, T&& value);
|
||||||
|
|
||||||
|
template<typename U> // U = T[N]
|
||||||
|
shared_ptr<U> <a href="#functions">make_shared</a>(T&& value);
|
||||||
|
|
||||||
|
template<typename U, typename A> // U = T[]
|
||||||
|
shared_ptr<U> <a href="#functions">allocate_shared</a>(const A& allocator, size_t size, T&& value);
|
||||||
|
|
||||||
|
template<typename U, typename A> // U = T[N]
|
||||||
|
shared_ptr<U> <a href="#functions">allocate_shared</a>(const A& allocator, T&& value);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<typename U> // U = T[]
|
||||||
|
shared_ptr<U> <a href="#functions">make_shared_noinit</a>(size_t size);
|
||||||
|
|
||||||
|
template<typename U> // U = T[N]
|
||||||
|
shared_ptr<U> <a href="#functions">make_shared_noinit</a>();
|
||||||
|
|
||||||
|
template<typename U, typename A> // U = T[]
|
||||||
|
shared_ptr<U> <a href="#functions">allocate_shared_noinit</a>(const A& allocator, size_t size);
|
||||||
|
|
||||||
|
template<typename U, typename A> // U = T[N]
|
||||||
|
shared_ptr<U> <a href="#functions">allocate_shared_noinit</a>(const A& allocator);
|
||||||
|
}</pre>
|
||||||
|
<h2><a name="functions">Free Functions</a></h2>
|
||||||
|
<pre>template<typename U, typename... Args> // U = T[]
|
||||||
|
shared_ptr<U> make_shared(size_t size, Args&&... args);
|
||||||
|
|
||||||
|
template<typename U, typename A, typename... Args> // U = T[]
|
||||||
|
shared_ptr<U> allocate_shared(const A& allocator, size_t size, Args&&... args);</pre>
|
||||||
|
<blockquote>
|
||||||
|
<p><b>Requires:</b> The expression
|
||||||
|
<code>new(pointer) T(forward<Args>(args)...)</code>, where
|
||||||
|
<code>pointer</code> is a <code>void*</code> pointing to storage
|
||||||
|
suitable to hold an object of type <code>T</code>, shall be
|
||||||
|
well-formed. <code>A</code> shall be an <em>Allocator</em>, as
|
||||||
|
described in section 20.1.5 (<strong>Allocator requirements</strong>)
|
||||||
|
of the C++ Standard. The copy constructor and destructor of
|
||||||
|
<code>A</code> shall not throw.</p>
|
||||||
|
<p><b>Effects:</b> Allocates memory suitable for an array of type
|
||||||
|
<code>T</code> and size <code>size</code> and constructs an array
|
||||||
|
of objects in it via the placement new expression
|
||||||
|
<code>new(pointer) T()</code> or
|
||||||
|
<code>new(pointer) T(args...)</code>.
|
||||||
|
<code>allocate_shared</code> uses a copy of
|
||||||
|
<code>allocator</code> to allocate memory. If an exception is thrown,
|
||||||
|
has no effect.</p>
|
||||||
|
<p><b>Returns:</b> A <code>shared_ptr</code> instance that stores and
|
||||||
|
owns the address of the newly constructed array of type <code>T</code>
|
||||||
|
and size <code>size</code>.</p>
|
||||||
|
<p><b>Postconditions:</b>
|
||||||
|
<code>get() != 0 && use_count() == 1</code>.</p>
|
||||||
|
<p><b>Throws:</b> <code>bad_alloc</code>, or an exception thrown from
|
||||||
|
<code>A::allocate</code> or the constructor of <code>T</code>.</p>
|
||||||
|
<p><b>Notes:</b> This implementation allocates the memory required for
|
||||||
|
the returned <code>shared_ptr</code> and an array of type
|
||||||
|
<code>T</code> of size <code>size</code> in a single allocation. This
|
||||||
|
provides efficiency to equivalent to an intrusive smart array
|
||||||
|
pointer.</p>
|
||||||
|
<p>The prototypes shown above are used if your compiler supports r-value
|
||||||
|
references and variadic templates. They perfectly forward the
|
||||||
|
<code>args</code> parameters to the constructors of
|
||||||
|
<code>T</code> for each array element.</p>
|
||||||
|
<p>Otherwise, you can use the overloads which take only the array size
|
||||||
|
(and the allocator in case of <code>allocate_shared</code>) and do not
|
||||||
|
take any constructor arguments. These overloads invoke the default
|
||||||
|
constructor of <code>T</code> for each array element.</p>
|
||||||
|
</blockquote>
|
||||||
|
<pre>template<typename U, typename... Args> // U = T[N]
|
||||||
|
shared_ptr<U> make_shared(Args&&... args);
|
||||||
|
|
||||||
|
template<typename U, typename A, typename... Args> // U = T[N]
|
||||||
|
shared_ptr<U> allocate_shared(const A& allocator, Args&&... args);</pre>
|
||||||
|
<blockquote>
|
||||||
|
<p><b>Description:</b> These overloads of the utilities above are for a
|
||||||
|
fixed size array.</p>
|
||||||
|
</blockquote>
|
||||||
|
<pre>template<typename U, typename... Args> // U = T[]
|
||||||
|
shared_ptr<U> make_shared(initializer_list<T> list);
|
||||||
|
|
||||||
|
template<typename U, typename A, typename... Args> // U = T[]
|
||||||
|
shared_ptr<U> allocate_shared(const A& allocator, initializer_list<T> list);</pre>
|
||||||
|
<blockquote>
|
||||||
|
<p><b>Description:</b> These overloads initialize the array elements
|
||||||
|
from the initializer list.</p>
|
||||||
|
</blockquote>
|
||||||
|
<pre>template<typename U, typename... Args> // U = T[N]
|
||||||
|
shared_ptr<U> make_shared(const T (&list)[N]);
|
||||||
|
|
||||||
|
template<typename U, typename A, typename... Args> // U = T[N]
|
||||||
|
shared_ptr<U> allocate_shared(const A& allocator, const T (&list)[N]);</pre>
|
||||||
|
<blockquote>
|
||||||
|
<p><b>Description:</b> These overloads of the utilities above are for a
|
||||||
|
fixed size array.</p>
|
||||||
|
</blockquote>
|
||||||
|
<pre>template<typename U, typename... Args> // U = T[][N]
|
||||||
|
shared_ptr<U> make_shared(size_t size, const T (&list)[N]);
|
||||||
|
|
||||||
|
template<typename U, typename A, typename... Args> // U = T[][N]
|
||||||
|
shared_ptr<U> allocate_shared(const A& allocator, size_t size, const T (&list)[N]);</pre>
|
||||||
|
<blockquote>
|
||||||
|
<p><b>Description:</b> These overloads initialize inner array elements
|
||||||
|
from the initializer list.</p>
|
||||||
|
</blockquote>
|
||||||
|
<pre>template<typename U, typename... Args> // U = T[M][N]
|
||||||
|
shared_ptr<U> make_shared(const T (&list)[N]);
|
||||||
|
|
||||||
|
template<typename U, typename A, typename... Args> // U = T[M][N]
|
||||||
|
shared_ptr<U> allocate_shared(const A& allocator, const T (&list)[N]);</pre>
|
||||||
|
<blockquote>
|
||||||
|
<p><b>Description:</b> These overloads of the utilities above are for a
|
||||||
|
fixed size array.</p>
|
||||||
|
</blockquote>
|
||||||
|
<pre>template<typename U> // U = T[]
|
||||||
|
shared_ptr<U> make_shared(size_t size, T&& value);
|
||||||
|
|
||||||
|
template<typename U, typename A> // U = T[]
|
||||||
|
shared_ptr<U> allocate_shared(const A& allocator, size_t size, T&& value);</pre>
|
||||||
|
<blockquote>
|
||||||
|
<p><b>Description:</b> These overloads initialize array elements with
|
||||||
|
the given value.</p>
|
||||||
|
</blockquote>
|
||||||
|
<pre>template<typename U> // U = T[N]
|
||||||
|
shared_ptr<U> make_shared(T&& value);
|
||||||
|
|
||||||
|
template<typename U, typename A> // U = T[N]
|
||||||
|
shared_ptr<U> allocate_shared(const A& allocator, T&& value);</pre>
|
||||||
|
<blockquote>
|
||||||
|
<p><b>Description:</b> These overloads of the utilities above are for a
|
||||||
|
fixed size array.</p>
|
||||||
|
</blockquote>
|
||||||
|
<pre>template<typename U> // U = T[]
|
||||||
|
shared_ptr<U> make_shared_noinit(size_t size);
|
||||||
|
|
||||||
|
template<typename U, typename A> // U = T[]
|
||||||
|
shared_ptr<U> allocate_shared_noinit(const A& allocator, size_t size);</pre>
|
||||||
|
<blockquote>
|
||||||
|
<p><b>Description:</b> These overloads do not perform any value
|
||||||
|
initialization of elements.</p>
|
||||||
|
</blockquote>
|
||||||
|
<pre>template<typename U> // U = T[N]
|
||||||
|
shared_ptr<U> make_shared_noinit();
|
||||||
|
|
||||||
|
template<typename U, typename A> // U = T[N]
|
||||||
|
shared_ptr<U> allocate_shared_noinit(const A& allocator);</pre>
|
||||||
|
<blockquote>
|
||||||
|
<p><b>Description:</b> These overloads of the utilities above are for a
|
||||||
|
fixed size array.</p>
|
||||||
|
</blockquote>
|
||||||
|
<h2><a name="example">Example</a></h2>
|
||||||
|
<p>An example of each overload of make_shared for arrays:</p>
|
||||||
|
<blockquote>
|
||||||
|
<pre>boost::shared_ptr<int[]> a1 = boost::make_shared<int[]>(size);
|
||||||
|
boost::shared_ptr<point[]> a2 = boost::make_shared<point[]>(size, x, y);
|
||||||
|
boost::shared_ptr<point[5]> a3 = boost::make_shared<point[5]>(x, y);
|
||||||
|
boost::shared_ptr<int[]> a4 = boost::make_shared<int[]>({1, 2, 3});
|
||||||
|
boost::shared_ptr<int[3]> a5 = boost::make_shared<int[3]>({1, 2, 3});
|
||||||
|
boost::shared_ptr<int[][3]> a6 = boost::make_shared<int[][3]>(size, {1, 2, 3});
|
||||||
|
boost::shared_ptr<int[5][3]> a7 = boost::make_shared<int[5][3]>({1, 2, 3});
|
||||||
|
boost::shared_ptr<point[]> a8 = boost::make_shared<point[]>(size, {x, y});
|
||||||
|
boost::shared_ptr<point[5]> a9 = boost::make_shared<point[5]>({x, y});
|
||||||
|
boost::shared_ptr<int[]> a10 = boost::make_shared_noinit<int[]>(size);
|
||||||
|
boost::shared_ptr<int[5]> a11 = boost::make_shared_noinit<int[5]>();</pre>
|
||||||
|
</blockquote>
|
||||||
|
<h2><a name="history">History</a></h2>
|
||||||
|
<p>November 2012. Glen Fernandes contributed implementations of
|
||||||
|
make_shared and allocate_shared for arrays.</p>
|
||||||
|
<hr>
|
||||||
|
<p>$Date: 2012-10-30 10:12:25 -0800 (Tue, 30 Oct 2012) $</p>
|
||||||
|
<p><small>Copyright 2012 Glen Fernandes. Distributed under the Boost
|
||||||
|
Software License, Version 1.0. See accompanying file
|
||||||
|
<A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or copy at
|
||||||
|
<A href="http://www.boost.org/LICENSE_1_0.txt">
|
||||||
|
http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
|
||||||
|
</body>
|
||||||
|
</html>
|
1040
shared_ptr.htm
1040
shared_ptr.htm
File diff suppressed because it is too large
Load Diff
@@ -70,6 +70,11 @@
|
|||||||
<td><a href="../../boost/make_shared.hpp"><boost/make_shared.hpp></a></td>
|
<td><a href="../../boost/make_shared.hpp"><boost/make_shared.hpp></a></td>
|
||||||
<td>Efficient creation of <code>shared_ptr</code> objects.</td>
|
<td>Efficient creation of <code>shared_ptr</code> objects.</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><a href="make_shared_array.html"><b>make_shared and allocate_shared for arrays</b></a></td>
|
||||||
|
<td><a href="../../boost/make_shared.hpp"><boost/make_shared.hpp></a></td>
|
||||||
|
<td>Efficient creation of <code>shared_ptr</code> arrays.</td>
|
||||||
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<p>A test program, <a href="test/smart_ptr_test.cpp">smart_ptr_test.cpp</a>, is
|
<p>A test program, <a href="test/smart_ptr_test.cpp">smart_ptr_test.cpp</a>, is
|
||||||
@@ -126,6 +131,12 @@
|
|||||||
<p>Functions which destroy objects of the pointed to type are prohibited from
|
<p>Functions which destroy objects of the pointed to type are prohibited from
|
||||||
throwing exceptions by the <a href="#common_requirements">common requirements</a>.</p>
|
throwing exceptions by the <a href="#common_requirements">common requirements</a>.</p>
|
||||||
<h2><a name="History">History</a> and Acknowledgements</h2>
|
<h2><a name="History">History</a> and Acknowledgements</h2>
|
||||||
|
<p>November 2012. Glen Fernandes provided implementations of <b>make_shared</b>
|
||||||
|
and <b>allocate_shared</b> for arrays. They achieve a single allocation for an
|
||||||
|
array that can be initialized with constructor arguments or initializer lists
|
||||||
|
as well as overloads for default initialization and no value initialization.
|
||||||
|
See the <a href="make_shared_array.html">make_shared and allocate_shared for
|
||||||
|
arrays</a> page for more information.</p>
|
||||||
<p>January 2002. Peter Dimov reworked all four classes, adding features, fixing
|
<p>January 2002. Peter Dimov reworked all four classes, adding features, fixing
|
||||||
bugs, and splitting them into four separate headers, and added <b>weak_ptr</b>.
|
bugs, and splitting them into four separate headers, and added <b>weak_ptr</b>.
|
||||||
See the <a href="compatibility.htm">compatibility</a> page for a summary of the
|
See the <a href="compatibility.htm">compatibility</a> page for a summary of the
|
||||||
|
@@ -624,7 +624,7 @@ public:
|
|||||||
<h2><A name="wrapper">Using <code>shared_ptr</code> to wrap member function calls</A></h2>
|
<h2><A name="wrapper">Using <code>shared_ptr</code> to wrap member function calls</A></h2>
|
||||||
<p><code>shared_ptr</code> implements the ownership semantics required from the <code>Wrap</code>/<code>CallProxy</code>
|
<p><code>shared_ptr</code> implements the ownership semantics required from the <code>Wrap</code>/<code>CallProxy</code>
|
||||||
scheme described in Bjarne Stroustrup's article "Wrapping C++ Member Function
|
scheme described in Bjarne Stroustrup's article "Wrapping C++ Member Function
|
||||||
Calls" (available online at <A href="http://www.research.att.com/~bs/wrapper.pdf">http://www.research.att.com/~bs/wrapper.pdf</A>).
|
Calls" (available online at <A href="http://www.stroustrup.com/wrapper.pdf">http://www.stroustrup.com/wrapper.pdf</A>).
|
||||||
An implementation is given below:</p>
|
An implementation is given below:</p>
|
||||||
<pre>template<class T> class pointer
|
<pre>template<class T> class pointer
|
||||||
{
|
{
|
||||||
|
@@ -21,6 +21,7 @@ import testing ;
|
|||||||
[ run get_deleter_test.cpp ]
|
[ run get_deleter_test.cpp ]
|
||||||
[ run intrusive_ptr_test.cpp ]
|
[ run intrusive_ptr_test.cpp ]
|
||||||
[ run intrusive_ptr_move_test.cpp ]
|
[ run intrusive_ptr_move_test.cpp ]
|
||||||
|
[ run intrusive_ref_counter_test.cpp ]
|
||||||
[ run atomic_count_test.cpp ]
|
[ run atomic_count_test.cpp ]
|
||||||
[ run lw_mutex_test.cpp ]
|
[ run lw_mutex_test.cpp ]
|
||||||
[ compile-fail shared_ptr_assign_fail.cpp ]
|
[ compile-fail shared_ptr_assign_fail.cpp ]
|
||||||
@@ -45,7 +46,8 @@ import testing ;
|
|||||||
[ run spinlock_try_test.cpp : : : <threading>multi : spinlock_try_test.mt ]
|
[ run spinlock_try_test.cpp : : : <threading>multi : spinlock_try_test.mt ]
|
||||||
[ run spinlock_pool_test.cpp ]
|
[ run spinlock_pool_test.cpp ]
|
||||||
[ run make_shared_test.cpp ]
|
[ run make_shared_test.cpp ]
|
||||||
[ run sp_convertible_test.cpp ]
|
[ run make_shared_perfect_forwarding_test.cpp ]
|
||||||
|
[ run shared_ptr_convertible_test.cpp ]
|
||||||
[ run wp_convertible_test.cpp ]
|
[ run wp_convertible_test.cpp ]
|
||||||
[ run ip_convertible_test.cpp ]
|
[ run ip_convertible_test.cpp ]
|
||||||
[ run allocate_shared_test.cpp ]
|
[ run allocate_shared_test.cpp ]
|
||||||
@@ -59,7 +61,97 @@ import testing ;
|
|||||||
[ run sp_recursive_assign_rv_test.cpp ]
|
[ run sp_recursive_assign_rv_test.cpp ]
|
||||||
[ run sp_recursive_assign2_rv_test.cpp ]
|
[ run sp_recursive_assign2_rv_test.cpp ]
|
||||||
[ run esft_constructor_test.cpp ]
|
[ run esft_constructor_test.cpp ]
|
||||||
|
[ run enable_shared_from_raw_test.cpp ]
|
||||||
[ compile-fail auto_ptr_lv_fail.cpp ]
|
[ compile-fail auto_ptr_lv_fail.cpp ]
|
||||||
[ run atomic_count_test2.cpp ]
|
[ run atomic_count_test2.cpp ]
|
||||||
|
[ run sp_typeinfo_test.cpp ]
|
||||||
|
[ compile make_shared_fp_test.cpp ]
|
||||||
|
[ run sp_hash_test.cpp ]
|
||||||
|
[ run get_deleter_array_test.cpp ]
|
||||||
|
[ run ip_hash_test.cpp ]
|
||||||
|
[ run owner_less_test.cpp ]
|
||||||
|
[ run sp_unique_ptr_test.cpp ]
|
||||||
|
[ run sp_array_test.cpp ]
|
||||||
|
[ compile sp_array_cv_test.cpp ]
|
||||||
|
[ run sp_convertible_test.cpp ]
|
||||||
|
[ run sp_array_n_test.cpp ]
|
||||||
|
[ run sp_array_cast_test.cpp ]
|
||||||
|
[ run sp_zero_compare_test.cpp ]
|
||||||
|
[ run sp_nullptr_test.cpp ]
|
||||||
|
|
||||||
|
[ compile-fail array_fail_spa_sp_c.cpp ]
|
||||||
|
[ compile-fail array_fail_sp_spa_c.cpp ]
|
||||||
|
[ compile-fail array_fail_spa_spa_c.cpp ]
|
||||||
|
[ compile-fail array_fail_spa_wp_c.cpp ]
|
||||||
|
[ compile-fail array_fail_sp_wpa_c.cpp ]
|
||||||
|
[ compile-fail array_fail_spa_wpa_c.cpp ]
|
||||||
|
[ compile-fail array_fail_wpa_wp_c.cpp ]
|
||||||
|
[ compile-fail array_fail_wp_wpa_c.cpp ]
|
||||||
|
[ compile-fail array_fail_wpa_wpa_c.cpp ]
|
||||||
|
[ compile-fail array_fail_ap_spa_c.cpp ]
|
||||||
|
[ compile-fail array_fail_upa_sp_c.cpp ]
|
||||||
|
[ compile-fail array_fail_up_spa_c.cpp ]
|
||||||
|
|
||||||
|
[ compile-fail array_fail_spa_sp_mc.cpp ]
|
||||||
|
[ compile-fail array_fail_sp_spa_mc.cpp ]
|
||||||
|
[ compile-fail array_fail_spa_spa_mc.cpp ]
|
||||||
|
[ compile-fail array_fail_spa_wp_mc.cpp ]
|
||||||
|
[ compile-fail array_fail_sp_wpa_mc.cpp ]
|
||||||
|
[ compile-fail array_fail_spa_wpa_mc.cpp ]
|
||||||
|
[ compile-fail array_fail_wpa_wp_mc.cpp ]
|
||||||
|
[ compile-fail array_fail_wp_wpa_mc.cpp ]
|
||||||
|
[ compile-fail array_fail_wpa_wpa_mc.cpp ]
|
||||||
|
[ compile-fail array_fail_ap_spa_mc.cpp ]
|
||||||
|
[ compile-fail array_fail_upa_sp_mc.cpp ]
|
||||||
|
[ compile-fail array_fail_up_spa_mc.cpp ]
|
||||||
|
|
||||||
|
[ compile-fail array_fail_spa_sp_a.cpp ]
|
||||||
|
[ compile-fail array_fail_sp_spa_a.cpp ]
|
||||||
|
[ compile-fail array_fail_spa_spa_a.cpp ]
|
||||||
|
[ compile-fail array_fail_spa_wp_a.cpp ]
|
||||||
|
[ compile-fail array_fail_sp_wpa_a.cpp ]
|
||||||
|
[ compile-fail array_fail_spa_wpa_a.cpp ]
|
||||||
|
[ compile-fail array_fail_wpa_wp_a.cpp ]
|
||||||
|
[ compile-fail array_fail_wp_wpa_a.cpp ]
|
||||||
|
[ compile-fail array_fail_wpa_wpa_a.cpp ]
|
||||||
|
[ compile-fail array_fail_ap_spa_a.cpp ]
|
||||||
|
[ compile-fail array_fail_upa_sp_a.cpp ]
|
||||||
|
[ compile-fail array_fail_up_spa_a.cpp ]
|
||||||
|
|
||||||
|
[ compile-fail array_fail_spa_sp_ma.cpp ]
|
||||||
|
[ compile-fail array_fail_sp_spa_ma.cpp ]
|
||||||
|
[ compile-fail array_fail_spa_spa_ma.cpp ]
|
||||||
|
[ compile-fail array_fail_spa_wp_ma.cpp ]
|
||||||
|
[ compile-fail array_fail_sp_wpa_ma.cpp ]
|
||||||
|
[ compile-fail array_fail_spa_wpa_ma.cpp ]
|
||||||
|
[ compile-fail array_fail_wpa_wp_ma.cpp ]
|
||||||
|
[ compile-fail array_fail_wp_wpa_ma.cpp ]
|
||||||
|
[ compile-fail array_fail_wpa_wpa_ma.cpp ]
|
||||||
|
[ compile-fail array_fail_ap_spa_ma.cpp ]
|
||||||
|
[ compile-fail array_fail_upa_sp_ma.cpp ]
|
||||||
|
[ compile-fail array_fail_up_spa_ma.cpp ]
|
||||||
|
|
||||||
|
[ compile-fail array_fail_dereference.cpp ]
|
||||||
|
[ compile-fail array_fail_member_access.cpp ]
|
||||||
|
[ compile-fail array_fail_array_access.cpp ]
|
||||||
|
|
||||||
|
[ run make_shared_array_test.cpp ]
|
||||||
|
[ run make_shared_arrays_test.cpp ]
|
||||||
|
[ run make_shared_array_create_test.cpp ]
|
||||||
|
[ run make_shared_array_init_test.cpp : : : <toolset>gcc-4.6.3_0x:<cxxflags>-fno-deduce-init-list ]
|
||||||
|
[ run make_shared_arrays_create_test.cpp : : : <toolset>gcc-4.6.3_0x:<cxxflags>-fno-deduce-init-list ]
|
||||||
|
[ run make_shared_arrays_init_test.cpp : : : <toolset>gcc-4.6.3_0x:<cxxflags>-fno-deduce-init-list ]
|
||||||
|
[ run make_shared_array_throws_test.cpp ]
|
||||||
|
[ run make_shared_array_esft_test.cpp ]
|
||||||
|
[ run make_shared_array_args_test.cpp ]
|
||||||
|
[ run allocate_shared_array_test.cpp ]
|
||||||
|
[ run allocate_shared_arrays_test.cpp ]
|
||||||
|
[ run allocate_shared_array_create_test.cpp ]
|
||||||
|
[ run allocate_shared_array_init_test.cpp : : : <toolset>gcc-4.6.3_0x:<cxxflags>-fno-deduce-init-list ]
|
||||||
|
[ run allocate_shared_arrays_create_test.cpp : : : <toolset>gcc-4.6.3_0x:<cxxflags>-fno-deduce-init-list ]
|
||||||
|
[ run allocate_shared_arrays_init_test.cpp : : : <toolset>gcc-4.6.3_0x:<cxxflags>-fno-deduce-init-list ]
|
||||||
|
[ run allocate_shared_array_throws_test.cpp ]
|
||||||
|
[ run allocate_shared_array_esft_test.cpp ]
|
||||||
|
[ run allocate_shared_array_args_test.cpp ]
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
173
test/allocate_shared_array_args_test.cpp
Normal file
173
test/allocate_shared_array_args_test.cpp
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
// allocate_shared_array_args_test.cpp
|
||||||
|
//
|
||||||
|
// Copyright 2007-2009, 2012 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
|
||||||
|
#include <boost/detail/lightweight_test.hpp>
|
||||||
|
#include <boost/make_shared.hpp>
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
#include <memory>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
class X
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
X( X const & );
|
||||||
|
X & operator=( X const & );
|
||||||
|
|
||||||
|
void * operator new[]( std::size_t n );
|
||||||
|
void operator delete[]( void * p );
|
||||||
|
|
||||||
|
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_TEST( X::instances == 0 );
|
||||||
|
|
||||||
|
{
|
||||||
|
boost::shared_ptr< X[] > px = boost::allocate_shared< X[] >( std::allocator<X>(), 2 );
|
||||||
|
|
||||||
|
BOOST_TEST( X::instances == 2 );
|
||||||
|
BOOST_TEST( px[0].v == 0 );
|
||||||
|
BOOST_TEST( px[1].v == 0 );
|
||||||
|
|
||||||
|
px.reset();
|
||||||
|
|
||||||
|
BOOST_TEST( X::instances == 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||||
|
|
||||||
|
{
|
||||||
|
boost::shared_ptr< X[] > px = boost::allocate_shared< X[] >( std::allocator<X>(), 2, 1 );
|
||||||
|
|
||||||
|
BOOST_TEST( X::instances == 2 );
|
||||||
|
BOOST_TEST( px[0].v == 1 );
|
||||||
|
BOOST_TEST( px[1].v == 1 );
|
||||||
|
|
||||||
|
px.reset();
|
||||||
|
|
||||||
|
BOOST_TEST( X::instances == 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
boost::shared_ptr< X[] > px = boost::allocate_shared< X[] >( std::allocator<X>(), 2, 1, 2 );
|
||||||
|
|
||||||
|
BOOST_TEST( X::instances == 2 );
|
||||||
|
BOOST_TEST( px[0].v == 1+2 );
|
||||||
|
BOOST_TEST( px[1].v == 1+2 );
|
||||||
|
|
||||||
|
px.reset();
|
||||||
|
|
||||||
|
BOOST_TEST( X::instances == 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
boost::shared_ptr< X[] > px = boost::allocate_shared< X[] >( std::allocator<X>(), 2, 1, 2, 3 );
|
||||||
|
|
||||||
|
BOOST_TEST( X::instances == 2 );
|
||||||
|
BOOST_TEST( px[0].v == 1+2+3 );
|
||||||
|
BOOST_TEST( px[1].v == 1+2+3 );
|
||||||
|
|
||||||
|
px.reset();
|
||||||
|
|
||||||
|
BOOST_TEST( X::instances == 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
boost::shared_ptr< X[] > px = boost::allocate_shared< X[] >( std::allocator<X>(), 2, 1, 2, 3, 4 );
|
||||||
|
|
||||||
|
BOOST_TEST( X::instances == 2 );
|
||||||
|
BOOST_TEST( px[0].v == 1+2+3+4 );
|
||||||
|
BOOST_TEST( px[1].v == 1+2+3+4 );
|
||||||
|
|
||||||
|
px.reset();
|
||||||
|
|
||||||
|
BOOST_TEST( X::instances == 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
boost::shared_ptr< X[] > px = boost::allocate_shared< X[] >( std::allocator<X>(), 2, 1, 2, 3, 4, 5 );
|
||||||
|
|
||||||
|
BOOST_TEST( X::instances == 2 );
|
||||||
|
BOOST_TEST( px[0].v == 1+2+3+4+5 );
|
||||||
|
BOOST_TEST( px[1].v == 1+2+3+4+5 );
|
||||||
|
|
||||||
|
px.reset();
|
||||||
|
|
||||||
|
BOOST_TEST( X::instances == 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
boost::shared_ptr< X[] > px = boost::allocate_shared< X[] >( std::allocator<X>(), 2, 1, 2, 3, 4, 5, 6 );
|
||||||
|
|
||||||
|
BOOST_TEST( X::instances == 2 );
|
||||||
|
BOOST_TEST( px[0].v == 1+2+3+4+5+6 );
|
||||||
|
BOOST_TEST( px[1].v == 1+2+3+4+5+6 );
|
||||||
|
|
||||||
|
px.reset();
|
||||||
|
|
||||||
|
BOOST_TEST( X::instances == 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
boost::shared_ptr< X[] > px = boost::allocate_shared< X[] >( std::allocator<X>(), 2, 1, 2, 3, 4, 5, 6, 7 );
|
||||||
|
|
||||||
|
BOOST_TEST( X::instances == 2 );
|
||||||
|
BOOST_TEST( px[0].v == 1+2+3+4+5+6+7 );
|
||||||
|
BOOST_TEST( px[1].v == 1+2+3+4+5+6+7 );
|
||||||
|
|
||||||
|
px.reset();
|
||||||
|
|
||||||
|
BOOST_TEST( X::instances == 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
boost::shared_ptr< X[] > px = boost::allocate_shared< X[] >( std::allocator<X>(), 2, 1, 2, 3, 4, 5, 6, 7, 8 );
|
||||||
|
|
||||||
|
BOOST_TEST( X::instances == 2 );
|
||||||
|
BOOST_TEST( px[0].v == 1+2+3+4+5+6+7+8 );
|
||||||
|
BOOST_TEST( px[1].v == 1+2+3+4+5+6+7+8 );
|
||||||
|
|
||||||
|
px.reset();
|
||||||
|
|
||||||
|
BOOST_TEST( X::instances == 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
boost::shared_ptr< X[] > px = boost::allocate_shared< X[] >( std::allocator<X>(), 2, 1, 2, 3, 4, 5, 6, 7, 8, 9 );
|
||||||
|
|
||||||
|
BOOST_TEST( X::instances == 2 );
|
||||||
|
BOOST_TEST( px[0].v == 1+2+3+4+5+6+7+8+9 );
|
||||||
|
BOOST_TEST( px[1].v == 1+2+3+4+5+6+7+8+9 );
|
||||||
|
|
||||||
|
px.reset();
|
||||||
|
|
||||||
|
BOOST_TEST( X::instances == 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
114
test/allocate_shared_array_create_test.cpp
Normal file
114
test/allocate_shared_array_create_test.cpp
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2012 Glen Joseph Fernandes
|
||||||
|
* glenfe at live dot com
|
||||||
|
*
|
||||||
|
* Distributed under the Boost Software License,
|
||||||
|
* Version 1.0. (See accompanying file LICENSE_1_0.txt
|
||||||
|
* or copy at http://boost.org/LICENSE_1_0.txt)
|
||||||
|
*/
|
||||||
|
#include <boost/detail/lightweight_test.hpp>
|
||||||
|
#include <boost/smart_ptr/allocate_shared_array.hpp>
|
||||||
|
|
||||||
|
class type {
|
||||||
|
public:
|
||||||
|
static int instances;
|
||||||
|
explicit type(int a=0, int b=0, int c=0, int d=0, int e=0, int f=0, int g=0, int h=0, int i=0)
|
||||||
|
: a(a), b(b), c(c), d(d), e(e), f(f), g(g), h(h), i(i) {
|
||||||
|
instances++;
|
||||||
|
}
|
||||||
|
~type() {
|
||||||
|
instances--;
|
||||||
|
}
|
||||||
|
const int a;
|
||||||
|
const int b;
|
||||||
|
const int c;
|
||||||
|
const int d;
|
||||||
|
const int e;
|
||||||
|
const int f;
|
||||||
|
const int g;
|
||||||
|
const int h;
|
||||||
|
const int i;
|
||||||
|
private:
|
||||||
|
type(const type&);
|
||||||
|
type& operator=(const type&);
|
||||||
|
};
|
||||||
|
|
||||||
|
int type::instances = 0;
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
{
|
||||||
|
boost::shared_ptr<type[]> a1 = boost::allocate_shared<type[]>(std::allocator<type>(), 2, 1, 2, 3, 4, 5, 6, 7, 8, 9);
|
||||||
|
BOOST_TEST(type::instances == 2);
|
||||||
|
BOOST_TEST(a1[0].a == 1);
|
||||||
|
BOOST_TEST(a1[0].d == 4);
|
||||||
|
BOOST_TEST(a1[1].f == 6);
|
||||||
|
BOOST_TEST(a1[1].i == 9);
|
||||||
|
}
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
{
|
||||||
|
boost::shared_ptr<type[2]> a1 = boost::allocate_shared<type[2]>(std::allocator<type>(), 1, 2, 3, 4, 5, 6, 7, 8, 9);
|
||||||
|
BOOST_TEST(type::instances == 2);
|
||||||
|
BOOST_TEST(a1[0].a == 1);
|
||||||
|
BOOST_TEST(a1[0].d == 4);
|
||||||
|
BOOST_TEST(a1[1].f == 6);
|
||||||
|
BOOST_TEST(a1[1].i == 9);
|
||||||
|
}
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
{
|
||||||
|
boost::shared_ptr<type[][2]> a1 = boost::allocate_shared<type[][2]>(std::allocator<type>(), 2, 1, 2, 3, 4, 5, 6, 7);
|
||||||
|
BOOST_TEST(type::instances == 4);
|
||||||
|
BOOST_TEST(a1[0][0].a == 1);
|
||||||
|
BOOST_TEST(a1[0][1].d == 4);
|
||||||
|
BOOST_TEST(a1[1][0].f == 6);
|
||||||
|
BOOST_TEST(a1[1][1].i == 0);
|
||||||
|
}
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
{
|
||||||
|
boost::shared_ptr<type[2][2]> a1 = boost::allocate_shared<type[2][2]>(std::allocator<type>(), 1, 2, 3, 4, 5, 6, 7);
|
||||||
|
BOOST_TEST(type::instances == 4);
|
||||||
|
BOOST_TEST(a1[0][0].a == 1);
|
||||||
|
BOOST_TEST(a1[0][1].d == 4);
|
||||||
|
BOOST_TEST(a1[1][0].f == 6);
|
||||||
|
BOOST_TEST(a1[1][1].i == 0);
|
||||||
|
}
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
{
|
||||||
|
boost::shared_ptr<type[][2][2]> a1 = boost::allocate_shared<type[][2][2]>(std::allocator<type>(), 2, 1, 2, 3, 4, 5);
|
||||||
|
BOOST_TEST(type::instances == 8);
|
||||||
|
BOOST_TEST(a1[0][0][0].a == 1);
|
||||||
|
BOOST_TEST(a1[0][1][0].c == 3);
|
||||||
|
BOOST_TEST(a1[1][0][1].e == 5);
|
||||||
|
BOOST_TEST(a1[1][1][1].i == 0);
|
||||||
|
}
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
{
|
||||||
|
boost::shared_ptr<type[2][2][2]> a1 = boost::allocate_shared<type[2][2][2]>(std::allocator<type>(), 1, 2, 3, 4, 5);
|
||||||
|
BOOST_TEST(type::instances == 8);
|
||||||
|
BOOST_TEST(a1[0][0][0].a == 1);
|
||||||
|
BOOST_TEST(a1[0][1][0].c == 3);
|
||||||
|
BOOST_TEST(a1[1][0][1].e == 5);
|
||||||
|
BOOST_TEST(a1[1][1][1].i == 0);
|
||||||
|
}
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
{
|
||||||
|
boost::shared_ptr<type[][2][2][2]> a1 = boost::allocate_shared<type[][2][2][2]>(std::allocator<type>(), 2, 1, 2, 3);
|
||||||
|
BOOST_TEST(type::instances == 16);
|
||||||
|
BOOST_TEST(a1[0][0][0][1].a == 1);
|
||||||
|
BOOST_TEST(a1[0][0][1][0].c == 3);
|
||||||
|
BOOST_TEST(a1[0][1][0][0].f == 0);
|
||||||
|
BOOST_TEST(a1[1][0][0][0].i == 0);
|
||||||
|
}
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
{
|
||||||
|
boost::shared_ptr<type[2][2][2][2]> a1 = boost::allocate_shared<type[2][2][2][2]>(std::allocator<type>(), 1, 2, 3);
|
||||||
|
BOOST_TEST(type::instances == 16);
|
||||||
|
BOOST_TEST(a1[0][0][0][1].a == 1);
|
||||||
|
BOOST_TEST(a1[0][0][1][0].c == 3);
|
||||||
|
BOOST_TEST(a1[0][1][0][0].f == 0);
|
||||||
|
BOOST_TEST(a1[1][0][0][0].i == 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
52
test/allocate_shared_array_esft_test.cpp
Normal file
52
test/allocate_shared_array_esft_test.cpp
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2012 Glen Joseph Fernandes
|
||||||
|
* glenfe at live dot com
|
||||||
|
*
|
||||||
|
* Distributed under the Boost Software License,
|
||||||
|
* Version 1.0. (See accompanying file LICENSE_1_0.txt
|
||||||
|
* or copy at http://boost.org/LICENSE_1_0.txt)
|
||||||
|
*/
|
||||||
|
#include <boost/detail/lightweight_test.hpp>
|
||||||
|
#include <boost/smart_ptr/allocate_shared_array.hpp>
|
||||||
|
#include <boost/smart_ptr/enable_shared_from_this.hpp>
|
||||||
|
|
||||||
|
class type
|
||||||
|
: public boost::enable_shared_from_this<type> {
|
||||||
|
public:
|
||||||
|
static unsigned int instances;
|
||||||
|
explicit type() {
|
||||||
|
instances++;
|
||||||
|
}
|
||||||
|
~type() {
|
||||||
|
instances--;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
type(const type&);
|
||||||
|
type& operator=(const type&);
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned int type::instances = 0;
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
{
|
||||||
|
boost::shared_ptr<type[]> a1 = boost::allocate_shared<type[]>(std::allocator<type>(), 3);
|
||||||
|
try {
|
||||||
|
a1[0].shared_from_this();
|
||||||
|
BOOST_ERROR("shared_from_this did not throw");
|
||||||
|
} catch (...) {
|
||||||
|
BOOST_TEST(type::instances == 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
{
|
||||||
|
boost::shared_ptr<type[]> a1 = boost::allocate_shared_noinit<type[]>(std::allocator<type>(), 3);
|
||||||
|
try {
|
||||||
|
a1[0].shared_from_this();
|
||||||
|
BOOST_ERROR("shared_from_this did not throw");
|
||||||
|
} catch (...) {
|
||||||
|
BOOST_TEST(type::instances == 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
84
test/allocate_shared_array_init_test.cpp
Normal file
84
test/allocate_shared_array_init_test.cpp
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2012 Glen Joseph Fernandes
|
||||||
|
* glenfe at live dot com
|
||||||
|
*
|
||||||
|
* Distributed under the Boost Software License,
|
||||||
|
* Version 1.0. (See accompanying file LICENSE_1_0.txt
|
||||||
|
* or copy at http://boost.org/LICENSE_1_0.txt)
|
||||||
|
*/
|
||||||
|
#include <boost/detail/lightweight_test.hpp>
|
||||||
|
#include <boost/smart_ptr/allocate_shared_array.hpp>
|
||||||
|
|
||||||
|
class type {
|
||||||
|
public:
|
||||||
|
type(int value)
|
||||||
|
: value(value) {
|
||||||
|
}
|
||||||
|
const int value;
|
||||||
|
private:
|
||||||
|
type& operator=(const type&);
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
|
||||||
|
{
|
||||||
|
boost::shared_ptr<int[4]> a1 = boost::allocate_shared<int[4]>(std::allocator<int>(), { 0, 1, 2, 3 });
|
||||||
|
BOOST_TEST(a1[0] == 0);
|
||||||
|
BOOST_TEST(a1[1] == 1);
|
||||||
|
BOOST_TEST(a1[2] == 2);
|
||||||
|
BOOST_TEST(a1[3] == 3);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
boost::shared_ptr<const int[4]> a1 = boost::allocate_shared<const int[4]>(std::allocator<int>(), { 0, 1, 2, 3 });
|
||||||
|
BOOST_TEST(a1[0] == 0);
|
||||||
|
BOOST_TEST(a1[1] == 1);
|
||||||
|
BOOST_TEST(a1[2] == 2);
|
||||||
|
BOOST_TEST(a1[3] == 3);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
boost::shared_ptr<type[4]> a1 = boost::allocate_shared<type[4]>(std::allocator<type>(), { 0, 1, 2, 3 });
|
||||||
|
BOOST_TEST(a1[0].value == 0);
|
||||||
|
BOOST_TEST(a1[1].value == 1);
|
||||||
|
BOOST_TEST(a1[2].value == 2);
|
||||||
|
BOOST_TEST(a1[3].value == 3);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
boost::shared_ptr<const type[4]> a1 = boost::allocate_shared<const type[4]>(std::allocator<type>(), { 0, 1, 2, 3 });
|
||||||
|
BOOST_TEST(a1[0].value == 0);
|
||||||
|
BOOST_TEST(a1[1].value == 1);
|
||||||
|
BOOST_TEST(a1[2].value == 2);
|
||||||
|
BOOST_TEST(a1[3].value == 3);
|
||||||
|
}
|
||||||
|
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||||
|
{
|
||||||
|
boost::shared_ptr<int[]> a1 = boost::allocate_shared<int[]>(std::allocator<int>(), { 0, 1, 2, 3 });
|
||||||
|
BOOST_TEST(a1[0] == 0);
|
||||||
|
BOOST_TEST(a1[1] == 1);
|
||||||
|
BOOST_TEST(a1[2] == 2);
|
||||||
|
BOOST_TEST(a1[3] == 3);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
boost::shared_ptr<const int[]> a1 = boost::allocate_shared<const int[]>(std::allocator<int>(), { 0, 1, 2, 3 });
|
||||||
|
BOOST_TEST(a1[0] == 0);
|
||||||
|
BOOST_TEST(a1[1] == 1);
|
||||||
|
BOOST_TEST(a1[2] == 2);
|
||||||
|
BOOST_TEST(a1[3] == 3);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
boost::shared_ptr<type[]> a1 = boost::allocate_shared<type[]>(std::allocator<type>(), { 0, 1, 2, 3 });
|
||||||
|
BOOST_TEST(a1[0].value == 0);
|
||||||
|
BOOST_TEST(a1[1].value == 1);
|
||||||
|
BOOST_TEST(a1[2].value == 2);
|
||||||
|
BOOST_TEST(a1[3].value == 3);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
boost::shared_ptr<const type[]> a1 = boost::allocate_shared<const type[]>(std::allocator<type>(), { 0, 1, 2, 3 });
|
||||||
|
BOOST_TEST(a1[0].value == 0);
|
||||||
|
BOOST_TEST(a1[1].value == 1);
|
||||||
|
BOOST_TEST(a1[2].value == 2);
|
||||||
|
BOOST_TEST(a1[3].value == 3);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
199
test/allocate_shared_array_test.cpp
Normal file
199
test/allocate_shared_array_test.cpp
Normal file
@@ -0,0 +1,199 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2012 Glen Joseph Fernandes
|
||||||
|
* glenfe at live dot com
|
||||||
|
*
|
||||||
|
* Distributed under the Boost Software License,
|
||||||
|
* Version 1.0. (See accompanying file LICENSE_1_0.txt
|
||||||
|
* or copy at http://boost.org/LICENSE_1_0.txt)
|
||||||
|
*/
|
||||||
|
#include <boost/detail/lightweight_test.hpp>
|
||||||
|
#include <boost/smart_ptr/allocate_shared_array.hpp>
|
||||||
|
#include <boost/smart_ptr/weak_ptr.hpp>
|
||||||
|
#include <boost/type_traits/alignment_of.hpp>
|
||||||
|
|
||||||
|
class type {
|
||||||
|
public:
|
||||||
|
static unsigned int instances;
|
||||||
|
explicit type(int = 0, int = 0)
|
||||||
|
: member() {
|
||||||
|
instances++;
|
||||||
|
}
|
||||||
|
~type() {
|
||||||
|
instances--;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
type(const type&);
|
||||||
|
type& operator=(const type&);
|
||||||
|
double member;
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned int type::instances = 0;
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
{
|
||||||
|
boost::shared_ptr<int[]> a1 = boost::allocate_shared<int[]>(std::allocator<int>(), 3);
|
||||||
|
int* a2 = a1.get();
|
||||||
|
BOOST_TEST(a1.use_count() == 1);
|
||||||
|
BOOST_TEST(a2 != 0);
|
||||||
|
BOOST_TEST(size_t(a2) % boost::alignment_of<int>::value == 0);
|
||||||
|
BOOST_TEST(a1[0] == 0);
|
||||||
|
BOOST_TEST(a1[1] == 0);
|
||||||
|
BOOST_TEST(a1[2] == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
boost::shared_ptr<const int[]> a1 = boost::allocate_shared<const int[]>(std::allocator<int>(), 3);
|
||||||
|
const int* a2 = a1.get();
|
||||||
|
BOOST_TEST(a1.use_count() == 1);
|
||||||
|
BOOST_TEST(a2 != 0);
|
||||||
|
BOOST_TEST(size_t(a2) % boost::alignment_of<int>::value == 0);
|
||||||
|
BOOST_TEST(a1[0] == 0);
|
||||||
|
BOOST_TEST(a1[1] == 0);
|
||||||
|
BOOST_TEST(a1[2] == 0);
|
||||||
|
}
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
{
|
||||||
|
boost::shared_ptr<type[]> a1 = boost::allocate_shared<type[]>(std::allocator<type>(), 3);
|
||||||
|
type* a2 = a1.get();
|
||||||
|
BOOST_TEST(a1.use_count() == 1);
|
||||||
|
BOOST_TEST(a2 != 0);
|
||||||
|
BOOST_TEST(size_t(a2) % boost::alignment_of<type>::value == 0);
|
||||||
|
BOOST_TEST(type::instances == 3);
|
||||||
|
boost::weak_ptr<type[]> w1 = a1;
|
||||||
|
a1.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
{
|
||||||
|
boost::shared_ptr<const type[]> a1 = boost::allocate_shared<const type[]>(std::allocator<type>(), 3);
|
||||||
|
const type* a2 = a1.get();
|
||||||
|
BOOST_TEST(a1.use_count() == 1);
|
||||||
|
BOOST_TEST(a2 != 0);
|
||||||
|
BOOST_TEST(size_t(a2) % boost::alignment_of<type>::value == 0);
|
||||||
|
BOOST_TEST(type::instances == 3);
|
||||||
|
a1.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
{
|
||||||
|
boost::shared_ptr<type[]> a1 = boost::allocate_shared<type[]>(std::allocator<type>(), 3, 1, 5);
|
||||||
|
type* a2 = a1.get();
|
||||||
|
BOOST_TEST(a1.use_count() == 1);
|
||||||
|
BOOST_TEST(a2 != 0);
|
||||||
|
BOOST_TEST(size_t(a2) % boost::alignment_of<type>::value == 0);
|
||||||
|
BOOST_TEST(type::instances == 3);
|
||||||
|
boost::weak_ptr<type[]> w1 = a1;
|
||||||
|
a1.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
{
|
||||||
|
boost::shared_ptr<type[3]> a1 = boost::allocate_shared<type[3]>(std::allocator<type>(), 1, 5);
|
||||||
|
type* a2 = a1.get();
|
||||||
|
BOOST_TEST(a1.use_count() == 1);
|
||||||
|
BOOST_TEST(a2 != 0);
|
||||||
|
BOOST_TEST(size_t(a2) % boost::alignment_of<type>::value == 0);
|
||||||
|
BOOST_TEST(type::instances == 3);
|
||||||
|
boost::weak_ptr<type[3]> w1 = a1;
|
||||||
|
a1.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
{
|
||||||
|
boost::shared_ptr<const type[]> a1 = boost::allocate_shared<const type[]>(std::allocator<type>(), 3, 1, 5);
|
||||||
|
const type* a2 = a1.get();
|
||||||
|
BOOST_TEST(a1.use_count() == 1);
|
||||||
|
BOOST_TEST(a2 != 0);
|
||||||
|
BOOST_TEST(size_t(a2) % boost::alignment_of<type>::value == 0);
|
||||||
|
BOOST_TEST(type::instances == 3);
|
||||||
|
a1.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
{
|
||||||
|
boost::shared_ptr<const type[3]> a1 = boost::allocate_shared<const type[3]>(std::allocator<type>(), 1, 5);
|
||||||
|
const type* a2 = a1.get();
|
||||||
|
BOOST_TEST(a1.use_count() == 1);
|
||||||
|
BOOST_TEST(a2 != 0);
|
||||||
|
BOOST_TEST(size_t(a2) % boost::alignment_of<type>::value == 0);
|
||||||
|
BOOST_TEST(type::instances == 3);
|
||||||
|
a1.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
boost::shared_ptr<int[]> a1 = boost::allocate_shared_noinit<int[]>(std::allocator<int>(), 3);
|
||||||
|
int* a2 = a1.get();
|
||||||
|
BOOST_TEST(a1.use_count() == 1);
|
||||||
|
BOOST_TEST(a2 != 0);
|
||||||
|
BOOST_TEST(size_t(a2) % boost::alignment_of<int>::value == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
boost::shared_ptr<int[3]> a1 = boost::allocate_shared_noinit<int[3]>(std::allocator<int>());
|
||||||
|
int* a2 = a1.get();
|
||||||
|
BOOST_TEST(a1.use_count() == 1);
|
||||||
|
BOOST_TEST(a2 != 0);
|
||||||
|
BOOST_TEST(size_t(a2) % boost::alignment_of<int>::value == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
boost::shared_ptr<const int[]> a1 = boost::allocate_shared_noinit<const int[]>(std::allocator<int>(), 3);
|
||||||
|
const int* a2 = a1.get();
|
||||||
|
BOOST_TEST(a1.use_count() == 1);
|
||||||
|
BOOST_TEST(a2 != 0);
|
||||||
|
BOOST_TEST(size_t(a2) % boost::alignment_of<int>::value == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
boost::shared_ptr<const int[3]> a1 = boost::allocate_shared_noinit<const int[3]>(std::allocator<int>());
|
||||||
|
const int* a2 = a1.get();
|
||||||
|
BOOST_TEST(a1.use_count() == 1);
|
||||||
|
BOOST_TEST(a2 != 0);
|
||||||
|
BOOST_TEST(size_t(a2) % boost::alignment_of<int>::value == 0);
|
||||||
|
}
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
{
|
||||||
|
boost::shared_ptr<type[]> a1 = boost::allocate_shared_noinit<type[]>(std::allocator<type>(), 3);
|
||||||
|
type* a2 = a1.get();
|
||||||
|
BOOST_TEST(a1.use_count() == 1);
|
||||||
|
BOOST_TEST(a2 != 0);
|
||||||
|
BOOST_TEST(size_t(a2) % boost::alignment_of<type>::value == 0);
|
||||||
|
BOOST_TEST(type::instances == 3);
|
||||||
|
boost::weak_ptr<type[]> w1 = a1;
|
||||||
|
a1.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
{
|
||||||
|
boost::shared_ptr<type[3]> a1 = boost::allocate_shared_noinit<type[3]>(std::allocator<type>());
|
||||||
|
type* a2 = a1.get();
|
||||||
|
BOOST_TEST(a1.use_count() == 1);
|
||||||
|
BOOST_TEST(a2 != 0);
|
||||||
|
BOOST_TEST(size_t(a2) % boost::alignment_of<type>::value == 0);
|
||||||
|
BOOST_TEST(type::instances == 3);
|
||||||
|
boost::weak_ptr<type[3]> w1 = a1;
|
||||||
|
a1.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
{
|
||||||
|
boost::shared_ptr<const type[]> a1 = boost::allocate_shared_noinit<const type[]>(std::allocator<type>(), 3);
|
||||||
|
const type* a2 = a1.get();
|
||||||
|
BOOST_TEST(a1.use_count() == 1);
|
||||||
|
BOOST_TEST(a2 != 0);
|
||||||
|
BOOST_TEST(size_t(a2) % boost::alignment_of<type>::value == 0);
|
||||||
|
BOOST_TEST(type::instances == 3);
|
||||||
|
a1.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
{
|
||||||
|
boost::shared_ptr<const type[3]> a1 = boost::allocate_shared_noinit<const type[3]>(std::allocator<type>());
|
||||||
|
const type* a2 = a1.get();
|
||||||
|
BOOST_TEST(a1.use_count() == 1);
|
||||||
|
BOOST_TEST(a2 != 0);
|
||||||
|
BOOST_TEST(size_t(a2) % boost::alignment_of<type>::value == 0);
|
||||||
|
BOOST_TEST(type::instances == 3);
|
||||||
|
a1.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
77
test/allocate_shared_array_throws_test.cpp
Normal file
77
test/allocate_shared_array_throws_test.cpp
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2012 Glen Joseph Fernandes
|
||||||
|
* glenfe at live dot com
|
||||||
|
*
|
||||||
|
* Distributed under the Boost Software License,
|
||||||
|
* Version 1.0. (See accompanying file LICENSE_1_0.txt
|
||||||
|
* or copy at http://boost.org/LICENSE_1_0.txt)
|
||||||
|
*/
|
||||||
|
#include <boost/detail/lightweight_test.hpp>
|
||||||
|
#include <boost/smart_ptr/allocate_shared_array.hpp>
|
||||||
|
|
||||||
|
class type {
|
||||||
|
public:
|
||||||
|
static unsigned int instances;
|
||||||
|
explicit type() {
|
||||||
|
if (instances == 5) {
|
||||||
|
throw true;
|
||||||
|
}
|
||||||
|
instances++;
|
||||||
|
}
|
||||||
|
~type() {
|
||||||
|
instances--;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
type(const type&);
|
||||||
|
type& operator=(const type&);
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned int type::instances = 0;
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
try {
|
||||||
|
boost::allocate_shared<type[]>(std::allocator<type>(), 6);
|
||||||
|
BOOST_ERROR("allocate_shared did not throw");
|
||||||
|
} catch (...) {
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
try {
|
||||||
|
boost::allocate_shared<type[][2]>(std::allocator<type>(), 3);
|
||||||
|
BOOST_ERROR("allocate_shared did not throw");
|
||||||
|
} catch (...) {
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
try {
|
||||||
|
boost::allocate_shared<type[6]>(std::allocator<type>());
|
||||||
|
BOOST_ERROR("allocate_shared did not throw");
|
||||||
|
} catch (...) {
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
try {
|
||||||
|
boost::allocate_shared<type[3][2]>(std::allocator<type>());
|
||||||
|
BOOST_ERROR("allocate_shared did not throw");
|
||||||
|
} catch (...) {
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
try {
|
||||||
|
boost::allocate_shared_noinit<type[]>(std::allocator<type>(), 6);
|
||||||
|
BOOST_ERROR("allocate_shared_noinit did not throw");
|
||||||
|
} catch (...) {
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
try {
|
||||||
|
boost::allocate_shared_noinit<type[][2]>(std::allocator<type>(), 3);
|
||||||
|
BOOST_ERROR("allocate_shared_noinit did not throw");
|
||||||
|
} catch (...) {
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
94
test/allocate_shared_arrays_create_test.cpp
Normal file
94
test/allocate_shared_arrays_create_test.cpp
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2012 Glen Joseph Fernandes
|
||||||
|
* glenfe at live dot com
|
||||||
|
*
|
||||||
|
* Distributed under the Boost Software License,
|
||||||
|
* Version 1.0. (See accompanying file LICENSE_1_0.txt
|
||||||
|
* or copy at http://boost.org/LICENSE_1_0.txt)
|
||||||
|
*/
|
||||||
|
#include <boost/detail/lightweight_test.hpp>
|
||||||
|
#include <boost/smart_ptr/allocate_shared_array.hpp>
|
||||||
|
|
||||||
|
class type {
|
||||||
|
public:
|
||||||
|
type(int x, int y)
|
||||||
|
: x(x), y(y) {
|
||||||
|
}
|
||||||
|
const int x;
|
||||||
|
const int y;
|
||||||
|
private:
|
||||||
|
type& operator=(const type&);
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
|
||||||
|
{
|
||||||
|
boost::shared_ptr<int[4]> a1 = boost::allocate_shared<int[4]>(std::allocator<int>(), {0, 1, 2, 3});
|
||||||
|
BOOST_TEST(a1[0] == 0);
|
||||||
|
BOOST_TEST(a1[1] == 1);
|
||||||
|
BOOST_TEST(a1[2] == 2);
|
||||||
|
BOOST_TEST(a1[3] == 3);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
boost::shared_ptr<int[2][2]> a1 = boost::allocate_shared<int[2][2]>(std::allocator<int>(), { {0, 1}, {2, 3} });
|
||||||
|
BOOST_TEST(a1[0][0] == 0);
|
||||||
|
BOOST_TEST(a1[0][1] == 1);
|
||||||
|
BOOST_TEST(a1[1][0] == 2);
|
||||||
|
BOOST_TEST(a1[1][1] == 3);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
boost::shared_ptr<int[][2]> a1 = boost::allocate_shared<int[][2]>(std::allocator<int>(), 2, {0, 1});
|
||||||
|
BOOST_TEST(a1[0][0] == 0);
|
||||||
|
BOOST_TEST(a1[0][1] == 1);
|
||||||
|
BOOST_TEST(a1[1][0] == 0);
|
||||||
|
BOOST_TEST(a1[1][1] == 1);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
boost::shared_ptr<int[][2][2]> a1 = boost::allocate_shared<int[][2][2]>(std::allocator<int>(), 2, { {0, 1}, {2, 3} });
|
||||||
|
BOOST_TEST(a1[0][0][0] == 0);
|
||||||
|
BOOST_TEST(a1[0][0][1] == 1);
|
||||||
|
BOOST_TEST(a1[1][1][0] == 2);
|
||||||
|
BOOST_TEST(a1[1][1][1] == 3);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
boost::shared_ptr<int[2][2]> a1 = boost::allocate_shared<int[2][2]>(std::allocator<int>(), {0, 1});
|
||||||
|
BOOST_TEST(a1[0][0] == 0);
|
||||||
|
BOOST_TEST(a1[0][1] == 1);
|
||||||
|
BOOST_TEST(a1[1][0] == 0);
|
||||||
|
BOOST_TEST(a1[1][1] == 1);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
boost::shared_ptr<int[2][2][2]> a1 = boost::allocate_shared<int[2][2][2]>(std::allocator<int>(), { {0, 1}, {2, 3} });
|
||||||
|
BOOST_TEST(a1[0][0][0] == 0);
|
||||||
|
BOOST_TEST(a1[0][0][1] == 1);
|
||||||
|
BOOST_TEST(a1[1][1][0] == 2);
|
||||||
|
BOOST_TEST(a1[1][1][1] == 3);
|
||||||
|
}
|
||||||
|
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||||
|
{
|
||||||
|
boost::shared_ptr<int[]> a1 = boost::allocate_shared<int[]>(std::allocator<int>(), {0, 1, 2, 3});
|
||||||
|
BOOST_TEST(a1[0] == 0);
|
||||||
|
BOOST_TEST(a1[1] == 1);
|
||||||
|
BOOST_TEST(a1[2] == 2);
|
||||||
|
BOOST_TEST(a1[3] == 3);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||||
|
{
|
||||||
|
boost::shared_ptr<type[]> a1 = boost::allocate_shared<type[]>(std::allocator<type>(), 4, {1, 2});
|
||||||
|
BOOST_TEST(a1[0].x == 1);
|
||||||
|
BOOST_TEST(a1[1].y == 2);
|
||||||
|
BOOST_TEST(a1[2].x == 1);
|
||||||
|
BOOST_TEST(a1[3].y == 2);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
boost::shared_ptr<type[4]> a1 = boost::allocate_shared<type[4]>(std::allocator<type>(), {1, 2});
|
||||||
|
BOOST_TEST(a1[0].x == 1);
|
||||||
|
BOOST_TEST(a1[1].y == 2);
|
||||||
|
BOOST_TEST(a1[2].x == 1);
|
||||||
|
BOOST_TEST(a1[3].y == 2);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
23
test/allocate_shared_arrays_init_test.cpp
Normal file
23
test/allocate_shared_arrays_init_test.cpp
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2012 Glen Joseph Fernandes
|
||||||
|
* glenfe at live dot com
|
||||||
|
*
|
||||||
|
* Distributed under the Boost Software License,
|
||||||
|
* Version 1.0. (See accompanying file LICENSE_1_0.txt
|
||||||
|
* or copy at http://boost.org/LICENSE_1_0.txt)
|
||||||
|
*/
|
||||||
|
#include <boost/detail/lightweight_test.hpp>
|
||||||
|
#include <boost/smart_ptr/allocate_shared_array.hpp>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) && !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||||
|
{
|
||||||
|
boost::shared_ptr<int[][2]> a1 = boost::allocate_shared<int[][2]>(std::allocator<int>(), { {0, 1}, {2, 3} });
|
||||||
|
BOOST_TEST(a1[0][0] == 0);
|
||||||
|
BOOST_TEST(a1[0][1] == 1);
|
||||||
|
BOOST_TEST(a1[1][0] == 2);
|
||||||
|
BOOST_TEST(a1[1][1] == 3);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
160
test/allocate_shared_arrays_test.cpp
Normal file
160
test/allocate_shared_arrays_test.cpp
Normal file
@@ -0,0 +1,160 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2012 Glen Joseph Fernandes
|
||||||
|
* glenfe at live dot com
|
||||||
|
*
|
||||||
|
* Distributed under the Boost Software License,
|
||||||
|
* Version 1.0. (See accompanying file LICENSE_1_0.txt
|
||||||
|
* or copy at http://boost.org/LICENSE_1_0.txt)
|
||||||
|
*/
|
||||||
|
#include <boost/detail/lightweight_test.hpp>
|
||||||
|
#include <boost/smart_ptr/allocate_shared_array.hpp>
|
||||||
|
|
||||||
|
class type {
|
||||||
|
public:
|
||||||
|
static unsigned int instances;
|
||||||
|
explicit type(int = 0, int = 0)
|
||||||
|
: member() {
|
||||||
|
instances++;
|
||||||
|
}
|
||||||
|
~type() {
|
||||||
|
instances--;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
type(const type&);
|
||||||
|
type& operator=(const type&);
|
||||||
|
double member;
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned int type::instances = 0;
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
{
|
||||||
|
boost::shared_ptr<int[][2][2]> a1 = boost::allocate_shared<int[][2][2]>(std::allocator<int>(), 2);
|
||||||
|
BOOST_TEST(a1.get() != 0);
|
||||||
|
BOOST_TEST(a1.use_count() == 1);
|
||||||
|
BOOST_TEST(a1[0][0][1] == 0);
|
||||||
|
BOOST_TEST(a1[0][1][0] == 0);
|
||||||
|
BOOST_TEST(a1[1][0][0] == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
boost::shared_ptr<const int[][2][2]> a1 = boost::allocate_shared<const int[][2][2]>(std::allocator<int>(), 2);
|
||||||
|
BOOST_TEST(a1.get() != 0);
|
||||||
|
BOOST_TEST(a1.use_count() == 1);
|
||||||
|
BOOST_TEST(a1[0][0][1] == 0);
|
||||||
|
BOOST_TEST(a1[0][1][0] == 0);
|
||||||
|
BOOST_TEST(a1[1][0][0] == 0);
|
||||||
|
}
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
{
|
||||||
|
boost::shared_ptr<type[][2][2]> a1 = boost::allocate_shared<type[][2][2]>(std::allocator<type>(), 2);
|
||||||
|
BOOST_TEST(a1.get() != 0);
|
||||||
|
BOOST_TEST(a1.use_count() == 1);
|
||||||
|
BOOST_TEST(type::instances == 8);
|
||||||
|
a1.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
{
|
||||||
|
boost::shared_ptr<const type[][2][2]> a1 = boost::allocate_shared<const type[][2][2]>(std::allocator<type>(), 2);
|
||||||
|
BOOST_TEST(a1.get() != 0);
|
||||||
|
BOOST_TEST(a1.use_count() == 1);
|
||||||
|
BOOST_TEST(type::instances == 8);
|
||||||
|
a1.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
{
|
||||||
|
boost::shared_ptr<type[][2][2]> a1 = boost::allocate_shared<type[][2][2]>(std::allocator<type>(), 2, 1, 5);
|
||||||
|
BOOST_TEST(a1.get() != 0);
|
||||||
|
BOOST_TEST(a1.use_count() == 1);
|
||||||
|
BOOST_TEST(type::instances == 8);
|
||||||
|
a1.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
{
|
||||||
|
boost::shared_ptr<type[2][2][2]> a1 = boost::allocate_shared<type[2][2][2]>(std::allocator<type>(), 1, 5);
|
||||||
|
BOOST_TEST(a1.get() != 0);
|
||||||
|
BOOST_TEST(a1.use_count() == 1);
|
||||||
|
BOOST_TEST(type::instances == 8);
|
||||||
|
a1.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
{
|
||||||
|
boost::shared_ptr<const type[][2][2]> a1 = boost::allocate_shared<const type[][2][2]>(std::allocator<type>(), 2, 1, 5);
|
||||||
|
BOOST_TEST(a1.get() != 0);
|
||||||
|
BOOST_TEST(a1.use_count() == 1);
|
||||||
|
BOOST_TEST(type::instances == 8);
|
||||||
|
a1.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
{
|
||||||
|
boost::shared_ptr<const type[2][2][2]> a1 = boost::allocate_shared<const type[2][2][2]>(std::allocator<type>(), 1, 5);
|
||||||
|
BOOST_TEST(a1.get() != 0);
|
||||||
|
BOOST_TEST(a1.use_count() == 1);
|
||||||
|
BOOST_TEST(type::instances == 8);
|
||||||
|
a1.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
boost::shared_ptr<int[][2][2]> a1 = boost::allocate_shared_noinit<int[][2][2]>(std::allocator<int>(), 2);
|
||||||
|
BOOST_TEST(a1.get() != 0);
|
||||||
|
BOOST_TEST(a1.use_count() == 1);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
boost::shared_ptr<int[2][2][2]> a1 = boost::allocate_shared_noinit<int[2][2][2]>(std::allocator<int>());
|
||||||
|
BOOST_TEST(a1.get() != 0);
|
||||||
|
BOOST_TEST(a1.use_count() == 1);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
boost::shared_ptr<const int[][2][2]> a1 = boost::allocate_shared_noinit<const int[][2][2]>(std::allocator<int>(), 2);
|
||||||
|
BOOST_TEST(a1.get() != 0);
|
||||||
|
BOOST_TEST(a1.use_count() == 1);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
boost::shared_ptr<const int[2][2][2]> a1 = boost::allocate_shared_noinit<const int[2][2][2]>(std::allocator<int>());
|
||||||
|
BOOST_TEST(a1.get() != 0);
|
||||||
|
BOOST_TEST(a1.use_count() == 1);
|
||||||
|
}
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
{
|
||||||
|
boost::shared_ptr<type[][2][2]> a1 = boost::allocate_shared_noinit<type[][2][2]>(std::allocator<type>(), 2);
|
||||||
|
BOOST_TEST(a1.get() != 0);
|
||||||
|
BOOST_TEST(a1.use_count() == 1);
|
||||||
|
BOOST_TEST(type::instances == 8);
|
||||||
|
a1.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
{
|
||||||
|
boost::shared_ptr<type[2][2][2]> a1 = boost::allocate_shared_noinit<type[2][2][2]>(std::allocator<type>());
|
||||||
|
BOOST_TEST(a1.get() != 0);
|
||||||
|
BOOST_TEST(a1.use_count() == 1);
|
||||||
|
BOOST_TEST(type::instances == 8);
|
||||||
|
a1.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
{
|
||||||
|
boost::shared_ptr<const type[][2][2]> a1 = boost::allocate_shared_noinit<const type[][2][2]>(std::allocator<type>(), 2);
|
||||||
|
BOOST_TEST(a1.get() != 0);
|
||||||
|
BOOST_TEST(a1.use_count() == 1);
|
||||||
|
BOOST_TEST(type::instances == 8);
|
||||||
|
a1.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
{
|
||||||
|
boost::shared_ptr<const type[2][2][2]> a1 = boost::allocate_shared_noinit<const type[2][2][2]>(std::allocator<type>());
|
||||||
|
BOOST_TEST(a1.get() != 0);
|
||||||
|
BOOST_TEST(a1.use_count() == 1);
|
||||||
|
BOOST_TEST(type::instances == 8);
|
||||||
|
a1.reset();
|
||||||
|
BOOST_TEST(type::instances == 0);
|
||||||
|
}
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
20
test/array_fail_ap_spa_a.cpp
Normal file
20
test/array_fail_ap_spa_a.cpp
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) 2012 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
struct X
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
std::auto_ptr<X> px;
|
||||||
|
boost::shared_ptr<X[]> px2; px2 = px;
|
||||||
|
}
|
20
test/array_fail_ap_spa_c.cpp
Normal file
20
test/array_fail_ap_spa_c.cpp
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) 2012 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
struct X
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
std::auto_ptr<X> px;
|
||||||
|
boost::shared_ptr<X[]> px2( px );
|
||||||
|
}
|
19
test/array_fail_ap_spa_ma.cpp
Normal file
19
test/array_fail_ap_spa_ma.cpp
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) 2012 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
struct X
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
boost::shared_ptr<X[]> px2; px2 = std::auto_ptr<X>();
|
||||||
|
}
|
19
test/array_fail_ap_spa_mc.cpp
Normal file
19
test/array_fail_ap_spa_mc.cpp
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) 2012 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
struct X
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
boost::shared_ptr<X[]> px2(( std::auto_ptr<X>() ));
|
||||||
|
}
|
19
test/array_fail_array_access.cpp
Normal file
19
test/array_fail_array_access.cpp
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) 2012 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
|
struct X
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
boost::shared_ptr<X> px( new X );
|
||||||
|
px[ 0 ];
|
||||||
|
}
|
19
test/array_fail_dereference.cpp
Normal file
19
test/array_fail_dereference.cpp
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) 2012 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
|
struct X
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
boost::shared_ptr<X[]> px( new X[ 1 ] );
|
||||||
|
*px;
|
||||||
|
}
|
20
test/array_fail_member_access.cpp
Normal file
20
test/array_fail_member_access.cpp
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) 2012 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
|
struct X
|
||||||
|
{
|
||||||
|
int m;
|
||||||
|
};
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
boost::shared_ptr<X[]> px( new X[ 1 ] );
|
||||||
|
px->m = 0;
|
||||||
|
}
|
19
test/array_fail_sp_spa_a.cpp
Normal file
19
test/array_fail_sp_spa_a.cpp
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) 2012 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
|
struct X
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
boost::shared_ptr<X> px;
|
||||||
|
boost::shared_ptr<X[]> px2; px2 = px;
|
||||||
|
}
|
19
test/array_fail_sp_spa_c.cpp
Normal file
19
test/array_fail_sp_spa_c.cpp
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) 2012 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
|
struct X
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
boost::shared_ptr<X> px;
|
||||||
|
boost::shared_ptr<X[]> px2( px );
|
||||||
|
}
|
18
test/array_fail_sp_spa_ma.cpp
Normal file
18
test/array_fail_sp_spa_ma.cpp
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) 2012 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
|
struct X
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
boost::shared_ptr<X[]> px2; px2 = boost::shared_ptr<X>();
|
||||||
|
}
|
18
test/array_fail_sp_spa_mc.cpp
Normal file
18
test/array_fail_sp_spa_mc.cpp
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) 2012 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
|
struct X
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
boost::shared_ptr<X[]> px2(( boost::shared_ptr<X>() ));
|
||||||
|
}
|
20
test/array_fail_sp_wpa_a.cpp
Normal file
20
test/array_fail_sp_wpa_a.cpp
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) 2012 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
#include <boost/weak_ptr.hpp>
|
||||||
|
|
||||||
|
struct X
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
boost::shared_ptr<X> px;
|
||||||
|
boost::weak_ptr<X[]> px2; px2 = px;
|
||||||
|
}
|
20
test/array_fail_sp_wpa_c.cpp
Normal file
20
test/array_fail_sp_wpa_c.cpp
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) 2012 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
#include <boost/weak_ptr.hpp>
|
||||||
|
|
||||||
|
struct X
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
boost::shared_ptr<X> px;
|
||||||
|
boost::weak_ptr<X[]> px2( px );
|
||||||
|
}
|
19
test/array_fail_sp_wpa_ma.cpp
Normal file
19
test/array_fail_sp_wpa_ma.cpp
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) 2012 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
#include <boost/weak_ptr.hpp>
|
||||||
|
|
||||||
|
struct X
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
boost::weak_ptr<X[]> px2; px2 = boost::shared_ptr<X>();
|
||||||
|
}
|
19
test/array_fail_sp_wpa_mc.cpp
Normal file
19
test/array_fail_sp_wpa_mc.cpp
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) 2012 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
#include <boost/weak_ptr.hpp>
|
||||||
|
|
||||||
|
struct X
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
boost::weak_ptr<X[]> px2(( boost::shared_ptr<X>() ));
|
||||||
|
}
|
19
test/array_fail_spa_sp_a.cpp
Normal file
19
test/array_fail_spa_sp_a.cpp
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) 2012 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
|
struct X
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
boost::shared_ptr<X[]> px;
|
||||||
|
boost::shared_ptr<X> px2; px2 = px;
|
||||||
|
}
|
19
test/array_fail_spa_sp_c.cpp
Normal file
19
test/array_fail_spa_sp_c.cpp
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) 2012 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
|
struct X
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
boost::shared_ptr<X[]> px;
|
||||||
|
boost::shared_ptr<X> px2( px );
|
||||||
|
}
|
18
test/array_fail_spa_sp_ma.cpp
Normal file
18
test/array_fail_spa_sp_ma.cpp
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) 2012 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
|
struct X
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
boost::shared_ptr<X> px2; px2 = boost::shared_ptr<X[]>();
|
||||||
|
}
|
18
test/array_fail_spa_sp_mc.cpp
Normal file
18
test/array_fail_spa_sp_mc.cpp
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) 2012 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
|
struct X
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
boost::shared_ptr<X> px2(( boost::shared_ptr<X[]>() ));
|
||||||
|
}
|
23
test/array_fail_spa_spa_a.cpp
Normal file
23
test/array_fail_spa_spa_a.cpp
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) 2012 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
|
struct X
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Y: public X
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
boost::shared_ptr<Y[]> px;
|
||||||
|
boost::shared_ptr<X[]> px2; px2 = px;
|
||||||
|
}
|
23
test/array_fail_spa_spa_c.cpp
Normal file
23
test/array_fail_spa_spa_c.cpp
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) 2012 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
|
struct X
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Y: public X
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
boost::shared_ptr<Y[]> px;
|
||||||
|
boost::shared_ptr<X[]> px2( px );
|
||||||
|
}
|
22
test/array_fail_spa_spa_ma.cpp
Normal file
22
test/array_fail_spa_spa_ma.cpp
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) 2012 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
|
struct X
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Y: public X
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
boost::shared_ptr<X[]> px2; px2 = boost::shared_ptr<Y[]>();
|
||||||
|
}
|
22
test/array_fail_spa_spa_mc.cpp
Normal file
22
test/array_fail_spa_spa_mc.cpp
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) 2012 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
|
struct X
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Y: public X
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
boost::shared_ptr<X[]> px2(( boost::shared_ptr<Y[]>() ));
|
||||||
|
}
|
20
test/array_fail_spa_wp_a.cpp
Normal file
20
test/array_fail_spa_wp_a.cpp
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) 2012 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
#include <boost/weak_ptr.hpp>
|
||||||
|
|
||||||
|
struct X
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
boost::shared_ptr<X[]> px;
|
||||||
|
boost::weak_ptr<X> px2; px2 = px;
|
||||||
|
}
|
20
test/array_fail_spa_wp_c.cpp
Normal file
20
test/array_fail_spa_wp_c.cpp
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) 2012 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
#include <boost/weak_ptr.hpp>
|
||||||
|
|
||||||
|
struct X
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
boost::shared_ptr<X[]> px;
|
||||||
|
boost::weak_ptr<X> px2( px );
|
||||||
|
}
|
19
test/array_fail_spa_wp_ma.cpp
Normal file
19
test/array_fail_spa_wp_ma.cpp
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) 2012 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
#include <boost/weak_ptr.hpp>
|
||||||
|
|
||||||
|
struct X
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
boost::weak_ptr<X> px2; px2 = boost::shared_ptr<X[]>();
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user