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:
Glen Fernandes
2012-12-05 04:28:20 +00:00
parent 3551d17566
commit 08e5894510
8 changed files with 203 additions and 16 deletions

View File

@ -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
}

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -75,6 +75,20 @@
template&lt;typename T, typename A, typename... Args&gt;
shared_ptr&lt;T[M][N]&gt; <a href="#functions">allocate_shared</a>(const A&amp; allocator, const T (&amp;list)[N]);
#if defined(BOOST_HAS_RVALUE_REFS)
template&lt;typename T&gt;
shared_ptr&lt;T[]&gt; <a href="#functions">make_shared</a>(size_t size, T&amp;&amp; value);
template&lt;typename T&gt;
shared_ptr&lt;T[N]&gt; <a href="#functions">make_shared</a>(T&amp;&amp; value);
template&lt;typename T, typename A&gt;
shared_ptr&lt;T[]&gt; <a href="#functions">allocate_shared</a>(const A&amp; allocator, size_t size, T&amp;&amp; value);
template&lt;typename T, typename A&gt;
shared_ptr&lt;T[N]&gt; <a href="#functions">allocate_shared</a>(const A&amp; allocator, T&amp;&amp; value);
#endif
#endif
template&lt;typename T&gt;
@ -162,6 +176,22 @@ template&lt;typename T, typename A, typename... Args&gt;
shared_ptr&lt;T[M][N]&gt; make_shared(const T (&amp;list)[N]);
template&lt;typename T, typename A, typename... Args&gt;
shared_ptr&lt;T[M][N]&gt; allocate_shared(const A&amp; allocator, const T (&amp;list)[N]);</pre>
<blockquote>
<p><b>Description:</b> These overloads of the utilities above are for a
fixed size array.</p>
</blockquote>
<pre>template&lt;typename T&gt;
shared_ptr&lt;T[]&gt; make_shared(size_t size, T&amp;&amp; value);
template&lt;typename T, typename A&gt;
shared_ptr&lt;T[]&gt; allocate_shared(const A&amp; allocator, size_t size, T&amp;&amp; value);</pre>
<blockquote>
<p><b>Description:</b> These overloads initialize array elements with
the given value.</p>
</blockquote>
<pre>template&lt;typename T&gt;
shared_ptr&lt;T[N]&gt; make_shared(T&amp;&amp; value);
template&lt;typename T, typename A&gt;
shared_ptr&lt;T[N]&gt; allocate_shared(const A&amp; allocator, T&amp;&amp; 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&lt;int[]&gt; a4 = boost::make_shared&lt;int[]&gt;({1, 2, 3});
boost::shared_ptr&lt;int[3]&gt; a5 = boost::make_shared&lt;int[3]&gt;({1, 2, 3});
boost::shared_ptr&lt;int[][3]&gt; a6 = boost::make_shared&lt;int[][3]&gt;(size, {1, 2, 3});
boost::shared_ptr&lt;int[5][3]&gt; a7 = boost::make_shared&lt;int[5][3]&gt;({1, 2, 3});
boost::shared_ptr&lt;int[]&gt; a8 = boost::make_shared_noinit&lt;int[]&gt;(size);
boost::shared_ptr&lt;int[5]&gt; a9 = boost::make_shared_noinit&lt;int[5]&gt;();</pre>
boost::shared_ptr&lt;point[]&gt; a8 = boost::make_shared&lt;point[]&gt;(size, {x, y});
boost::shared_ptr&lt;point[5]&gt; a9 = boost::make_shared&lt;point[5]&gt;({x, y});
boost::shared_ptr&lt;int[]&gt; a10 = boost::make_shared_noinit&lt;int[]&gt;(size);
boost::shared_ptr&lt;int[5]&gt; a11 = boost::make_shared_noinit&lt;int[5]&gt;();</pre>
</blockquote>
<h2><a name="history">History</a></h2>
<p>November 2012. Glen Fernandes contributed implementations of

View File

@ -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();
}

View File

@ -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();
}