mirror of
https://github.com/boostorg/smart_ptr.git
synced 2025-08-02 14:14:27 +02:00
Add overloads of make_shared and allocate_shared for arrays for E&& where E is typename boost::detail::array_base<T>::type
[SVN r81700]
This commit is contained in:
@@ -169,6 +169,46 @@ namespace boost {
|
|||||||
d2->construct_list(p2, p3, M);
|
d2->construct_list(p2, p3, M);
|
||||||
return boost::shared_ptr<T>(s1, p1);
|
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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -38,7 +38,20 @@ namespace boost {
|
|||||||
throw;
|
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>
|
template<typename... Args>
|
||||||
void construct(T* memory, Args&&... args) {
|
void construct(T* memory, Args&&... args) {
|
||||||
std::size_t i = 0;
|
std::size_t i = 0;
|
||||||
@@ -52,6 +65,7 @@ namespace boost {
|
|||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
void construct_list(T* memory, const T* list) {
|
void construct_list(T* memory, const T* list) {
|
||||||
std::size_t i = 0;
|
std::size_t i = 0;
|
||||||
@@ -125,7 +139,20 @@ namespace boost {
|
|||||||
throw;
|
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>
|
template<typename... Args>
|
||||||
void construct(T* memory, Args&&... args) {
|
void construct(T* memory, Args&&... args) {
|
||||||
std::size_t i = 0;
|
std::size_t i = 0;
|
||||||
@@ -139,6 +166,7 @@ namespace boost {
|
|||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
void construct_list(T* memory, const T* list) {
|
void construct_list(T* memory, const T* list) {
|
||||||
std::size_t i = 0;
|
std::size_t i = 0;
|
||||||
|
@@ -17,6 +17,10 @@ namespace boost {
|
|||||||
struct array_base {
|
struct array_base {
|
||||||
typedef typename boost::remove_cv<T>::type type;
|
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>
|
template<typename T, std::size_t N>
|
||||||
struct array_base<T[N]> {
|
struct array_base<T[N]> {
|
||||||
typedef typename array_base<T>::type type;
|
typedef typename array_base<T>::type type;
|
||||||
|
@@ -14,15 +14,13 @@
|
|||||||
namespace boost {
|
namespace boost {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct sp_if_array {
|
struct sp_if_array;
|
||||||
};
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct sp_if_array<T[]> {
|
struct sp_if_array<T[]> {
|
||||||
typedef boost::shared_ptr<T[]> type;
|
typedef boost::shared_ptr<T[]> type;
|
||||||
};
|
};
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct sp_if_size_array {
|
struct sp_if_size_array;
|
||||||
};
|
|
||||||
template<typename T, std::size_t N>
|
template<typename T, std::size_t N>
|
||||||
struct sp_if_size_array<T[N]> {
|
struct sp_if_size_array<T[N]> {
|
||||||
typedef boost::shared_ptr<T[N]> type;
|
typedef boost::shared_ptr<T[N]> type;
|
||||||
|
@@ -167,6 +167,45 @@ namespace boost {
|
|||||||
d2->construct_list(p2, p3, M);
|
d2->construct_list(p2, p3, M);
|
||||||
return boost::shared_ptr<T>(s1, p1);
|
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
|
#endif
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline typename boost::detail::sp_if_array<T>::type
|
inline typename boost::detail::sp_if_array<T>::type
|
||||||
|
@@ -75,6 +75,20 @@
|
|||||||
|
|
||||||
template<typename T, typename A, typename... Args>
|
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]);
|
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
|
#endif
|
||||||
|
|
||||||
template<typename T>
|
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]);
|
shared_ptr<T[M][N]> make_shared(const T (&list)[N]);
|
||||||
template<typename T, typename A, typename... Args>
|
template<typename T, typename A, typename... Args>
|
||||||
shared_ptr<T[M][N]> allocate_shared(const A& allocator, const T (&list)[N]);</pre>
|
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>
|
<blockquote>
|
||||||
<p><b>Description:</b> These overloads of the utilities above are for a
|
<p><b>Description:</b> These overloads of the utilities above are for a
|
||||||
fixed size array.</p>
|
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]> 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[][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[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<point[]> a8 = boost::make_shared<point[]>(4, {x, y});
|
||||||
boost::shared_ptr<int[5]> a9 = boost::make_shared_noinit<int[5]>();</pre>
|
boost::shared_ptr<point[4]> a9 = boost::make_shared<point[4]>({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>
|
</blockquote>
|
||||||
<h2><a name="history">History</a></h2>
|
<h2><a name="history">History</a></h2>
|
||||||
<p>November 2012. Glen Fernandes contributed implementations of
|
<p>November 2012. Glen Fernandes contributed implementations of
|
||||||
|
@@ -9,6 +9,17 @@
|
|||||||
#include <boost/detail/lightweight_test.hpp>
|
#include <boost/detail/lightweight_test.hpp>
|
||||||
#include <boost/smart_ptr/allocate_shared_array.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() {
|
int main() {
|
||||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
#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][0] == 2);
|
||||||
BOOST_TEST(a1[1][1][1] == 3);
|
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
|
#endif
|
||||||
return boost::report_errors();
|
return boost::report_errors();
|
||||||
}
|
}
|
||||||
|
@@ -9,6 +9,17 @@
|
|||||||
#include <boost/detail/lightweight_test.hpp>
|
#include <boost/detail/lightweight_test.hpp>
|
||||||
#include <boost/smart_ptr/make_shared_array.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() {
|
int main() {
|
||||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
#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][0] == 2);
|
||||||
BOOST_TEST(a1[1][1][1] == 3);
|
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
|
#endif
|
||||||
return boost::report_errors();
|
return boost::report_errors();
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user