mirror of
https://github.com/boostorg/smart_ptr.git
synced 2025-07-30 20:57:21 +02:00
Merged revisions 81700,81703 from trunk:
Add overloads of make_shared and allocate_shared for arrays for E&& where E is typename boost::detail::array_base<T>::type ........ Update documentation and remove unused code. ........ [SVN r81716]
This commit is contained in:
@ -169,6 +169,46 @@ namespace boost {
|
||||
d2->construct_list(p2, p3, M);
|
||||
return boost::shared_ptr<T>(s1, p1);
|
||||
}
|
||||
#if defined(BOOST_HAS_RVALUE_REFS)
|
||||
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);
|
||||
boost::detail::array_deleter<T2[]>* d2;
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
d2 = get_deleter<boost::detail::array_deleter<T2[]> >(s1);
|
||||
d2->construct(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);
|
||||
boost::detail::array_deleter<T2[N]>* d2;
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
d2 = get_deleter<boost::detail::array_deleter<T2[N]> >(s1);
|
||||
d2->construct(p2, boost::detail::sp_forward<T2>(value));
|
||||
return boost::shared_ptr<T>(s1, p1);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,20 @@ namespace boost {
|
||||
throw;
|
||||
}
|
||||
}
|
||||
#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS)
|
||||
#if defined(BOOST_HAS_RVALUE_REFS)
|
||||
void construct(T* memory, T&& value) {
|
||||
std::size_t i = 0;
|
||||
try {
|
||||
for (object = memory; i < size; i++) {
|
||||
void* p1 = memory + i;
|
||||
::new(p1) T(value);
|
||||
}
|
||||
} catch (...) {
|
||||
destroy(i);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
#if defined(BOOST_HAS_VARIADIC_TMPL)
|
||||
template<typename... Args>
|
||||
void construct(T* memory, Args&&... args) {
|
||||
std::size_t i = 0;
|
||||
@ -52,6 +65,7 @@ namespace boost {
|
||||
throw;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
void construct_list(T* memory, const T* list) {
|
||||
std::size_t i = 0;
|
||||
@ -125,7 +139,20 @@ namespace boost {
|
||||
throw;
|
||||
}
|
||||
}
|
||||
#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS)
|
||||
#if defined(BOOST_HAS_RVALUE_REFS)
|
||||
void construct(T* memory, T&& value) {
|
||||
std::size_t i = 0;
|
||||
try {
|
||||
for (object = memory; i < N; i++) {
|
||||
void* p1 = memory + i;
|
||||
::new(p1) T(value);
|
||||
}
|
||||
} catch (...) {
|
||||
destroy(i);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
#if defined(BOOST_HAS_VARIADIC_TMPL)
|
||||
template<typename... Args>
|
||||
void construct(T* memory, Args&&... args) {
|
||||
std::size_t i = 0;
|
||||
@ -139,6 +166,7 @@ namespace boost {
|
||||
throw;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
void construct_list(T* memory, const T* list) {
|
||||
std::size_t i = 0;
|
||||
|
@ -17,19 +17,15 @@ namespace boost {
|
||||
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_size;
|
||||
template<typename T, std::size_t N>
|
||||
struct array_size<T[N]> {
|
||||
enum {
|
||||
size = N
|
||||
};
|
||||
};
|
||||
template<typename T>
|
||||
struct array_total {
|
||||
enum {
|
||||
size = 1
|
||||
|
@ -14,15 +14,13 @@
|
||||
namespace boost {
|
||||
namespace detail {
|
||||
template<typename T>
|
||||
struct sp_if_array {
|
||||
};
|
||||
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 {
|
||||
};
|
||||
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;
|
||||
|
@ -167,6 +167,45 @@ namespace boost {
|
||||
d2->construct_list(p2, p3, M);
|
||||
return boost::shared_ptr<T>(s1, p1);
|
||||
}
|
||||
#if defined(BOOST_HAS_RVALUE_REFS)
|
||||
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);
|
||||
boost::detail::array_deleter<T2[]>* d2;
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
d2 = get_deleter<boost::detail::array_deleter<T2[]> >(s1);
|
||||
d2->construct(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);
|
||||
boost::detail::array_deleter<T2[N]>* d2;
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
d2 = get_deleter<boost::detail::array_deleter<T2[N]> >(s1);
|
||||
d2->construct(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
|
||||
|
@ -75,6 +75,20 @@
|
||||
|
||||
template<typename T, typename A, typename... Args>
|
||||
shared_ptr<T[M][N]> <a href="#functions">allocate_shared</a>(const A& allocator, const T (&list)[N]);
|
||||
|
||||
#if defined(BOOST_HAS_RVALUE_REFS)
|
||||
template<typename T>
|
||||
shared_ptr<T[]> <a href="#functions">make_shared</a>(size_t size, T&& value);
|
||||
|
||||
template<typename T>
|
||||
shared_ptr<T[N]> <a href="#functions">make_shared</a>(T&& value);
|
||||
|
||||
template<typename T, typename A>
|
||||
shared_ptr<T[]> <a href="#functions">allocate_shared</a>(const A& allocator, size_t size, T&& value);
|
||||
|
||||
template<typename T, typename A>
|
||||
shared_ptr<T[N]> <a href="#functions">allocate_shared</a>(const A& allocator, T&& value);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
@ -162,6 +176,22 @@ template<typename T, typename A, typename... Args>
|
||||
shared_ptr<T[M][N]> make_shared(const T (&list)[N]);
|
||||
template<typename T, typename A, typename... Args>
|
||||
shared_ptr<T[M][N]> 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 T>
|
||||
shared_ptr<T[]> make_shared(size_t size, T&& value);
|
||||
template<typename T, typename A>
|
||||
shared_ptr<T[]> 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 T>
|
||||
shared_ptr<T[N]> make_shared(T&& value);
|
||||
template<typename T, typename A>
|
||||
shared_ptr<T[N]> 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>
|
||||
@ -188,8 +218,10 @@ 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<int[]> a8 = boost::make_shared_noinit<int[]>(size);
|
||||
boost::shared_ptr<int[5]> a9 = boost::make_shared_noinit<int[5]>();</pre>
|
||||
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
|
||||
|
@ -9,6 +9,17 @@
|
||||
#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_HDR_INITIALIZER_LIST)
|
||||
{
|
||||
@ -69,6 +80,22 @@ int main() {
|
||||
BOOST_TEST(a1[1][1][0] == 2);
|
||||
BOOST_TEST(a1[1][1][1] == 3);
|
||||
}
|
||||
#if defined(BOOST_HAS_RVALUE_REFS)
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
@ -9,6 +9,17 @@
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/smart_ptr/make_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_HDR_INITIALIZER_LIST)
|
||||
{
|
||||
@ -69,6 +80,22 @@ int main() {
|
||||
BOOST_TEST(a1[1][1][0] == 2);
|
||||
BOOST_TEST(a1[1][1][1] == 3);
|
||||
}
|
||||
#if defined(BOOST_HAS_RVALUE_REFS)
|
||||
{
|
||||
boost::shared_ptr<type[]> a1 = boost::make_shared<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::make_shared<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);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
Reference in New Issue
Block a user