Merge branch 'develop'

This commit is contained in:
Peter Dimov
2014-02-11 01:29:29 +02:00
89 changed files with 6786 additions and 5192 deletions

View File

@@ -1,12 +1,12 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html> <html>
<head> <head>
<title>Smart Pointer Changes</title> <title>Smart Pointer Changes</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head> </head>
<body bgcolor="#ffffff" text="#000000"> <body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
<h1><A href="../../index.htm"><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="277" height="86" <h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
border="0"></A>Smart Pointer Changes</h1> width="277" align="middle" border="0">Smart Pointer Changes</h1>
<p>The February 2002 change to the Boost smart pointers introduced a number of <p>The February 2002 change to the Boost smart pointers introduced a number of
changes. Since the previous version of the smart pointers was in use for a long changes. Since the previous version of the smart pointers was in use for a long
time, it's useful to have a detailed list of what changed from a library user's time, it's useful to have a detailed list of what changed from a library user's
@@ -80,7 +80,7 @@
violate the C++ standard.</li> violate the C++ standard.</li>
</ul> </ul>
<hr> <hr>
<p>Revised 1 February 2002</p> <p>$Date$</p>
<p><small>Copyright 2002 Darin Adler. Distributed under the Boost Software License, Version <p><small>Copyright 2002 Darin Adler. Distributed under the Boost Software License, Version
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or 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> copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>

View File

@@ -1,23 +1,13 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html> <html>
<head> <head>
<title>Boost: enable_shared_from_this.hpp documentation</title> <title>enable_shared_from_this</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head> </head>
<body bgcolor="white" style="MARGIN-LEFT: 5%; MARGIN-RIGHT: 5%"> <body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
<table border="0" width="100%"> <h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
<tr> width="277" align="middle" border="0">enable_shared_from_this</h1>
<td width="277"><A href="../../index.htm"> <img src="../../boost.png" alt="boost.png (6897 bytes)" width="277" height="86" border="0"></A> <h2><a name="Purpose">Purpose</a></h2>
</td>
<td align="center">
<h1>enable_shared_from_this.hpp</h1>
</td>
</tr>
<tr>
<td colspan="2" height="64">&nbsp;</td>
</tr>
</table>
<h3><a name="Purpose">Purpose</a></h3>
<p> <p>
The header <STRONG>&lt;boost/enable_shared_from_this.hpp&gt;</STRONG> defines The header <STRONG>&lt;boost/enable_shared_from_this.hpp&gt;</STRONG> defines
the class template <STRONG>enable_shared_from_this</STRONG>. It is used as a the class template <STRONG>enable_shared_from_this</STRONG>. It is used as a
@@ -27,7 +17,7 @@
<P><STRONG>enable_shared_from_this&lt;T&gt;</STRONG> defines two member functions <P><STRONG>enable_shared_from_this&lt;T&gt;</STRONG> defines two member functions
called <STRONG>shared_from_this</STRONG> that return a <STRONG>shared_ptr&lt;T&gt;</STRONG> called <STRONG>shared_from_this</STRONG> that return a <STRONG>shared_ptr&lt;T&gt;</STRONG>
and <STRONG>shared_ptr&lt;T const&gt;</STRONG>, depending on constness, to <STRONG>this</STRONG>.</P> and <STRONG>shared_ptr&lt;T const&gt;</STRONG>, depending on constness, to <STRONG>this</STRONG>.</P>
<h3><a name="Example">Example</a></h3> <h2><a name="Example">Example</a></h2>
<pre> <pre>
#include &lt;boost/enable_shared_from_this.hpp&gt; #include &lt;boost/enable_shared_from_this.hpp&gt;
#include &lt;boost/shared_ptr.hpp&gt; #include &lt;boost/shared_ptr.hpp&gt;
@@ -86,9 +76,9 @@ public:
<b>Postconditions:</b> <tt>r.get() == this</tt>. <b>Postconditions:</b> <tt>r.get() == this</tt>.
</p> </p>
</blockquote> </blockquote>
<p>$Date$</p>
<p> <p>
<br> <small>Copyright &copy; 2002, 2003 by Peter Dimov. Distributed under the Boost Software License, Version
<small>Copyright <20> 2002, 2003 by Peter Dimov. Distributed under the Boost Software License, Version
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or 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> copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
</body> </body>

View File

@@ -0,0 +1,14 @@
/*
* Copyright (c) 2014 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_MAKE_UNIQUE_HPP_INCLUDED
#define BOOST_MAKE_UNIQUE_HPP_INCLUDED
#include <boost/smart_ptr/make_unique.hpp>
#endif

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012 Glen Joseph Fernandes * Copyright (c) 2012-2014 Glen Joseph Fernandes
* glenfe at live dot com * glenfe at live dot com
* *
* Distributed under the Boost Software License, * Distributed under the Boost Software License,
@@ -9,14 +9,10 @@
#ifndef BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP #ifndef BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP
#define 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/array_allocator.hpp>
#include <boost/smart_ptr/detail/allocate_array_helper.hpp>
#include <boost/smart_ptr/detail/array_deleter.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> #include <boost/smart_ptr/detail/sp_if_array.hpp>
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) #include <boost/type_traits/remove_cv.hpp>
#include <initializer_list>
#endif
namespace boost { namespace boost {
template<typename T, typename A> template<typename T, typename A>
@@ -24,225 +20,140 @@ namespace boost {
allocate_shared(const A& allocator, std::size_t size) { allocate_shared(const A& allocator, std::size_t size) {
typedef typename boost::detail::array_inner<T>::type T1; typedef typename boost::detail::array_inner<T>::type T1;
typedef typename boost::detail::array_base<T1>::type T2; typedef typename boost::detail::array_base<T1>::type T2;
typedef typename boost::remove_cv<T2>::type T3;
typedef boost::detail::as_allocator<T3[], A> A1;
typedef boost::detail::as_deleter<T3[], A> D1;
T1* p1 = 0; T1* p1 = 0;
T2* p2 = 0; T3* p2 = 0;
std::size_t n1 = size * boost::detail::array_total<T1>::size; std::size_t n1 = size * boost::detail::array_total<T1>::size;
boost::detail::allocate_array_helper<A, T2[]> a1(allocator, n1, &p2); D1 d1(allocator, n1);
boost::detail::array_deleter<T2[]> d1(n1); A1 a1(allocator, n1, &p2);
boost::shared_ptr<T> s1(p1, d1, a1); boost::shared_ptr<T> s1(p1, d1, a1);
typedef boost::detail::array_deleter<T2[]>* D2;
p1 = reinterpret_cast<T1*>(p2); p1 = reinterpret_cast<T1*>(p2);
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter()); boost::detail::as_init(allocator, p2, n1);
d2->init(p2); D1* d2 = static_cast<D1*>(s1._internal_get_untyped_deleter());
d2->set(p2);
return boost::shared_ptr<T>(s1, p1); 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> template<typename T, typename A>
inline typename boost::detail::sp_if_size_array<T>::type inline typename boost::detail::sp_if_size_array<T>::type
allocate_shared(const A& allocator, const T& list) { allocate_shared(const A& allocator) {
typedef typename boost::detail::array_inner<T>::type T1; typedef typename boost::detail::array_inner<T>::type T1;
typedef typename boost::detail::array_base<T1>::type T2; typedef typename boost::detail::array_base<T1>::type T2;
typedef const T2 T3; typedef typename boost::remove_cv<T2>::type T3;
enum { enum {
N = boost::detail::array_total<T>::size N = boost::detail::array_total<T>::size
}; };
typedef boost::detail::as_allocator<T3[N], A> A1;
typedef boost::detail::as_deleter<T3[N], A> D1;
T1* p1 = 0; T1* p1 = 0;
T2* p2 = 0; T3* p2 = 0;
T3* p3 = 0; D1 d1(allocator);
boost::detail::allocate_array_helper<A, T2[N]> a1(allocator, &p2); A1 a1(allocator, &p2);
boost::detail::array_deleter<T2[N]> d1;
boost::shared_ptr<T> s1(p1, d1, a1); 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); p1 = reinterpret_cast<T1*>(p2);
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter()); boost::detail::as_init(allocator, p2, N);
d2->init_list(p2, p3); D1* d2 = static_cast<D1*>(s1._internal_get_untyped_deleter());
d2->set(p2);
return boost::shared_ptr<T>(s1, p1); return boost::shared_ptr<T>(s1, p1);
} }
template<typename T, typename A> template<typename T, typename A>
inline typename boost::detail::sp_if_array<T>::type inline typename boost::detail::sp_if_array<T>::type
allocate_shared(const A& allocator, std::size_t size, allocate_shared(const A& allocator, std::size_t size,
const typename boost::detail::array_inner<T>::type& list) { const typename boost::detail::array_inner<T>::type& value) {
typedef typename boost::detail::array_inner<T>::type T1; typedef typename boost::detail::array_inner<T>::type T1;
typedef typename boost::detail::array_base<T1>::type T2; typedef typename boost::detail::array_base<T1>::type T2;
typedef const T2 T3; typedef typename boost::remove_cv<T2>::type T3;
typedef const T2 T4;
typedef boost::detail::as_allocator<T3[], A> A1;
typedef boost::detail::as_deleter<T3[], A> D1;
enum { enum {
M = boost::detail::array_total<T1>::size M = boost::detail::array_total<T1>::size
}; };
T1* p1 = 0; T1* p1 = 0;
T2* p2 = 0; T3* p2 = 0;
T3* p3 = 0; T4* p3 = reinterpret_cast<T4*>(&value);
std::size_t n1 = M * size; std::size_t n1 = M * size;
boost::detail::allocate_array_helper<A, T2[]> a1(allocator, n1, &p2); D1 d1(allocator, n1);
boost::detail::array_deleter<T2[]> d1(n1); A1 a1(allocator, n1, &p2);
boost::shared_ptr<T> s1(p1, d1, a1); 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); p1 = reinterpret_cast<T1*>(p2);
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter()); boost::detail::as_init<T3, A, M>(allocator, p2, n1, p3);
d2->template init_list<M>(p2, p3); D1* d2 = static_cast<D1*>(s1._internal_get_untyped_deleter());
d2->set(p2);
return boost::shared_ptr<T>(s1, p1); return boost::shared_ptr<T>(s1, p1);
} }
template<typename T, typename A> template<typename T, typename A>
inline typename boost::detail::sp_if_size_array<T>::type inline typename boost::detail::sp_if_size_array<T>::type
allocate_shared(const A& allocator, allocate_shared(const A& allocator,
const typename boost::detail::array_inner<T>::type& list) { const typename boost::detail::array_inner<T>::type& value) {
typedef typename boost::detail::array_inner<T>::type T1; typedef typename boost::detail::array_inner<T>::type T1;
typedef typename boost::detail::array_base<T1>::type T2; typedef typename boost::detail::array_base<T1>::type T2;
typedef const T2 T3; typedef typename boost::remove_cv<T2>::type T3;
typedef const T2 T4;
enum { enum {
M = boost::detail::array_total<T1>::size, M = boost::detail::array_total<T1>::size,
N = boost::detail::array_total<T>::size N = boost::detail::array_total<T>::size
}; };
typedef boost::detail::as_allocator<T3[N], A> A1;
typedef boost::detail::as_deleter<T3[N], A> D1;
T1* p1 = 0; T1* p1 = 0;
T2* p2 = 0; T3* p2 = 0;
T3* p3 = 0; T4* p3 = reinterpret_cast<T4*>(&value);
boost::detail::allocate_array_helper<A, T2[N]> a1(allocator, &p2); D1 d1(allocator);
boost::detail::array_deleter<T2[N]> d1; A1 a1(allocator, &p2);
boost::shared_ptr<T> s1(p1, d1, a1); 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); p1 = reinterpret_cast<T1*>(p2);
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter()); boost::detail::as_init<T3, A, M>(allocator, p2, N, p3);
d2->template init_list<M>(p2, p3); D1* d2 = static_cast<D1*>(s1._internal_get_untyped_deleter());
d2->set(p2);
return boost::shared_ptr<T>(s1, p1); 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> template<typename T, typename A>
inline typename boost::detail::sp_if_array<T>::type inline typename boost::detail::sp_if_array<T>::type
allocate_shared_noinit(const A& allocator, std::size_t size) { allocate_shared_noinit(const A& allocator, std::size_t size) {
typedef typename boost::detail::array_inner<T>::type T1; typedef typename boost::detail::array_inner<T>::type T1;
typedef typename boost::detail::array_base<T1>::type T2; typedef typename boost::detail::array_base<T1>::type T2;
typedef typename boost::remove_cv<T2>::type T3;
typedef boost::detail::as_allocator<T3[], A> A1;
typedef boost::detail::ms_deleter<T3[]> D1;
T1* p1 = 0; T1* p1 = 0;
T2* p2 = 0; T3* p2 = 0;
std::size_t n1 = size * boost::detail::array_total<T1>::size; std::size_t n1 = size * boost::detail::array_total<T1>::size;
boost::detail::allocate_array_helper<A, T2[]> a1(allocator, n1, &p2); D1 d1(n1);
boost::detail::array_deleter<T2[]> d1(n1); A1 a1(allocator, n1, &p2);
boost::shared_ptr<T> s1(p1, d1, a1); boost::shared_ptr<T> s1(p1, d1, a1);
typedef boost::detail::array_deleter<T2[]>* D2;
p1 = reinterpret_cast<T1*>(p2); p1 = reinterpret_cast<T1*>(p2);
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter()); boost::detail::ms_noinit(p2, n1);
d2->noinit(p2); D1* d2 = static_cast<D1*>(s1._internal_get_untyped_deleter());
d2->set(p2);
return boost::shared_ptr<T>(s1, p1); return boost::shared_ptr<T>(s1, p1);
} }
template<typename T, typename A> template<typename T, typename A>
inline typename boost::detail::sp_if_size_array<T>::type inline typename boost::detail::sp_if_size_array<T>::type
allocate_shared_noinit(const A& allocator) { allocate_shared_noinit(const A& allocator) {
typedef typename boost::detail::array_inner<T>::type T1; typedef typename boost::detail::array_inner<T>::type T1;
typedef typename boost::detail::array_base<T1>::type T2; typedef typename boost::detail::array_base<T1>::type T2;
typedef typename boost::remove_cv<T2>::type T3;
enum { enum {
N = boost::detail::array_total<T>::size N = boost::detail::array_total<T>::size
}; };
typedef boost::detail::as_allocator<T3[N], A> A1;
typedef boost::detail::ms_deleter<T3[N]> D1;
T1* p1 = 0; T1* p1 = 0;
T2* p2 = 0; T3* p2 = 0;
boost::detail::allocate_array_helper<A, T2[N]> a1(allocator, &p2); D1 d1;
boost::detail::array_deleter<T2[N]> d1; A1 a1(allocator, &p2);
boost::shared_ptr<T> s1(p1, d1, a1); boost::shared_ptr<T> s1(p1, d1, a1);
typedef boost::detail::array_deleter<T2[N]>* D2;
p1 = reinterpret_cast<T1*>(p2); p1 = reinterpret_cast<T1*>(p2);
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter()); boost::detail::ms_noinit(p2, N);
d2->noinit(p2); D1* d2 = static_cast<D1*>(s1._internal_get_untyped_deleter());
d2->set(p2);
return boost::shared_ptr<T>(s1, p1); return boost::shared_ptr<T>(s1, p1);
} }
} }

View File

@@ -1,169 +0,0 @@
/*
* 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

View File

@@ -0,0 +1,29 @@
/*
* Copyright (c) 2014 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_ALLOCATOR_PAIR_HPP
#define BOOST_SMART_PTR_DETAIL_ALLOCATOR_PAIR_HPP
#include <cstddef>
namespace boost {
namespace detail {
template<typename A, typename T>
struct as_pair
: A {
as_pair(const A& allocator, const T& value)
: A(allocator),
data(value) {
}
T data;
};
}
}
#endif

View File

@@ -0,0 +1,293 @@
/*
* Copyright (c) 2012-2014 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_ALLOCATOR_HPP
#define BOOST_SMART_PTR_DETAIL_ARRAY_ALLOCATOR_HPP
#include <boost/smart_ptr/detail/allocator_pair.hpp>
#include <boost/smart_ptr/detail/array_traits.hpp>
#include <boost/type_traits/alignment_of.hpp>
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
#include <memory>
#endif
namespace boost {
namespace detail {
template<typename T>
struct ms_allocator_base;
template<typename T>
struct ms_allocator_base<T[]> {
ms_allocator_base(std::size_t size_)
: size(size_ * sizeof(T)) {
}
std::size_t size;
};
template<typename T, std::size_t N>
struct ms_allocator_base<T[N]> {
enum {
size = N * sizeof(T)
};
};
template<typename T, typename A, typename Y = char>
class as_allocator
: ms_allocator_base<T> {
using ms_allocator_base<T>::size;
template<typename T_, typename A_, typename Y_>
friend class as_allocator;
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
typedef typename std::allocator_traits<A>::
template rebind_alloc<Y> YA;
typedef typename std::allocator_traits<A>::
template rebind_alloc<char> CA;
typedef typename std::allocator_traits<A>::
template rebind_traits<Y> YT;
typedef typename std::allocator_traits<A>::
template rebind_traits<char> CT;
#else
typedef typename A::template rebind<Y>::other YA;
typedef typename A::template rebind<char>::other CA;
#endif
public:
typedef typename array_inner<T>::type type;
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
typedef typename YT::value_type value_type;
typedef typename YT::pointer pointer;
typedef typename YT::const_pointer const_pointer;
typedef typename YT::size_type size_type;
typedef typename YT::difference_type difference_type;
typedef Y& reference;
typedef const Y& const_reference;
#else
typedef typename YA::value_type value_type;
typedef typename YA::pointer pointer;
typedef typename YA::const_pointer const_pointer;
typedef typename YA::size_type size_type;
typedef typename YA::difference_type difference_type;
typedef typename YA::reference reference;
typedef typename YA::const_reference const_reference;
#endif
template<typename U>
struct rebind {
typedef as_allocator<T, A, U> other;
};
as_allocator(const A& allocator, type** data)
: pair(allocator, data) {
}
as_allocator(const A& allocator, std::size_t size_, type** data)
: ms_allocator_base<T>(size_),
pair(allocator, data) {
}
template<class U>
as_allocator(const as_allocator<T, A, U>& other)
: ms_allocator_base<T>(other),
pair(other.pair, other.pair.data) {
}
pointer address(reference value) const {
return pair.address(value);
}
const_pointer address(const_reference value) const {
return pair.address(value);
}
size_type max_size() const {
return pair.max_size();
}
pointer allocate(size_type count, const void* value = 0) {
std::size_t a1 = boost::alignment_of<type>::value;
std::size_t n1 = count * sizeof(value_type) + a1 - 1;
CA ca(pair);
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
char* p1 = CT::allocate(ca, size + n1, value);
#else
char* p1 = ca.allocate(size + n1, value);
#endif
char* p2 = p1 + n1;
while (std::size_t(p2) % a1 != 0) {
p2--;
}
*pair.data = reinterpret_cast<type*>(p2);
return reinterpret_cast<value_type*>(p1);
}
void deallocate(pointer memory, size_type count) {
std::size_t a1 = boost::alignment_of<type>::value;
std::size_t n1 = count * sizeof(value_type) + a1 - 1;
char* p1 = reinterpret_cast<char*>(memory);
CA ca(pair);
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
CT::deallocate(ca, p1, size + n1);
#else
ca.deallocate(p1, size + n1);
#endif
}
template<typename U>
void construct(U* memory, const_reference value) {
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
YT::construct(pair, memory, value);
#else
pair.construct(memory, value);
#endif
}
template<typename U>
void destroy(U* memory) {
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
YT::destroy(pair, memory);
#else
pair.destroy(memory);
#endif
}
#if !defined(BOOST_NO_CXX11_ALLOCATOR) && \
!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template<typename U, typename... Args>
void construct(U* memory, Args&&... args) {
YT::construct(pair, memory, std::forward<Args>(args)...);
}
#endif
template<typename U>
bool operator==(const as_allocator<T, A, U>& other) const {
return pair == other.pair;
}
template<typename U>
bool operator!=(const as_allocator<T, A, U>& other) const {
return !(*this == other);
}
private:
as_pair<YA, type**> pair;
};
template<typename T, typename Y = char>
class ms_allocator
: ms_allocator_base<T> {
using ms_allocator_base<T>::size;
template<typename T_, typename Y_>
friend class ms_allocator;
public:
typedef typename array_inner<T>::type type;
typedef Y value_type;
typedef Y* pointer;
typedef const Y* const_pointer;
typedef std::size_t size_type;
typedef ptrdiff_t difference_type;
typedef Y& reference;
typedef const Y& const_reference;
template<typename U>
struct rebind {
typedef ms_allocator<T, U> other;
};
ms_allocator(type** data_)
: data(data_) {
}
ms_allocator(std::size_t size_, type** data_)
: ms_allocator_base<T>(size_),
data(data_) {
}
template<class U>
ms_allocator(const ms_allocator<T, U>& other)
: ms_allocator_base<T>(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 {
enum {
N = static_cast<std::size_t>(-1) / sizeof(value_type)
};
return N;
}
pointer allocate(size_type count, const void* = 0) {
std::size_t a1 = boost::alignment_of<type>::value;
std::size_t n1 = count * sizeof(value_type) + 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<type*>(p2);
return reinterpret_cast<value_type*>(p1);
}
void deallocate(pointer memory, size_type) {
void* p1 = memory;
::operator delete(p1);
}
template<typename U>
void construct(U* memory, const_reference value) {
void* p1 = memory;
::new(p1) U(value);
}
template<typename U>
void destroy(U* memory) {
memory->~U();
}
#if !defined(BOOST_NO_CXX11_ALLOCATOR) && \
!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template<typename U, typename... Args>
void construct(U* memory, Args&&... args) {
void* p1 = memory;
::new(p1) U(std::forward<Args>(args)...);
}
#endif
template<typename U>
bool operator==(const ms_allocator<T, U>&) const {
return true;
}
template<typename U>
bool operator!=(const ms_allocator<T, U>& other) const {
return !(*this == other);
}
private:
type** data;
};
}
}
#endif

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012 Glen Joseph Fernandes * Copyright (c) 2012-2014 Glen Joseph Fernandes
* glenfe at live dot com * glenfe at live dot com
* *
* Distributed under the Boost Software License, * Distributed under the Boost Software License,
@@ -9,114 +9,99 @@
#ifndef BOOST_SMART_PTR_DETAIL_ARRAY_DELETER_HPP #ifndef BOOST_SMART_PTR_DETAIL_ARRAY_DELETER_HPP
#define BOOST_SMART_PTR_DETAIL_ARRAY_DELETER_HPP #define BOOST_SMART_PTR_DETAIL_ARRAY_DELETER_HPP
#include <boost/smart_ptr/detail/allocator_pair.hpp>
#include <boost/smart_ptr/detail/array_traits.hpp>
#include <boost/smart_ptr/detail/array_utility.hpp> #include <boost/smart_ptr/detail/array_utility.hpp>
#include <boost/smart_ptr/detail/sp_forward.hpp>
namespace boost { namespace boost {
namespace detail { namespace detail {
template<typename T> template<typename T>
class array_deleter; struct ms_deleter_base;
template<typename T> template<typename T>
class array_deleter<T[]> { struct ms_deleter_base<T[]> {
public: ms_deleter_base(std::size_t size_)
array_deleter(std::size_t size_) : size(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; std::size_t size;
T* object;
}; };
template<typename T, std::size_t N> template<typename T, std::size_t N>
class array_deleter<T[N]> { struct ms_deleter_base<T[N]> {
enum {
size = N
};
};
template<typename T, typename A>
class as_deleter
: ms_deleter_base<T> {
using ms_deleter_base<T>::size;
public: public:
array_deleter() typedef typename array_inner<T>::type type;
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
typedef typename std::allocator_traits<A>::
template rebind_alloc<type> allocator;
#else
typedef typename A::
template rebind<type>::other allocator;
#endif
as_deleter(const A& allocator_)
: pair(allocator_, 0) {
}
as_deleter(const A& allocator_, std::size_t size_)
: ms_deleter_base<T>(size_),
pair(allocator_, 0) {
}
void set(type* memory) {
pair.data = memory;
}
void operator()(const void*) {
if (pair.data) {
as_destroy<type, allocator>(pair, pair.data, size);
}
}
private:
as_pair<allocator, type*> pair;
};
template<typename T>
class ms_deleter
: ms_deleter_base<T> {
using ms_deleter_base<T>::size;
public:
typedef typename array_inner<T>::type type;
ms_deleter()
: object(0) { : object(0) {
} }
~array_deleter() {
if (object) { ms_deleter(std::size_t size_)
array_destroy(object, N); : ms_deleter_base<T>(size_),
object(0) {
} }
}
void init(T* memory) { void set(type* 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; object = memory;
} }
void operator()(const void*) { void operator()(const void*) {
if (object) { if (object) {
array_destroy(object, N); ms_destroy(object, size);
object = 0;
} }
} }
private: private:
T* object; type* object;
}; };
} }
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012 Glen Joseph Fernandes * Copyright (c) 2012-2014 Glen Joseph Fernandes
* glenfe at live dot com * glenfe at live dot com
* *
* Distributed under the Boost Software License, * Distributed under the Boost Software License,
@@ -9,40 +9,47 @@
#ifndef BOOST_SMART_PTR_DETAIL_ARRAY_TRAITS_HPP #ifndef BOOST_SMART_PTR_DETAIL_ARRAY_TRAITS_HPP
#define BOOST_SMART_PTR_DETAIL_ARRAY_TRAITS_HPP #define BOOST_SMART_PTR_DETAIL_ARRAY_TRAITS_HPP
#include <boost/type_traits/remove_cv.hpp> #include <cstddef>
namespace boost { namespace boost {
namespace detail { namespace detail {
template<typename T> template<typename T>
struct array_base { struct array_base {
typedef typename boost::remove_cv<T>::type type; typedef T type;
}; };
template<typename T> template<typename T>
struct array_base<T[]> { struct array_base<T[]> {
typedef typename array_base<T>::type type; 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;
}; };
template<typename T> template<typename T>
struct array_total { struct array_total {
enum { enum {
size = 1 size = 1
}; };
}; };
template<typename T, std::size_t N> template<typename T, std::size_t N>
struct array_total<T[N]> { struct array_total<T[N]> {
enum { enum {
size = N * array_total<T>::size size = N * array_total<T>::size
}; };
}; };
template<typename T> template<typename T>
struct array_inner; struct array_inner;
template<typename T> template<typename T>
struct array_inner<T[]> { struct array_inner<T[]> {
typedef T type; typedef T type;
}; };
template<typename T, std::size_t N> template<typename T, std::size_t N>
struct array_inner<T[N]> { struct array_inner<T[N]> {
typedef T type; typedef T type;

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012 Glen Joseph Fernandes * Copyright (c) 2012-2014 Glen Joseph Fernandes
* glenfe at live dot com * glenfe at live dot com
* *
* Distributed under the Boost Software License, * Distributed under the Boost Software License,
@@ -12,31 +12,61 @@
#include <boost/config.hpp> #include <boost/config.hpp>
#include <boost/type_traits/has_trivial_constructor.hpp> #include <boost/type_traits/has_trivial_constructor.hpp>
#include <boost/type_traits/has_trivial_destructor.hpp> #include <boost/type_traits/has_trivial_destructor.hpp>
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
#include <memory>
#endif
namespace boost { namespace boost {
namespace detail { namespace detail {
typedef boost::true_type ms_is_trivial;
typedef boost::false_type ms_no_trivial;
template<typename T> template<typename T>
inline void array_destroy(T*, std::size_t, boost::true_type) { inline void ms_destroy(T*, std::size_t, ms_is_trivial) {
} }
template<typename T> template<typename T>
inline void array_destroy(T* memory, std::size_t size, boost::false_type) { inline void ms_destroy(T* memory, std::size_t size, ms_no_trivial) {
for (std::size_t i = size; i > 0;) { for (std::size_t i = size; i > 0;) {
memory[--i].~T(); memory[--i].~T();
} }
} }
template<typename T> template<typename T>
inline void array_destroy(T* memory, std::size_t size) { inline void ms_destroy(T* memory, std::size_t size) {
boost::has_trivial_destructor<T> type; boost::has_trivial_destructor<T> trivial;
array_destroy(memory, size, type); ms_destroy(memory, size, trivial);
} }
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
template<typename T, typename A>
inline void as_destroy(A& allocator, T* memory,
std::size_t size) {
typedef typename std::allocator_traits<A>::
template rebind_traits<T> TT;
for (std::size_t i = size; i > 0;) {
TT::destroy(allocator, &memory[--i]);
}
}
#else
template<typename T, typename A>
inline void as_destroy(const A&, T* memory,
std::size_t size) {
boost::has_trivial_destructor<T> trivial;
ms_destroy(memory, size, trivial);
}
#endif
template<typename T> template<typename T>
inline void array_init(T* memory, std::size_t size, boost::true_type) { inline void ms_init(T* memory, std::size_t size, ms_is_trivial) {
for (std::size_t i = 0; i < size; i++) { for (std::size_t i = 0; i < size; i++) {
memory[i] = T(); void* p1 = memory + i;
::new(p1) T();
} }
} }
template<typename T> template<typename T>
inline void array_init(T* memory, std::size_t size, boost::false_type) { inline void ms_init(T* memory, std::size_t size, ms_no_trivial) {
#if !defined(BOOST_NO_EXCEPTIONS) #if !defined(BOOST_NO_EXCEPTIONS)
std::size_t i = 0; std::size_t i = 0;
try { try {
@@ -45,7 +75,7 @@ namespace boost {
::new(p1) T(); ::new(p1) T();
} }
} catch (...) { } catch (...) {
array_destroy(memory, i); ms_destroy(memory, i);
throw; throw;
} }
#else #else
@@ -55,77 +85,68 @@ namespace boost {
} }
#endif #endif
} }
template<typename T> template<typename T>
inline void array_init(T* memory, std::size_t size) { inline void ms_init(T* memory, std::size_t size) {
boost::has_trivial_default_constructor<T> type; boost::has_trivial_default_constructor<T> trivial;
array_init(memory, size, type); ms_init(memory, size, trivial);
} }
#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_CXX11_ALLOCATOR)
template<typename T, typename A>
inline void as_init(const A& allocator, T* memory, std::size_t size,
ms_is_trivial) {
typedef typename std::allocator_traits<A>::
template rebind_alloc<T> TA;
typedef typename std::allocator_traits<A>::
template rebind_traits<T> TT;
TA a2(allocator);
for (std::size_t i = 0; i < size; i++) {
TT::construct(a2, memory + i);
}
}
template<typename T, typename A>
inline void as_init(const A& allocator, T* memory, std::size_t size,
ms_no_trivial) {
typedef typename std::allocator_traits<A>::
template rebind_alloc<T> TA;
typedef typename std::allocator_traits<A>::
template rebind_traits<T> TT;
TA a2(allocator);
#if !defined(BOOST_NO_EXCEPTIONS) #if !defined(BOOST_NO_EXCEPTIONS)
std::size_t i = 0; std::size_t i = 0;
try { try {
for (; i < size; i++) { for (; i < size; i++) {
void* p1 = memory + i; TT::construct(a2, memory + i);
::new(p1) T(value);
} }
} catch (...) { } catch (...) {
array_destroy(memory, i); as_destroy(a2, memory, i);
throw; throw;
} }
#else #else
for (std::size_t i = 0; i < size; i++) { for (std::size_t i = 0; i < size; i++) {
void* p1 = memory + i; TT::construct(a2, memory + i);
::new(p1) T(value);
} }
#endif #endif
} }
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<typename T, typename... Args> template<typename T, typename A>
inline void array_init_args(T* memory, std::size_t size, Args&&... args) { inline void as_init(const A& allocator, T* memory, std::size_t size) {
#if !defined(BOOST_NO_EXCEPTIONS) boost::has_trivial_default_constructor<T> trivial;
std::size_t i = 0; as_init(allocator, memory, size, trivial);
try {
for (; i < size; i++) {
void* p1 = memory + i;
::new(p1) T(args...);
}
} catch (...) {
array_destroy(memory, i);
throw;
} }
#else #else
for (std::size_t i = 0; i < size; i++) { template<typename T, typename A>
void* p1 = memory + i; inline void as_init(const A&, T* memory, std::size_t size) {
::new(p1) T(args...); boost::has_trivial_default_constructor<T> trivial;
ms_init(memory, size, trivial);
} }
#endif #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> template<typename T, std::size_t N>
inline void array_init_list(T* memory, std::size_t size, const T* list) { inline void ms_init(T* memory, std::size_t size, const T* list) {
#if !defined(BOOST_NO_EXCEPTIONS) #if !defined(BOOST_NO_EXCEPTIONS)
std::size_t i = 0; std::size_t i = 0;
try { try {
@@ -134,7 +155,7 @@ namespace boost {
::new(p1) T(list[i % N]); ::new(p1) T(list[i % N]);
} }
} catch (...) { } catch (...) {
array_destroy(memory, i); ms_destroy(memory, i);
throw; throw;
} }
#else #else
@@ -144,11 +165,62 @@ namespace boost {
} }
#endif #endif
} }
template<typename T>
inline void array_noinit(T*, std::size_t, boost::true_type) { #if !defined(BOOST_NO_CXX11_ALLOCATOR)
template<typename T, typename A, std::size_t N>
inline void as_init(const A& allocator, T* memory, std::size_t size,
const T* list) {
typedef typename std::allocator_traits<A>::
template rebind_alloc<T> TA;
typedef typename std::allocator_traits<A>::
template rebind_traits<T> TT;
TA a2(allocator);
#if !defined(BOOST_NO_EXCEPTIONS)
std::size_t i = 0;
try {
for (; i < size; i++) {
TT::construct(a2, memory + i, list[i % N]);
} }
} catch (...) {
as_destroy(a2, memory, i);
throw;
}
#else
for (std::size_t i = 0; i < size; i++) {
TT::construct(a2, memory + i, list[i % N]);
}
#endif
}
#else
template<typename T, typename A, std::size_t N>
inline void as_init(const A&, 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 (...) {
ms_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
}
#endif
template<typename T> template<typename T>
inline void array_noinit(T* memory, std::size_t size, boost::false_type) { inline void ms_noinit(T*, std::size_t, ms_is_trivial) {
}
template<typename T>
inline void ms_noinit(T* memory, std::size_t size, ms_no_trivial) {
#if !defined(BOOST_NO_EXCEPTIONS) #if !defined(BOOST_NO_EXCEPTIONS)
std::size_t i = 0; std::size_t i = 0;
try { try {
@@ -157,7 +229,7 @@ namespace boost {
::new(p1) T; ::new(p1) T;
} }
} catch (...) { } catch (...) {
array_destroy(memory, i); ms_destroy(memory, i);
throw; throw;
} }
#else #else
@@ -167,10 +239,11 @@ namespace boost {
} }
#endif #endif
} }
template<typename T> template<typename T>
inline void array_noinit(T* memory, std::size_t size) { inline void ms_noinit(T* memory, std::size_t size) {
boost::has_trivial_default_constructor<T> type; boost::has_trivial_default_constructor<T> trivial;
array_noinit(memory, size, type); ms_noinit(memory, size, trivial);
} }
} }
} }

View File

@@ -11,10 +11,11 @@
// boost/detail/atomic_count.hpp - thread/SMP safe reference counter // boost/detail/atomic_count.hpp - thread/SMP safe reference counter
// //
// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd. // Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
// Copyright (c) 2013 Peter Dimov
// //
// Distributed under the Boost Software License, Version 1.0. (See // Distributed under the Boost Software License, Version 1.0.
// 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
// //
// typedef <implementation-defined> boost::detail::atomic_count; // typedef <implementation-defined> boost::detail::atomic_count;
// //
@@ -27,92 +28,68 @@
// a; // a;
// //
// Returns: (long) the current value of a // Returns: (long) the current value of a
// Memory Ordering: acquire
// //
// ++a; // ++a;
// //
// Effects: Atomically increments the value of a // Effects: Atomically increments the value of a
// Returns: (long) the new value of a // Returns: (long) the new value of a
// Memory Ordering: acquire/release
// //
// --a; // --a;
// //
// Effects: Atomically decrements the value of a // Effects: Atomically decrements the value of a
// Returns: (long) the new value of a // Returns: (long) the new value of a
// // Memory Ordering: acquire/release
// Important note: when --a returns zero, it must act as a
// read memory barrier (RMB); i.e. the calling thread must
// have a synchronized view of the memory
//
// On Intel IA-32 (x86) memory is always synchronized, so this
// is not a problem.
//
// On many architectures the atomic instructions already act as
// a memory barrier.
//
// This property is necessary for proper reference counting, since
// a thread can update the contents of a shared object, then
// release its reference, and another thread may immediately
// release the last reference causing object destruction.
//
// The destructor needs to have a synchronized view of the
// object to perform proper cleanup.
//
// Original example by Alexander Terekhov:
//
// Given:
//
// - a mutable shared object OBJ;
// - two threads THREAD1 and THREAD2 each holding
// a private smart_ptr object pointing to that OBJ.
//
// t1: THREAD1 updates OBJ (thread-safe via some synchronization)
// and a few cycles later (after "unlock") destroys smart_ptr;
//
// t2: THREAD2 destroys smart_ptr WITHOUT doing any synchronization
// with respect to shared mutable object OBJ; OBJ destructors
// are called driven by smart_ptr interface...
// //
#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>
#ifndef BOOST_HAS_THREADS #if defined( BOOST_AC_DISABLE_THREADS )
# include <boost/smart_ptr/detail/atomic_count_nt.hpp>
namespace boost #elif defined( BOOST_AC_USE_STD_ATOMIC )
{ # include <boost/smart_ptr/detail/atomic_count_std_atomic.hpp>
namespace detail #elif defined( BOOST_AC_USE_SPINLOCK )
{ # include <boost/smart_ptr/detail/atomic_count_spin.hpp>
typedef long atomic_count;
}
}
#elif defined( BOOST_AC_USE_PTHREADS ) #elif defined( BOOST_AC_USE_PTHREADS )
# include <boost/smart_ptr/detail/atomic_count_pthreads.hpp> # include <boost/smart_ptr/detail/atomic_count_pt.hpp>
#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) #elif defined( BOOST_SP_DISABLE_THREADS )
# include <boost/smart_ptr/detail/atomic_count_nt.hpp>
#elif defined( BOOST_SP_USE_STD_ATOMIC )
# include <boost/smart_ptr/detail/atomic_count_std_atomic.hpp>
#elif defined( BOOST_SP_USE_SPINLOCK )
# include <boost/smart_ptr/detail/atomic_count_spin.hpp>
#elif defined( BOOST_SP_USE_PTHREADS )
# include <boost/smart_ptr/detail/atomic_count_pt.hpp>
#elif defined( BOOST_DISABLE_THREADS ) && !defined( BOOST_SP_ENABLE_THREADS ) && !defined( BOOST_DISABLE_WIN32 )
# include <boost/smart_ptr/detail/atomic_count_nt.hpp>
#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) && !defined( __PATHSCALE__ )
# include <boost/smart_ptr/detail/atomic_count_gcc_x86.hpp> # include <boost/smart_ptr/detail/atomic_count_gcc_x86.hpp>
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
# include <boost/smart_ptr/detail/atomic_count_win32.hpp>
#elif defined( BOOST_SP_HAS_SYNC ) #elif defined( BOOST_SP_HAS_SYNC )
# include <boost/smart_ptr/detail/atomic_count_sync.hpp> # include <boost/smart_ptr/detail/atomic_count_sync.hpp>
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
# include <boost/smart_ptr/detail/atomic_count_win32.hpp>
#elif defined(__GLIBCPP__) || defined(__GLIBCXX__) #elif defined(__GLIBCPP__) || defined(__GLIBCXX__)
# include <boost/smart_ptr/detail/atomic_count_gcc.hpp> # include <boost/smart_ptr/detail/atomic_count_gcc.hpp>
#elif defined(BOOST_HAS_PTHREADS) #elif !defined( BOOST_HAS_THREADS )
# include <boost/smart_ptr/detail/atomic_count_nt.hpp>
# define BOOST_AC_USE_PTHREADS
# include <boost/smart_ptr/detail/atomic_count_pthreads.hpp>
#else #else
# include <boost/smart_ptr/detail/atomic_count_spin.hpp>
// Use #define BOOST_DISABLE_THREADS to avoid the error
#error Unrecognized threading platform
#endif #endif

View File

@@ -0,0 +1,59 @@
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_NT_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_NT_HPP_INCLUDED
//
// boost/detail/atomic_count_nt.hpp
//
// Trivial atomic_count for the single-threaded case
//
// http://gcc.gnu.org/onlinedocs/porting/Thread-safety.html
//
// 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
//
namespace boost
{
namespace detail
{
class atomic_count
{
public:
explicit atomic_count( long v ): value_( v )
{
}
long operator++()
{
return ++value_;
}
long operator--()
{
return --value_;
}
operator long() const
{
return value_;
}
private:
atomic_count(atomic_count const &);
atomic_count & operator=(atomic_count const &);
long value_;
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_NT_HPP_INCLUDED

View File

@@ -11,6 +11,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>
// //
@@ -37,12 +38,12 @@ private:
scoped_lock(pthread_mutex_t & m): m_(m) scoped_lock(pthread_mutex_t & 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 );
} }
private: private:
@@ -54,12 +55,12 @@ public:
explicit atomic_count(long v): value_(v) explicit atomic_count(long v): value_(v)
{ {
pthread_mutex_init(&mutex_, 0); BOOST_VERIFY( pthread_mutex_init( &mutex_, 0 ) == 0 );
} }
~atomic_count() ~atomic_count()
{ {
pthread_mutex_destroy(&mutex_); BOOST_VERIFY( pthread_mutex_destroy( &mutex_ ) == 0 );
} }
long operator++() long operator++()

View File

@@ -0,0 +1,62 @@
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SPIN_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SPIN_HPP_INCLUDED
//
// boost/detail/atomic_count_spin.hpp
//
// Copyright (c) 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/smart_ptr/detail/spinlock_pool.hpp>
namespace boost
{
namespace detail
{
class atomic_count
{
private:
public:
explicit atomic_count( long v ): value_( v )
{
}
long operator++()
{
spinlock_pool<0>::scoped_lock lock( &value_ );
return ++value_;
}
long operator--()
{
spinlock_pool<0>::scoped_lock lock( &value_ );
return --value_;
}
operator long() const
{
spinlock_pool<0>::scoped_lock lock( &value_ );
return value_;
}
private:
atomic_count(atomic_count const &);
atomic_count & operator=(atomic_count const &);
long value_;
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SPIN_HPP_INCLUDED

View File

@@ -0,0 +1,60 @@
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_STD_ATOMIC_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_STD_ATOMIC_HPP_INCLUDED
//
// boost/detail/atomic_count_std_atomic.hpp
//
// atomic_count for std::atomic
//
// 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 <atomic>
#include <cstdint>
namespace boost
{
namespace detail
{
class atomic_count
{
public:
explicit atomic_count( long v ): value_( v )
{
}
long operator++()
{
return value_.fetch_add( 1, std::memory_order_acq_rel ) + 1;
}
long operator--()
{
return value_.fetch_sub( 1, std::memory_order_acq_rel ) - 1;
}
operator long() const
{
return value_.load( std::memory_order_acquire );
}
private:
atomic_count(atomic_count const &);
atomic_count & operator=(atomic_count const &);
std::atomic_int_least32_t value_;
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_STD_ATOMIC_HPP_INCLUDED

View File

@@ -1,157 +0,0 @@
/*
* 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

View File

@@ -1,151 +0,0 @@
#ifndef BOOST_SMART_PTR_DETAIL_SHARED_ARRAY_NMT_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SHARED_ARRAY_NMT_HPP_INCLUDED
//
// detail/shared_array_nmt.hpp - shared_array.hpp without member templates
//
// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
// Copyright (c) 2001, 2002 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)
//
// See http://www.boost.org/libs/smart_ptr/shared_array.htm for documentation.
//
#include <boost/assert.hpp>
#include <boost/checked_delete.hpp>
#include <boost/throw_exception.hpp>
#include <boost/smart_ptr/detail/atomic_count.hpp>
#include <cstddef> // for std::ptrdiff_t
#include <algorithm> // for std::swap
#include <functional> // for std::less
#include <new> // for std::bad_alloc
namespace boost
{
template<class T> class shared_array
{
private:
typedef detail::atomic_count count_type;
public:
typedef T element_type;
explicit shared_array(T * p = 0): px(p)
{
#ifndef BOOST_NO_EXCEPTIONS
try // prevent leak if new throws
{
pn = new count_type(1);
}
catch(...)
{
boost::checked_array_delete(p);
throw;
}
#else
pn = new count_type(1);
if(pn == 0)
{
boost::checked_array_delete(p);
boost::throw_exception(std::bad_alloc());
}
#endif
}
~shared_array()
{
if(--*pn == 0)
{
boost::checked_array_delete(px);
delete pn;
}
}
shared_array(shared_array const & r) : px(r.px) // never throws
{
pn = r.pn;
++*pn;
}
shared_array & operator=(shared_array const & r)
{
shared_array(r).swap(*this);
return *this;
}
void reset(T * p = 0)
{
BOOST_ASSERT(p == 0 || p != px);
shared_array(p).swap(*this);
}
T * get() const // never throws
{
return px;
}
T & operator[](std::ptrdiff_t i) const // never throws
{
BOOST_ASSERT(px != 0);
BOOST_ASSERT(i >= 0);
return px[i];
}
long use_count() const // never throws
{
return *pn;
}
bool unique() const // never throws
{
return *pn == 1;
}
void swap(shared_array<T> & other) // never throws
{
std::swap(px, other.px);
std::swap(pn, other.pn);
}
private:
T * px; // contained pointer
count_type * pn; // ptr to reference counter
}; // shared_array
template<class T, class U> inline bool operator==(shared_array<T> const & a, shared_array<U> const & b)
{
return a.get() == b.get();
}
template<class T, class U> inline bool operator!=(shared_array<T> const & a, shared_array<U> const & b)
{
return a.get() != b.get();
}
template<class T> inline bool operator<(shared_array<T> const & a, shared_array<T> const & b)
{
return std::less<T*>()(a.get(), b.get());
}
template<class T> void swap(shared_array<T> & a, shared_array<T> & b)
{
a.swap(b);
}
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SHARED_ARRAY_NMT_HPP_INCLUDED

View File

@@ -225,16 +225,35 @@ public:
#endif #endif
{ {
typedef sp_counted_impl_pda<P, D, A> impl_type; typedef sp_counted_impl_pda<P, D, A> impl_type;
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
typedef typename std::allocator_traits<A>::template rebind_alloc< impl_type > A2;
#else
typedef typename A::template rebind< impl_type >::other A2; typedef typename A::template rebind< impl_type >::other A2;
#endif
A2 a2( a ); A2 a2( a );
#ifndef BOOST_NO_EXCEPTIONS #ifndef BOOST_NO_EXCEPTIONS
try try
{ {
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
impl_type * pi = std::allocator_traits<A2>::allocate( a2, 1 );
pi_ = pi;
std::allocator_traits<A2>::construct( a2, pi, p, d, a );
#else
pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) ); pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
new( static_cast< void* >( pi_ ) ) impl_type( p, d, a ); ::new( static_cast< void* >( pi_ ) ) impl_type( p, d, a );
#endif
} }
catch(...) catch(...)
{ {
@@ -248,13 +267,30 @@ public:
throw; throw;
} }
#else
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
impl_type * pi = std::allocator_traits<A2>::allocate( a2, 1 );
pi_ = pi;
#else #else
pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) ); pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
#endif
if( pi_ != 0 ) if( pi_ != 0 )
{ {
new( static_cast< void* >( pi_ ) ) impl_type( p, d, a ); #if !defined( BOOST_NO_CXX11_ALLOCATOR )
std::allocator_traits<A2>::construct( a2, pi, p, d, a );
#else
::new( static_cast< void* >( pi_ ) ) impl_type( p, d, a );
#endif
} }
else else
{ {
@@ -273,16 +309,35 @@ public:
#endif #endif
{ {
typedef sp_counted_impl_pda< P, D, A > impl_type; typedef sp_counted_impl_pda< P, D, A > impl_type;
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
typedef typename std::allocator_traits<A>::template rebind_alloc< impl_type > A2;
#else
typedef typename A::template rebind< impl_type >::other A2; typedef typename A::template rebind< impl_type >::other A2;
#endif
A2 a2( a ); A2 a2( a );
#ifndef BOOST_NO_EXCEPTIONS #ifndef BOOST_NO_EXCEPTIONS
try try
{ {
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
impl_type * pi = std::allocator_traits<A2>::allocate( a2, 1 );
pi_ = pi;
std::allocator_traits<A2>::construct( a2, pi, p, a );
#else
pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) ); pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
new( static_cast< void* >( pi_ ) ) impl_type( p, a ); ::new( static_cast< void* >( pi_ ) ) impl_type( p, a );
#endif
} }
catch(...) catch(...)
{ {
@@ -296,13 +351,30 @@ public:
throw; throw;
} }
#else
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
impl_type * pi = std::allocator_traits<A2>::allocate( a2, 1 );
pi_ = pi;
#else #else
pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) ); pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
#endif
if( pi_ != 0 ) if( pi_ != 0 )
{ {
new( static_cast< void* >( pi_ ) ) impl_type( p, a ); #if !defined( BOOST_NO_CXX11_ALLOCATOR )
std::allocator_traits<A2>::construct( a2, pi, p, a );
#else
::new( static_cast< void* >( pi_ ) ) impl_type( p, a );
#endif
} }
else else
{ {

View File

@@ -1,182 +0,0 @@
#ifndef BOOST_SMART_PTR_DETAIL_SHARED_PTR_NMT_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SHARED_PTR_NMT_HPP_INCLUDED
//
// detail/shared_ptr_nmt.hpp - shared_ptr.hpp without member templates
//
// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
// Copyright (c) 2001, 2002 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)
//
// See http://www.boost.org/libs/smart_ptr/shared_ptr.htm for documentation.
//
#include <boost/assert.hpp>
#include <boost/checked_delete.hpp>
#include <boost/throw_exception.hpp>
#include <boost/smart_ptr/detail/atomic_count.hpp>
#ifndef BOOST_NO_AUTO_PTR
# include <memory> // for std::auto_ptr
#endif
#include <algorithm> // for std::swap
#include <functional> // for std::less
#include <new> // for std::bad_alloc
namespace boost
{
template<class T> class shared_ptr
{
private:
typedef detail::atomic_count count_type;
public:
typedef T element_type;
typedef T value_type;
explicit shared_ptr(T * p = 0): px(p)
{
#ifndef BOOST_NO_EXCEPTIONS
try // prevent leak if new throws
{
pn = new count_type(1);
}
catch(...)
{
boost::checked_delete(p);
throw;
}
#else
pn = new count_type(1);
if(pn == 0)
{
boost::checked_delete(p);
boost::throw_exception(std::bad_alloc());
}
#endif
}
~shared_ptr()
{
if(--*pn == 0)
{
boost::checked_delete(px);
delete pn;
}
}
shared_ptr(shared_ptr const & r): px(r.px) // never throws
{
pn = r.pn;
++*pn;
}
shared_ptr & operator=(shared_ptr const & r)
{
shared_ptr(r).swap(*this);
return *this;
}
#ifndef BOOST_NO_AUTO_PTR
explicit shared_ptr(std::auto_ptr<T> & r)
{
pn = new count_type(1); // may throw
px = r.release(); // fix: moved here to stop leak if new throws
}
shared_ptr & operator=(std::auto_ptr<T> & r)
{
shared_ptr(r).swap(*this);
return *this;
}
#endif
void reset(T * p = 0)
{
BOOST_ASSERT(p == 0 || p != px);
shared_ptr(p).swap(*this);
}
T & operator*() const // never throws
{
BOOST_ASSERT(px != 0);
return *px;
}
T * operator->() const // never throws
{
BOOST_ASSERT(px != 0);
return px;
}
T * get() const // never throws
{
return px;
}
long use_count() const // never throws
{
return *pn;
}
bool unique() const // never throws
{
return *pn == 1;
}
void swap(shared_ptr<T> & other) // never throws
{
std::swap(px, other.px);
std::swap(pn, other.pn);
}
private:
T * px; // contained pointer
count_type * pn; // ptr to reference counter
};
template<class T, class U> inline bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b)
{
return a.get() == b.get();
}
template<class T, class U> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b)
{
return a.get() != b.get();
}
template<class T> inline bool operator<(shared_ptr<T> const & a, shared_ptr<T> const & b)
{
return std::less<T*>()(a.get(), b.get());
}
template<class T> void swap(shared_ptr<T> & a, shared_ptr<T> & b)
{
a.swap(b);
}
// get_pointer() enables boost::mem_fn to recognize shared_ptr
template<class T> inline T * get_pointer(shared_ptr<T> const & p)
{
return p.get();
}
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SHARED_PTR_NMT_HPP_INCLUDED

View File

@@ -10,7 +10,7 @@
// //
// detail/sp_counted_base.hpp // detail/sp_counted_base.hpp
// //
// Copyright 2005, 2006 Peter Dimov // Copyright 2005-2013 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
@@ -23,6 +23,9 @@
#if defined( BOOST_SP_DISABLE_THREADS ) #if defined( BOOST_SP_DISABLE_THREADS )
# include <boost/smart_ptr/detail/sp_counted_base_nt.hpp> # include <boost/smart_ptr/detail/sp_counted_base_nt.hpp>
#elif defined( BOOST_SP_USE_STD_ATOMIC )
# include <boost/smart_ptr/detail/sp_counted_base_std_atomic.hpp>
#elif defined( BOOST_SP_USE_SPINLOCK ) #elif defined( BOOST_SP_USE_SPINLOCK )
# include <boost/smart_ptr/detail/sp_counted_base_spin.hpp> # include <boost/smart_ptr/detail/sp_counted_base_spin.hpp>

View File

@@ -19,6 +19,7 @@
// //
#include <boost/detail/sp_typeinfo.hpp> #include <boost/detail/sp_typeinfo.hpp>
#include <boost/assert.hpp>
#include <pthread.h> #include <pthread.h>
namespace boost namespace boost
@@ -46,15 +47,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
} }
virtual ~sp_counted_base() // nothrow virtual ~sp_counted_base() // nothrow
{ {
pthread_mutex_destroy( &m_ ); BOOST_VERIFY( pthread_mutex_destroy( &m_ ) == 0 );
} }
// dispose() is called when use_count_ drops to zero, to release // dispose() is called when use_count_ drops to zero, to release
@@ -74,24 +75,24 @@ public:
void add_ref_copy() void add_ref_copy()
{ {
pthread_mutex_lock( &m_ ); BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
++use_count_; ++use_count_;
pthread_mutex_unlock( &m_ ); BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
} }
bool add_ref_lock() // true on success bool add_ref_lock() // true on success
{ {
pthread_mutex_lock( &m_ ); BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
bool r = use_count_ == 0? false: ( ++use_count_, true ); bool r = use_count_ == 0? false: ( ++use_count_, true );
pthread_mutex_unlock( &m_ ); BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
return r; return r;
} }
void release() // nothrow void release() // nothrow
{ {
pthread_mutex_lock( &m_ ); BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
long new_use_count = --use_count_; long new_use_count = --use_count_;
pthread_mutex_unlock( &m_ ); BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
if( new_use_count == 0 ) if( new_use_count == 0 )
{ {
@@ -102,16 +103,16 @@ public:
void weak_add_ref() // nothrow void weak_add_ref() // nothrow
{ {
pthread_mutex_lock( &m_ ); BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
++weak_count_; ++weak_count_;
pthread_mutex_unlock( &m_ ); BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
} }
void weak_release() // nothrow void weak_release() // nothrow
{ {
pthread_mutex_lock( &m_ ); BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
long new_weak_count = --weak_count_; long new_weak_count = --weak_count_;
pthread_mutex_unlock( &m_ ); BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
if( new_weak_count == 0 ) if( new_weak_count == 0 )
{ {
@@ -121,9 +122,9 @@ public:
long use_count() const // nothrow long use_count() const // nothrow
{ {
pthread_mutex_lock( &m_ ); BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
long r = use_count_; long r = use_count_;
pthread_mutex_unlock( &m_ ); BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
return r; return r;
} }

View File

@@ -0,0 +1,137 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_STD_ATOMIC_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_STD_ATOMIC_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
// detail/sp_counted_base_std_atomic.hpp - C++11 std::atomic
//
// Copyright (c) 2007, 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/detail/sp_typeinfo.hpp>
#include <atomic>
#include <cstdint>
namespace boost
{
namespace detail
{
inline void atomic_increment( std::atomic_int_least32_t * pw )
{
pw->fetch_add( 1, std::memory_order_relaxed );
}
inline std::int_least32_t atomic_decrement( std::atomic_int_least32_t * pw )
{
return pw->fetch_sub( 1, std::memory_order_acq_rel );
}
inline std::int_least32_t atomic_conditional_increment( std::atomic_int_least32_t * pw )
{
// long r = *pw;
// if( r != 0 ) ++*pw;
// return r;
std::int_least32_t r = pw->load( std::memory_order_relaxed );
for( ;; )
{
if( r == 0 )
{
return r;
}
if( pw->compare_exchange_weak( r, r + 1, std::memory_order_relaxed, std::memory_order_relaxed ) )
{
return r;
}
}
}
class sp_counted_base
{
private:
sp_counted_base( sp_counted_base const & );
sp_counted_base & operator= ( sp_counted_base const & );
std::atomic_int_least32_t use_count_; // #shared
std::atomic_int_least32_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 use_count_.load( std::memory_order_acquire );
}
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_STD_ATOMIC_HPP_INCLUDED

View File

@@ -213,7 +213,7 @@ public:
{ {
} }
sp_counted_impl_pda( P p, A a ): p_( p ), d_(), a_( a ) sp_counted_impl_pda( P p, A a ): p_( p ), d_( a ), a_( a )
{ {
} }
@@ -224,11 +224,28 @@ public:
virtual void destroy() // nothrow virtual void destroy() // nothrow
{ {
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
typedef typename std::allocator_traits<A>::template rebind_alloc< this_type > A2;
#else
typedef typename A::template rebind< this_type >::other A2; typedef typename A::template rebind< this_type >::other A2;
#endif
A2 a2( a_ ); A2 a2( a_ );
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
std::allocator_traits<A2>::destroy( a2, this );
#else
this->~this_type(); this->~this_type();
#endif
a2.deallocate( this, 1 ); a2.deallocate( this, 1 );
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012 Glen Joseph Fernandes * Copyright (c) 2012-2014 Glen Joseph Fernandes
* glenfe at live dot com * glenfe at live dot com
* *
* Distributed under the Boost Software License, * Distributed under the Boost Software License,
@@ -15,12 +15,15 @@ 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;

View File

@@ -0,0 +1,26 @@
/*
* Copyright (c) 2014 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_UP_IF_ARRAY_HPP
#define BOOST_SMART_PTR_DETAIL_UP_IF_ARRAY_HPP
#include <memory>
namespace boost {
namespace detail {
template<typename T>
struct up_if_array;
template<typename T>
struct up_if_array<T[]> {
typedef std::unique_ptr<T[]> type;
};
}
}
#endif

View File

@@ -0,0 +1,31 @@
/*
* Copyright (c) 2014 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_UP_IF_NOT_ARRAY_HPP
#define BOOST_SMART_PTR_DETAIL_UP_IF_NOT_ARRAY_HPP
#include <memory>
namespace boost {
namespace detail {
template<typename T>
struct up_if_not_array {
typedef std::unique_ptr<T> type;
};
template<typename T>
struct up_if_not_array<T[]> {
};
template<typename T, std::size_t N>
struct up_if_not_array<T[N]> {
};
}
}
#endif

View File

@@ -146,11 +146,23 @@ public:
this_type( rhs ).swap( *this ); this_type( rhs ).swap( *this );
} }
void reset( T * rhs, bool add_ref )
{
this_type( rhs, add_ref ).swap( *this );
}
T * get() const BOOST_NOEXCEPT T * get() const BOOST_NOEXCEPT
{ {
return px; return px;
} }
T * detach() BOOST_NOEXCEPT
{
T * ret = px;
px = 0;
return ret;
}
T & operator*() const T & operator*() const
{ {
BOOST_ASSERT( px != 0 ); BOOST_ASSERT( px != 0 );

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012 Glen Joseph Fernandes * Copyright (c) 2012-2014 Glen Joseph Fernandes
* glenfe at live dot com * glenfe at live dot com
* *
* Distributed under the Boost Software License, * Distributed under the Boost Software License,
@@ -9,14 +9,10 @@
#ifndef BOOST_SMART_PTR_MAKE_SHARED_ARRAY_HPP #ifndef BOOST_SMART_PTR_MAKE_SHARED_ARRAY_HPP
#define 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_allocator.hpp>
#include <boost/smart_ptr/detail/array_deleter.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> #include <boost/smart_ptr/detail/sp_if_array.hpp>
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) #include <boost/type_traits/remove_cv.hpp>
#include <initializer_list>
#endif
namespace boost { namespace boost {
template<typename T> template<typename T>
@@ -24,222 +20,139 @@ namespace boost {
make_shared(std::size_t size) { make_shared(std::size_t size) {
typedef typename boost::detail::array_inner<T>::type T1; typedef typename boost::detail::array_inner<T>::type T1;
typedef typename boost::detail::array_base<T1>::type T2; typedef typename boost::detail::array_base<T1>::type T2;
typedef typename boost::remove_cv<T2>::type T3;
typedef boost::detail::ms_allocator<T3[]> A1;
typedef boost::detail::ms_deleter<T3[]> D1;
T1* p1 = 0; T1* p1 = 0;
T2* p2 = 0; T3* p2 = 0;
std::size_t n1 = size * boost::detail::array_total<T1>::size; std::size_t n1 = size * boost::detail::array_total<T1>::size;
boost::detail::make_array_helper<T2[]> a1(n1, &p2); D1 d1(n1);
boost::detail::array_deleter<T2[]> d1(n1); A1 a1(n1, &p2);
boost::shared_ptr<T> s1(p1, d1, a1); boost::shared_ptr<T> s1(p1, d1, a1);
typedef boost::detail::array_deleter<T2[]>* D2;
p1 = reinterpret_cast<T1*>(p2); p1 = reinterpret_cast<T1*>(p2);
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter()); boost::detail::ms_init(p2, n1);
d2->init(p2); D1* d2 = static_cast<D1*>(s1._internal_get_untyped_deleter());
d2->set(p2);
return boost::shared_ptr<T>(s1, p1); 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> template<typename T>
inline typename boost::detail::sp_if_size_array<T>::type inline typename boost::detail::sp_if_size_array<T>::type
make_shared(const T& list) { make_shared() {
typedef typename boost::detail::array_inner<T>::type T1; typedef typename boost::detail::array_inner<T>::type T1;
typedef typename boost::detail::array_base<T1>::type T2; typedef typename boost::detail::array_base<T1>::type T2;
typedef const T2 T3; typedef typename boost::remove_cv<T2>::type T3;
enum { enum {
N = boost::detail::array_total<T>::size N = boost::detail::array_total<T>::size
}; };
typedef boost::detail::ms_allocator<T3[N]> A1;
typedef boost::detail::ms_deleter<T3[N]> D1;
T1* p1 = 0; T1* p1 = 0;
T2* p2 = 0; T3* p2 = 0;
T3* p3 = 0; D1 d1;
boost::detail::make_array_helper<T2[N]> a1(&p2); A1 a1(&p2);
boost::detail::array_deleter<T2[N]> d1;
boost::shared_ptr<T> s1(p1, d1, a1); 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); p1 = reinterpret_cast<T1*>(p2);
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter()); boost::detail::ms_init(p2, N);
d2->init_list(p2, p3); D1* d2 = static_cast<D1*>(s1._internal_get_untyped_deleter());
d2->set(p2);
return boost::shared_ptr<T>(s1, p1); return boost::shared_ptr<T>(s1, p1);
} }
template<typename T> template<typename T>
inline typename boost::detail::sp_if_array<T>::type inline typename boost::detail::sp_if_array<T>::type
make_shared(std::size_t size, make_shared(std::size_t size,
const typename boost::detail::array_inner<T>::type& list) { const typename boost::detail::array_inner<T>::type& value) {
typedef typename boost::detail::array_inner<T>::type T1; typedef typename boost::detail::array_inner<T>::type T1;
typedef typename boost::detail::array_base<T1>::type T2; typedef typename boost::detail::array_base<T1>::type T2;
typedef const T2 T3; typedef typename boost::remove_cv<T2>::type T3;
typedef const T2 T4;
typedef boost::detail::ms_allocator<T3[]> A1;
typedef boost::detail::ms_deleter<T3[]> D1;
enum { enum {
M = boost::detail::array_total<T1>::size M = boost::detail::array_total<T1>::size
}; };
T1* p1 = 0; T1* p1 = 0;
T2* p2 = 0; T3* p2 = 0;
T3* p3 = 0; T4* p3 = reinterpret_cast<T4*>(&value);
std::size_t n1 = M * size; std::size_t n1 = M * size;
boost::detail::make_array_helper<T2[]> a1(n1, &p2); D1 d1(n1);
boost::detail::array_deleter<T2[]> d1(n1); A1 a1(n1, &p2);
boost::shared_ptr<T> s1(p1, d1, a1); 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); p1 = reinterpret_cast<T1*>(p2);
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter()); boost::detail::ms_init<T3, M>(p2, n1, p3);
d2->template init_list<M>(p2, p3); D1* d2 = static_cast<D1*>(s1._internal_get_untyped_deleter());
d2->set(p2);
return boost::shared_ptr<T>(s1, p1); return boost::shared_ptr<T>(s1, p1);
} }
template<typename T> template<typename T>
inline typename boost::detail::sp_if_size_array<T>::type inline typename boost::detail::sp_if_size_array<T>::type
make_shared(const typename boost::detail::array_inner<T>::type& list) { make_shared(const typename boost::detail::array_inner<T>::type& value) {
typedef typename boost::detail::array_inner<T>::type T1; typedef typename boost::detail::array_inner<T>::type T1;
typedef typename boost::detail::array_base<T1>::type T2; typedef typename boost::detail::array_base<T1>::type T2;
typedef const T2 T3; typedef typename boost::remove_cv<T2>::type T3;
typedef const T2 T4;
enum { enum {
M = boost::detail::array_total<T1>::size, M = boost::detail::array_total<T1>::size,
N = boost::detail::array_total<T>::size N = boost::detail::array_total<T>::size
}; };
typedef boost::detail::ms_allocator<T3[N]> A1;
typedef boost::detail::ms_deleter<T3[N]> D1;
T1* p1 = 0; T1* p1 = 0;
T2* p2 = 0; T3* p2 = 0;
T3* p3 = 0; T4* p3 = reinterpret_cast<T4*>(&value);
boost::detail::make_array_helper<T2[N]> a1(&p2); D1 d1;
boost::detail::array_deleter<T2[N]> d1; A1 a1(&p2);
boost::shared_ptr<T> s1(p1, d1, a1); 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); p1 = reinterpret_cast<T1*>(p2);
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter()); boost::detail::ms_init<T3, M>(p2, N, p3);
d2->template init_list<M>(p2, p3); D1* d2 = static_cast<D1*>(s1._internal_get_untyped_deleter());
d2->set(p2);
return boost::shared_ptr<T>(s1, p1); 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> template<typename T>
inline typename boost::detail::sp_if_array<T>::type inline typename boost::detail::sp_if_array<T>::type
make_shared_noinit(std::size_t size) { make_shared_noinit(std::size_t size) {
typedef typename boost::detail::array_inner<T>::type T1; typedef typename boost::detail::array_inner<T>::type T1;
typedef typename boost::detail::array_base<T1>::type T2; typedef typename boost::detail::array_base<T1>::type T2;
typedef typename boost::remove_cv<T2>::type T3;
typedef boost::detail::ms_allocator<T3[]> A1;
typedef boost::detail::ms_deleter<T3[]> D1;
T1* p1 = 0; T1* p1 = 0;
T2* p2 = 0; T3* p2 = 0;
std::size_t n1 = size * boost::detail::array_total<T1>::size; std::size_t n1 = size * boost::detail::array_total<T1>::size;
boost::detail::make_array_helper<T2[]> a1(n1, &p2); D1 d1(n1);
boost::detail::array_deleter<T2[]> d1(n1); A1 a1(n1, &p2);
boost::shared_ptr<T> s1(p1, d1, a1); boost::shared_ptr<T> s1(p1, d1, a1);
typedef boost::detail::array_deleter<T2[]>* D2;
p1 = reinterpret_cast<T1*>(p2); p1 = reinterpret_cast<T1*>(p2);
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter()); boost::detail::ms_noinit(p2, n1);
d2->noinit(p2); D1* d2 = static_cast<D1*>(s1._internal_get_untyped_deleter());
d2->set(p2);
return boost::shared_ptr<T>(s1, p1); return boost::shared_ptr<T>(s1, p1);
} }
template<typename T> template<typename T>
inline typename boost::detail::sp_if_size_array<T>::type inline typename boost::detail::sp_if_size_array<T>::type
make_shared_noinit() { make_shared_noinit() {
typedef typename boost::detail::array_inner<T>::type T1; typedef typename boost::detail::array_inner<T>::type T1;
typedef typename boost::detail::array_base<T1>::type T2; typedef typename boost::detail::array_base<T1>::type T2;
typedef typename boost::remove_cv<T2>::type T3;
enum { enum {
N = boost::detail::array_total<T>::size N = boost::detail::array_total<T>::size
}; };
typedef boost::detail::ms_allocator<T3[N]> A1;
typedef boost::detail::ms_deleter<T3[N]> D1;
T1* p1 = 0; T1* p1 = 0;
T2* p2 = 0; T3* p2 = 0;
boost::detail::make_array_helper<T2[N]> a1(&p2); D1 d1;
boost::detail::array_deleter<T2[N]> d1; A1 a1(&p2);
boost::shared_ptr<T> s1(p1, d1, a1); boost::shared_ptr<T> s1(p1, d1, a1);
typedef boost::detail::array_deleter<T2[N]>* D2;
p1 = reinterpret_cast<T1*>(p2); p1 = reinterpret_cast<T1*>(p2);
D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter()); boost::detail::ms_noinit(p2, N);
d2->noinit(p2); D1* d2 = static_cast<D1*>(s1._internal_get_untyped_deleter());
d2->set(p2);
return boost::shared_ptr<T>(s1, p1); return boost::shared_ptr<T>(s1, p1);
} }
} }

View File

@@ -72,6 +72,10 @@ public:
{ {
} }
template<class A> explicit sp_ms_deleter( A const & ) BOOST_NOEXCEPT : initialized_( false )
{
}
// optimization: do not copy storage_ // optimization: do not copy storage_
sp_ms_deleter( sp_ms_deleter const & ) BOOST_NOEXCEPT : initialized_( false ) sp_ms_deleter( sp_ms_deleter const & ) BOOST_NOEXCEPT : initialized_( false )
{ {
@@ -102,6 +106,74 @@ public:
} }
}; };
template< class T, class A > class sp_as_deleter
{
private:
typedef typename sp_aligned_storage< sizeof( T ), ::boost::alignment_of< T >::value >::type storage_type;
storage_type storage_;
A a_;
bool initialized_;
private:
void destroy()
{
if( initialized_ )
{
T * p = reinterpret_cast< T* >( storage_.data_ );
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
std::allocator_traits<A>::destroy( a_, p );
#else
p->~T();
#endif
initialized_ = false;
}
}
public:
sp_as_deleter( A const & a ) BOOST_NOEXCEPT : a_( a ), initialized_( false )
{
}
// optimization: do not copy storage_
sp_as_deleter( sp_as_deleter const & r ) BOOST_NOEXCEPT : a_( r.a_), initialized_( false )
{
}
~sp_as_deleter()
{
destroy();
}
void operator()( T * )
{
destroy();
}
static void operator_fn( T* ) // operator() can't be static
{
}
void * address() BOOST_NOEXCEPT
{
return storage_.data_;
}
void set_initialized() BOOST_NOEXCEPT
{
initialized_ = true;
}
};
template< class T > struct sp_if_not_array template< class T > struct sp_if_not_array
{ {
typedef boost::shared_ptr< T > type; typedef boost::shared_ptr< T > type;
@@ -131,26 +203,7 @@ template< class T, std::size_t N > struct sp_if_not_array< T[N] >
# define BOOST_SP_MSD( T ) boost::detail::sp_ms_deleter< T >() # define BOOST_SP_MSD( T ) boost::detail::sp_ms_deleter< T >()
#endif #endif
// Zero-argument versions // _noinit versions
//
// Used even when variadic templates are available because of the new T() vs new T issue
template< class T > typename boost::detail::sp_if_not_array< T >::type make_shared()
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
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 > typename boost::detail::sp_if_not_array< T >::type make_shared_noinit() template< class T > typename boost::detail::sp_if_not_array< T >::type make_shared_noinit()
{ {
@@ -169,23 +222,6 @@ template< class T > typename boost::detail::sp_if_not_array< T >::type make_shar
return boost::shared_ptr< T >( pt, pt2 ); return boost::shared_ptr< T >( pt, pt2 );
} }
template< class T, class A > typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
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 > typename boost::detail::sp_if_not_array< T >::type allocate_shared_noinit( A const & a ) template< class T, class A > typename boost::detail::sp_if_not_array< T >::type allocate_shared_noinit( A const & a )
{ {
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a ); boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
@@ -207,7 +243,7 @@ template< class T, class A > typename boost::detail::sp_if_not_array< T >::type
// Variadic templates, rvalue reference // Variadic templates, rvalue reference
template< class T, class Arg1, class... Args > typename boost::detail::sp_if_not_array< T >::type make_shared( Arg1 && arg1, Args && ... args ) template< class T, class... Args > typename boost::detail::sp_if_not_array< T >::type make_shared( Args && ... args )
{ {
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) ); boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
@@ -215,7 +251,7 @@ template< class T, class Arg1, class... Args > typename boost::detail::sp_if_not
void * pv = pd->address(); void * pv = pd->address();
::new( pv ) T( boost::detail::sp_forward<Arg1>( arg1 ), boost::detail::sp_forward<Args>( args )... ); ::new( pv ) T( boost::detail::sp_forward<Args>( args )... );
pd->set_initialized(); pd->set_initialized();
T * pt2 = static_cast< T* >( pv ); T * pt2 = static_cast< T* >( pv );
@@ -224,7 +260,68 @@ template< class T, class Arg1, class... Args > typename boost::detail::sp_if_not
return boost::shared_ptr< T >( pt, pt2 ); return boost::shared_ptr< T >( pt, pt2 );
} }
template< class T, class A, class Arg1, class... Args > typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, Arg1 && arg1, Args && ... args ) template< class T, class A, class... Args > typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, Args && ... args )
{
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
typedef typename std::allocator_traits<A>::template rebind_alloc<T> A2;
A2 a2( a );
typedef boost::detail::sp_as_deleter< T, A2 > D;
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_inplace_tag<D>(), a2 );
#else
typedef boost::detail::sp_ms_deleter< T > D;
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_inplace_tag<D>(), a );
#endif
D * pd = static_cast< D* >( pt._internal_get_untyped_deleter() );
void * pv = pd->address();
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
std::allocator_traits<A2>::construct( a2, static_cast< T* >( pv ), boost::detail::sp_forward<Args>( args )... );
#else
::new( pv ) T( boost::detail::sp_forward<Args>( args )... );
#endif
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 // !defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
// Common zero-argument versions
template< class T > typename boost::detail::sp_if_not_array< T >::type make_shared()
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
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 > typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a )
{ {
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a ); boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
@@ -232,7 +329,7 @@ template< class T, class A, class Arg1, class... Args > typename boost::detail::
void * pv = pd->address(); void * pv = pd->address();
::new( pv ) T( boost::detail::sp_forward<Arg1>( arg1 ), boost::detail::sp_forward<Args>( args )... ); ::new( pv ) T();
pd->set_initialized(); pd->set_initialized();
T * pt2 = static_cast< T* >( pv ); T * pt2 = static_cast< T* >( pv );
@@ -241,7 +338,7 @@ template< class T, class A, class Arg1, class... Args > typename boost::detail::
return boost::shared_ptr< T >( pt, pt2 ); return boost::shared_ptr< T >( pt, pt2 );
} }
#elif !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
// For example MSVC 10.0 // For example MSVC 10.0
@@ -695,7 +792,7 @@ typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a,
return boost::shared_ptr< T >( pt, pt2 ); return boost::shared_ptr< T >( pt, pt2 );
} }
#else #else // !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
// C++03 version // C++03 version
@@ -1023,7 +1120,9 @@ typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a,
return boost::shared_ptr< T >( pt, pt2 ); return boost::shared_ptr< T >( pt, pt2 );
} }
#endif #endif // !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
#endif // !defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
#undef BOOST_SP_MSD #undef BOOST_SP_MSD

View File

@@ -0,0 +1,15 @@
/*
* Copyright (c) 2014 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_UNIQUE_HPP
#define BOOST_SMART_PTR_MAKE_UNIQUE_HPP
#include <boost/smart_ptr/make_unique_array.hpp>
#include <boost/smart_ptr/make_unique_object.hpp>
#endif

View File

@@ -0,0 +1,31 @@
/*
* Copyright (c) 2014 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_UNIQUE_ARRAY_HPP
#define BOOST_SMART_PTR_MAKE_UNIQUE_ARRAY_HPP
#include <boost/smart_ptr/detail/up_if_array.hpp>
#include <boost/smart_ptr/detail/array_traits.hpp>
namespace boost {
template<typename T>
inline typename boost::detail::up_if_array<T>::type
make_unique(std::size_t size) {
typedef typename boost::detail::array_inner<T>::type U;
return std::unique_ptr<T>(new U[size]());
}
template<typename T>
inline typename boost::detail::up_if_array<T>::type
make_unique_noinit(std::size_t size) {
typedef typename boost::detail::array_inner<T>::type U;
return std::unique_ptr<T>(new U[size]);
}
}
#endif

View File

@@ -0,0 +1,44 @@
/*
* Copyright (c) 2014 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_UNIQUE_OBJECT_HPP
#define BOOST_SMART_PTR_MAKE_UNIQUE_OBJECT_HPP
#include <boost/config.hpp>
#include <boost/smart_ptr/detail/up_if_not_array.hpp>
#include <utility>
namespace boost {
template<typename T>
inline typename boost::detail::up_if_not_array<T>::type
make_unique() {
return std::unique_ptr<T>(new T());
}
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<typename T, typename... Args>
inline typename boost::detail::up_if_not_array<T>::type
make_unique(Args&&... args) {
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
#endif
template<typename T>
inline typename boost::detail::up_if_not_array<T>::type
make_unique(T&& value) {
return std::unique_ptr<T>(new T(std::move(value)));
}
template<typename T>
inline typename boost::detail::up_if_not_array<T>::type
make_unique_noinit() {
return std::unique_ptr<T>(new T);
}
}
#endif

View File

@@ -16,10 +16,6 @@
#include <boost/config.hpp> // for broken compiler workarounds #include <boost/config.hpp> // for broken compiler workarounds
#if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
#include <boost/smart_ptr/detail/shared_array_nmt.hpp>
#else
#include <memory> // TR1 cyclic inclusion fix #include <memory> // TR1 cyclic inclusion fix
#include <boost/assert.hpp> #include <boost/assert.hpp>
@@ -61,6 +57,14 @@ public:
{ {
} }
#if !defined( BOOST_NO_CXX11_NULLPTR )
shared_array( boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT : px( 0 ), pn()
{
}
#endif
template<class Y> template<class Y>
explicit shared_array( Y * p ): px( p ), pn( p, checked_array_deleter<Y>() ) explicit shared_array( Y * p ): px( p ), pn( p, checked_array_deleter<Y>() )
{ {
@@ -285,6 +289,4 @@ template< class D, class T > D * get_deleter( shared_array<T> const & p )
} // namespace boost } // namespace boost
#endif // #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
#endif // #ifndef BOOST_SMART_PTR_SHARED_ARRAY_HPP_INCLUDED #endif // #ifndef BOOST_SMART_PTR_SHARED_ARRAY_HPP_INCLUDED

View File

@@ -16,10 +16,6 @@
#include <boost/config.hpp> // for broken compiler workarounds #include <boost/config.hpp> // for broken compiler workarounds
#if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
#include <boost/smart_ptr/detail/shared_ptr_nmt.hpp>
#else
// 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
@@ -1030,6 +1026,4 @@ template< class T > std::size_t hash_value( boost::shared_ptr<T> const & p ) BOO
} // namespace boost } // namespace boost
#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

View File

@@ -1,14 +1,17 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html> <html>
<head> <head>
<title>Smart Pointers</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="refresh" content="0; URL=smart_ptr.htm"> <meta http-equiv="refresh" content="0; URL=smart_ptr.htm">
</head> </head>
<body> <body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
Automatic redirection failed, please go to Automatic redirection failed, please go to
<a href="smart_ptr.htm">smart_ptr.htm</a>. <a href="smart_ptr.htm">smart_ptr.htm</a>.
</body> </body>
</html> </html>
<!-- <!--
<09> Copyright Beman Dawes, 2001 (C) Copyright Beman Dawes, 2001
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

View File

@@ -1,49 +1,49 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html> <html>
<head> <head>
<title>intrusive_ptr</title> <title>intrusive_ptr</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head> </head>
<body text="#000000" bgColor="#ffffff"> <body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
<h1><A href="../../index.htm"><IMG height="86" alt="boost.png (6897 bytes)" src="../../boost.png" width="277" align="middle" <h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
border="0"></A>intrusive_ptr class template</h1> width="277" align="middle" border="0">intrusive_ptr class template</h1>
<p> <p>
<A href="#Introduction">Introduction</A><br> <a href="#Introduction">Introduction</a><br>
<A href="#Synopsis">Synopsis</A><br> <a href="#Synopsis">Synopsis</a><br>
<A href="#Members">Members</A><br> <a href="#Members">Members</a><br>
<A href="#functions">Free Functions</A><br> <a href="#functions">Free Functions</a><br>
</p> </p>
<h2><a name="Introduction">Introduction</a></h2> <h2><a name="Introduction">Introduction</a></h2>
<p>The <b>intrusive_ptr</b> class template stores a pointer to an object with an <p>The <code>intrusive_ptr</code> class template stores a pointer to an object with an
embedded reference count. Every new <b>intrusive_ptr</b> instance increments embedded reference count. Every new <code>intrusive_ptr</code> instance increments
the reference count by using an unqualified call to the function <STRONG>intrusive_ptr_add_ref</STRONG>, the reference count by using an unqualified call to the function <code>intrusive_ptr_add_ref</code>,
passing it the pointer as an argument. Similarly, when an <STRONG>intrusive_ptr</STRONG> passing it the pointer as an argument. Similarly, when an <code>intrusive_ptr</code>
is destroyed, it calls <STRONG>intrusive_ptr_release</STRONG>; this function is is destroyed, it calls <code>intrusive_ptr_release</code>; this function is
responsible for destroying the object when its reference count drops to zero. responsible for destroying the object when its reference count drops to zero.
The user is expected to provide suitable definitions of these two functions. On The user is expected to provide suitable definitions of these two functions. On
compilers that support argument-dependent lookup, <STRONG>intrusive_ptr_add_ref</STRONG> compilers that support argument-dependent lookup, <code>intrusive_ptr_add_ref</code>
and <STRONG>intrusive_ptr_release</STRONG> should be defined in the namespace and <code>intrusive_ptr_release</code> 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>. The library provides a helper base class template namespace <code>boost</code>. The library provides a helper base class template
<STRONG><a href="intrusive_ref_counter.html">intrusive_ref_counter</a></STRONG> which may <code><a href="intrusive_ref_counter.html">intrusive_ref_counter</a></code> which may
help adding support for <STRONG>intrusive_ptr</STRONG> to user&apos;s types.</p> help adding support for <code>intrusive_ptr</code> to user 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 <code>T</code>, the type of the object pointed
to. <STRONG>intrusive_ptr&lt;T&gt;</STRONG> can be implicitly converted to <STRONG>intrusive_ptr&lt;U&gt;</STRONG> to. <code>intrusive_ptr&lt;T&gt;</code> can be implicitly converted to <code>intrusive_ptr&lt;U&gt;</code>
whenever <STRONG>T*</STRONG> can be implicitly converted to <STRONG>U*</STRONG>.</p> whenever <code>T*</code> can be implicitly converted to <code>U*</code>.</p>
<P>The main reasons to use <STRONG>intrusive_ptr</STRONG> are:</P> <p>The main reasons to use <code>intrusive_ptr</code> are:</p>
<UL> <ul>
<LI> <li>
Some existing frameworks or OSes provide objects with embedded reference Some existing frameworks or OSes provide objects with embedded reference
counts; counts;</li>
<LI> <li>
The memory footprint of <STRONG>intrusive_ptr</STRONG> The memory footprint of <code>intrusive_ptr</code>
is the same as the corresponding raw pointer; is the same as the corresponding raw pointer;</li>
<LI> <li>
<STRONG>intrusive_ptr&lt;T&gt;</STRONG> can be constructed from an arbitrary <code>intrusive_ptr&lt;T&gt;</code> can be constructed from an arbitrary
raw pointer of type <STRONG>T *</STRONG>.</LI></UL> raw pointer of type <code>T *</code>.</li></ul>
<P>As a general rule, if it isn't obvious whether <STRONG>intrusive_ptr</STRONG> better <p>As a general rule, if it isn't obvious whether <code>intrusive_ptr</code> better
fits your needs than <STRONG>shared_ptr</STRONG>, try a <STRONG>shared_ptr</STRONG>-based fits your needs than <code>shared_ptr</code>, try a <code>shared_ptr</code>-based
design first.</P> design first.</p>
<h2><a name="Synopsis">Synopsis</a></h2> <h2><a name="Synopsis">Synopsis</a></h2>
<pre>namespace boost { <pre>namespace boost {
@@ -51,75 +51,77 @@
public: public:
typedef T <A href="#element_type" >element_type</A>; typedef T <a href="#element_type" >element_type</a>;
<A href="#constructors" >intrusive_ptr</A>(); // never throws <a href="#constructors" >intrusive_ptr</a>(); // never throws
<A href="#constructors" >intrusive_ptr</A>(T * p, bool add_ref = true); <a href="#constructors" >intrusive_ptr</a>(T * p, bool add_ref = true);
<A href="#constructors" >intrusive_ptr</A>(intrusive_ptr const &amp; r); <a href="#constructors" >intrusive_ptr</a>(intrusive_ptr const &amp; r);
template&lt;class Y&gt; <A href="#constructors" >intrusive_ptr</A>(intrusive_ptr&lt;Y&gt; const &amp; r); template&lt;class Y&gt; <a href="#constructors" >intrusive_ptr</a>(intrusive_ptr&lt;Y&gt; const &amp; r);
<A href="#destructor" >~intrusive_ptr</A>(); <a href="#destructor" >~intrusive_ptr</a>();
intrusive_ptr &amp; <A href="#assignment" >operator=</A>(intrusive_ptr const &amp; r); intrusive_ptr &amp; <a href="#assignment" >operator=</a>(intrusive_ptr const &amp; r);
template&lt;class Y&gt; intrusive_ptr &amp; <A href="#assignment" >operator=</A>(intrusive_ptr&lt;Y&gt; const &amp; r); template&lt;class Y&gt; intrusive_ptr &amp; <a href="#assignment" >operator=</a>(intrusive_ptr&lt;Y&gt; const &amp; r);
intrusive_ptr &amp; <A href="#assignment" >operator=</A>(T * r); intrusive_ptr &amp; <a href="#assignment" >operator=</a>(T * r);
void <a href="#reset" >reset</a>(); void <a href="#reset" >reset</a>();
void <a href="#reset" >reset</a>(T * r); void <a href="#reset" >reset</a>(T * r);
void <a href="#reset" >reset</a>(T * r, bool add_ref);
T &amp; <A href="#indirection" >operator*</A>() const; // never throws T &amp; <a href="#indirection" >operator*</a>() const; // never throws
T * <A href="#indirection" >operator-&gt;</A>() const; // never throws T * <a href="#indirection" >operator-&gt;</a>() const; // never throws
T * <A href="#get" >get</A>() const; // never throws T * <a href="#get" >get</a>() const; // never throws
T * <a href="#detach" >detach</a>(); // never throws
operator <A href="#conversions" ><i>unspecified-bool-type</i></A>() const; // never throws operator <a href="#conversions" ><i>unspecified-bool-type</i></a>() const; // never throws
void <A href="#swap" >swap</A>(intrusive_ptr &amp; b); // never throws void <a href="#swap" >swap</a>(intrusive_ptr &amp; b); // never throws
}; };
template&lt;class T, class U&gt; template&lt;class T, class U&gt;
bool <A href="#comparison" >operator==</A>(intrusive_ptr&lt;T&gt; const &amp; a, intrusive_ptr&lt;U&gt; const &amp; b); // never throws bool <a href="#comparison" >operator==</a>(intrusive_ptr&lt;T&gt; const &amp; a, intrusive_ptr&lt;U&gt; const &amp; b); // never throws
template&lt;class T, class U&gt; template&lt;class T, class U&gt;
bool <A href="#comparison" >operator!=</A>(intrusive_ptr&lt;T&gt; const &amp; a, intrusive_ptr&lt;U&gt; const &amp; b); // never throws bool <a href="#comparison" >operator!=</a>(intrusive_ptr&lt;T&gt; const &amp; a, intrusive_ptr&lt;U&gt; const &amp; b); // never throws
template&lt;class T&gt; template&lt;class T&gt;
bool <A href="#comparison" >operator==</A>(intrusive_ptr&lt;T&gt; const &amp; a, T * b); // never throws bool <a href="#comparison" >operator==</a>(intrusive_ptr&lt;T&gt; const &amp; a, T * b); // never throws
template&lt;class T&gt; template&lt;class T&gt;
bool <A href="#comparison" >operator!=</A>(intrusive_ptr&lt;T&gt; const &amp; a, T * b); // never throws bool <a href="#comparison" >operator!=</a>(intrusive_ptr&lt;T&gt; const &amp; a, T * b); // never throws
template&lt;class T&gt; template&lt;class T&gt;
bool <A href="#comparison" >operator==</A>(T * a, intrusive_ptr&lt;T&gt; const &amp; b); // never throws bool <a href="#comparison" >operator==</a>(T * a, intrusive_ptr&lt;T&gt; const &amp; b); // never throws
template&lt;class T&gt; template&lt;class T&gt;
bool <A href="#comparison" >operator!=</A>(T * a, intrusive_ptr&lt;T&gt; const &amp; b); // never throws bool <a href="#comparison" >operator!=</a>(T * a, intrusive_ptr&lt;T&gt; const &amp; b); // never throws
template&lt;class T, class U&gt; template&lt;class T, class U&gt;
bool <A href="#comparison" >operator&lt;</A>(intrusive_ptr&lt;T&gt; const &amp; a, intrusive_ptr&lt;U&gt; const &amp; b); // never throws bool <a href="#comparison" >operator&lt;</a>(intrusive_ptr&lt;T&gt; const &amp; a, intrusive_ptr&lt;U&gt; const &amp; b); // never throws
template&lt;class T&gt; void <A href="#free-swap" >swap</A>(intrusive_ptr&lt;T&gt; &amp; a, intrusive_ptr&lt;T&gt; &amp; b); // never throws template&lt;class T&gt; void <a href="#free-swap" >swap</a>(intrusive_ptr&lt;T&gt; &amp; a, intrusive_ptr&lt;T&gt; &amp; b); // never throws
template&lt;class T&gt; T * <A href="#get_pointer" >get_pointer</A>(intrusive_ptr&lt;T&gt; const &amp; p); // never throws template&lt;class T&gt; T * <a href="#get_pointer" >get_pointer</a>(intrusive_ptr&lt;T&gt; const &amp; p); // never throws
template&lt;class T, class U&gt; template&lt;class T, class U&gt;
intrusive_ptr&lt;T&gt; <A href="#static_pointer_cast" >static_pointer_cast</A>(intrusive_ptr&lt;U&gt; const &amp; r); // never throws intrusive_ptr&lt;T&gt; <a href="#static_pointer_cast" >static_pointer_cast</a>(intrusive_ptr&lt;U&gt; const &amp; r); // never throws
template&lt;class T, class U&gt; template&lt;class T, class U&gt;
intrusive_ptr&lt;T&gt; <A href="#const_pointer_cast" >const_pointer_cast</A>(intrusive_ptr&lt;U&gt; const &amp; r); // never throws intrusive_ptr&lt;T&gt; <a href="#const_pointer_cast" >const_pointer_cast</a>(intrusive_ptr&lt;U&gt; const &amp; r); // never throws
template&lt;class T, class U&gt; template&lt;class T, class U&gt;
intrusive_ptr&lt;T&gt; <A href="#dynamic_pointer_cast" >dynamic_pointer_cast</A>(intrusive_ptr&lt;U&gt; const &amp; r); // never throws intrusive_ptr&lt;T&gt; <a href="#dynamic_pointer_cast" >dynamic_pointer_cast</a>(intrusive_ptr&lt;U&gt; const &amp; r); // never throws
template&lt;class E, class T, class Y&gt; template&lt;class E, class T, class Y&gt;
std::basic_ostream&lt;E, T&gt; &amp; <A href="#insertion-operator" >operator&lt;&lt;</A> (std::basic_ostream&lt;E, T&gt; &amp; os, intrusive_ptr&lt;Y&gt; const &amp; p); std::basic_ostream&lt;E, T&gt; &amp; <a href="#insertion-operator" >operator&lt;&lt;</a> (std::basic_ostream&lt;E, T&gt; &amp; os, intrusive_ptr&lt;Y&gt; const &amp; p);
}</pre> }</pre>
<h2><a name="Members">Members</a></h2> <h2><a name="Members">Members</a></h2>
<h3><a name="element_type">element_type</a></h3> <h3><a name="element_type">element_type</a></h3>
<pre>typedef T element_type;</pre> <pre>typedef T element_type;</pre>
<blockquote> <blockquote>
<p>Provides the type of the template parameter T.</p> <p>Provides the type of the template parameter <code>T</code>.</p>
</blockquote> </blockquote>
<h3><a name="constructors">constructors</a></h3> <h3><a name="constructors">constructors</a></h3>
<pre>intrusive_ptr(); // never throws</pre> <pre>intrusive_ptr(); // never throws</pre>
@@ -140,26 +142,30 @@ template&lt;class Y&gt; intrusive_ptr(intrusive_ptr&lt;Y&gt; const &amp; r);</pr
</blockquote> </blockquote>
<h3><a name="destructor">destructor</a></h3> <h3><a name="destructor">destructor</a></h3>
<pre>~intrusive_ptr();</pre> <pre>~intrusive_ptr();</pre>
<BLOCKQUOTE> <blockquote>
<P><B>Effects:</B> <code>if(get() != 0) intrusive_ptr_release(get());</code>.</P> <p><b>Effects:</b> <code>if(get() != 0) intrusive_ptr_release(get());</code>.</p>
</BLOCKQUOTE> </blockquote>
<H3><a name="assignment">assignment</a></H3> <h3><a name="assignment">assignment</a></h3>
<pre>intrusive_ptr &amp; operator=(intrusive_ptr const &amp; r); <pre>intrusive_ptr &amp; operator=(intrusive_ptr const &amp; r);
template&lt;class Y&gt; intrusive_ptr &amp; operator=(intrusive_ptr&lt;Y&gt; const &amp; r); template&lt;class Y&gt; intrusive_ptr &amp; operator=(intrusive_ptr&lt;Y&gt; const &amp; r);
intrusive_ptr &amp; operator=(T * r);</pre> intrusive_ptr &amp; operator=(T * r);</pre>
<BLOCKQUOTE> <blockquote>
<P><B>Effects:</B> Equivalent to <code>intrusive_ptr(r).swap(*this)</code>.</P> <p><b>Effects:</b> Equivalent to <code>intrusive_ptr(r).swap(*this)</code>.</p>
<P><B>Returns:</B> <code>*this</code>.</P> <p><b>Returns:</b> <code>*this</code>.</p>
</BLOCKQUOTE> </blockquote>
<H3><a name="reset">reset</a></H3> <h3><a name="reset">reset</a></h3>
<pre>void reset();</pre> <pre>void reset();</pre>
<BLOCKQUOTE> <blockquote>
<P><B>Effects:</B> Equivalent to <code>intrusive_ptr().swap(*this)</code>.</P> <p><b>Effects:</b> Equivalent to <code>intrusive_ptr().swap(*this)</code>.</p>
</BLOCKQUOTE> </blockquote>
<pre>void reset(T * r);</pre> <pre>void reset(T * r);</pre>
<BLOCKQUOTE> <blockquote>
<P><B>Effects:</B> Equivalent to <code>intrusive_ptr(r).swap(*this)</code>.</P> <p><b>Effects:</b> Equivalent to <code>intrusive_ptr(r).swap(*this)</code>.</p>
</BLOCKQUOTE> </blockquote>
<pre>void reset(T * r, bool add_ref);</pre>
<blockquote>
<p><b>Effects:</b> Equivalent to <code>intrusive_ptr(r, add_ref).swap(*this)</code>.</p>
</blockquote>
<h3><a name="indirection">indirection</a></h3> <h3><a name="indirection">indirection</a></h3>
<pre>T &amp; operator*() const; // never throws</pre> <pre>T &amp; operator*() const; // never throws</pre>
<blockquote> <blockquote>
@@ -179,16 +185,32 @@ intrusive_ptr &amp; operator=(T * r);</pre>
<p><b>Returns:</b> the stored pointer.</p> <p><b>Returns:</b> the stored pointer.</p>
<p><b>Throws:</b> nothing.</p> <p><b>Throws:</b> nothing.</p>
</blockquote> </blockquote>
<h3><a name="detach">detach</a></h3>
<pre>T * detach(); // never throws</pre>
<blockquote>
<p><b>Returns:</b> the stored pointer.</p>
<p><b>Throws:</b> nothing.</p>
<p><b>Postconditions:</b> <code>get() == 0</code>.</p>
<p><b>Notes:</b> The returned pointer has an elevated reference count. This
allows conversion of an <code>intrusive_ptr</code> back to a raw pointer,
without the performance overhead of acquiring and dropping an extra
reference. It can be viewed as the complement of the
non-reference-incrementing constructor.</p>
<p><b>Caution:</b> Using <code>detach</code> escapes the safety of automatic
reference counting provided by <code>intrusive_ptr</code>. It should
by used only where strictly necessary (such as when interfacing to an
existing API), and when the implications are thoroughly understood.</p>
</blockquote>
<h3><a name="conversions">conversions</a></h3> <h3><a name="conversions">conversions</a></h3>
<pre>operator <i>unspecified-bool-type</i> () const; // never throws</pre> <pre>operator <i>unspecified-bool-type</i> () const; // never throws</pre>
<blockquote> <blockquote>
<p><b>Returns:</b> an unspecified value that, when used in boolean contexts, is <p><b>Returns:</b> an unspecified value that, when used in boolean contexts, is
equivalent to <code>get() != 0</code>.</p> equivalent to <code>get() != 0</code>.</p>
<p><b>Throws:</b> nothing.</p> <p><b>Throws:</b> nothing.</p>
<P><B>Notes:</B> This conversion operator allows <b>intrusive_ptr</b> objects to be <p><b>Notes:</b> This conversion operator allows <code>intrusive_ptr</code> objects to be
used in boolean contexts, like <code>if (p &amp;&amp; p-&gt;valid()) {}</code>. used in boolean contexts, like <code>if (p &amp;&amp; p-&gt;valid()) {}</code>.
The actual target type is typically a pointer to a member function, avoiding The actual target type is typically a pointer to a member function, avoiding
many of the implicit conversion pitfalls.</P> many of the implicit conversion pitfalls.</p>
</blockquote> </blockquote>
<h3><a name="swap">swap</a></h3> <h3><a name="swap">swap</a></h3>
<pre>void swap(intrusive_ptr &amp; b); // never throws</pre> <pre>void swap(intrusive_ptr &amp; b); // never throws</pre>
@@ -239,61 +261,60 @@ intrusive_ptr &amp; operator=(T * r);</pre>
<blockquote> <blockquote>
<p><b>Returns:</b> <code>std::less&lt;T *&gt;()(a.get(), b.get())</code>.</p> <p><b>Returns:</b> <code>std::less&lt;T *&gt;()(a.get(), b.get())</code>.</p>
<p><b>Throws:</b> nothing.</p> <p><b>Throws:</b> nothing.</p>
<P><B>Notes:</B> Allows <STRONG>intrusive_ptr</STRONG> objects to be used as keys <p><b>Notes:</b> Allows <code>intrusive_ptr</code> objects to be used as keys
in associative containers.</P> in associative containers.</p>
</blockquote> </blockquote>
<h3><a name="free-swap">swap</a></h3> <h3><a name="free-swap">swap</a></h3>
<pre>template&lt;class T&gt; <pre>template&lt;class T&gt;
void swap(intrusive_ptr&lt;T&gt; &amp; a, intrusive_ptr&lt;T&gt; &amp; b); // never throws</pre> void swap(intrusive_ptr&lt;T&gt; &amp; a, intrusive_ptr&lt;T&gt; &amp; b); // never throws</pre>
<BLOCKQUOTE> <blockquote>
<P><B>Effects:</B> Equivalent to <code>a.swap(b)</code>.</P> <p><b>Effects:</b> Equivalent to <code>a.swap(b)</code>.</p>
<P><B>Throws:</B> nothing.</P> <p><b>Throws:</b> nothing.</p>
<P><B>Notes:</B> Matches the interface of <B>std::swap</B>. Provided as an aid to <p><b>Notes:</b> Matches the interface of <code>std::swap</code>. Provided as an aid to
generic programming.</P> generic programming.</p>
</BLOCKQUOTE> </blockquote>
<h3><a name="get_pointer">get_pointer</a></h3> <h3><a name="get_pointer">get_pointer</a></h3>
<pre>template&lt;class T&gt; <pre>template&lt;class T&gt;
T * get_pointer(intrusive_ptr&lt;T&gt; const &amp; p); // never throws</pre> T * get_pointer(intrusive_ptr&lt;T&gt; const &amp; p); // never throws</pre>
<BLOCKQUOTE> <blockquote>
<P><B>Returns:</B> <code>p.get()</code>.</P> <p><b>Returns:</b> <code>p.get()</code>.</p>
<P><B>Throws:</B> nothing.</P> <p><b>Throws:</b> nothing.</p>
<P><B>Notes:</B> Provided as an aid to generic programming. Used by <A href="../bind/mem_fn.html"> <p><b>Notes:</b> Provided as an aid to generic programming. Used by <a href="../bind/mem_fn.html">
mem_fn</A>.</P> mem_fn</a>.</p>
</BLOCKQUOTE> </blockquote>
<h3><a name="static_pointer_cast">static_pointer_cast</a></h3> <h3><a name="static_pointer_cast">static_pointer_cast</a></h3>
<pre>template&lt;class T, class U&gt; <pre>template&lt;class T, class U&gt;
intrusive_ptr&lt;T&gt; static_pointer_cast(intrusive_ptr&lt;U&gt; const &amp; r); // never throws</pre> intrusive_ptr&lt;T&gt; static_pointer_cast(intrusive_ptr&lt;U&gt; const &amp; r); // never throws</pre>
<BLOCKQUOTE> <blockquote>
<P><B>Returns:</B> <code>intrusive_ptr&lt;T&gt;(static_cast&lt;T*&gt;(r.get()))</code>.</P> <p><b>Returns:</b> <code>intrusive_ptr&lt;T&gt;(static_cast&lt;T*&gt;(r.get()))</code>.</p>
<P><B>Throws:</B> nothing.</P> <p><b>Throws:</b> nothing.</p>
</BLOCKQUOTE> </blockquote>
<h3><a name="const_pointer_cast">const_pointer_cast</a></h3> <h3><a name="const_pointer_cast">const_pointer_cast</a></h3>
<pre>template&lt;class T, class U&gt; <pre>template&lt;class T, class U&gt;
intrusive_ptr&lt;T&gt; const_pointer_cast(intrusive_ptr&lt;U&gt; const &amp; r); // never throws</pre> intrusive_ptr&lt;T&gt; const_pointer_cast(intrusive_ptr&lt;U&gt; const &amp; r); // never throws</pre>
<BLOCKQUOTE> <blockquote>
<P><B>Returns:</B> <code>intrusive_ptr&lt;T&gt;(const_cast&lt;T*&gt;(r.get()))</code>.</P> <p><b>Returns:</b> <code>intrusive_ptr&lt;T&gt;(const_cast&lt;T*&gt;(r.get()))</code>.</p>
<P><B>Throws:</B> nothing.</P> <p><b>Throws:</b> nothing.</p>
</BLOCKQUOTE> </blockquote>
<h3><a name="dynamic_pointer_cast">dynamic_pointer_cast</a></h3> <h3><a name="dynamic_pointer_cast">dynamic_pointer_cast</a></h3>
<pre>template&lt;class T, class U&gt; <pre>template&lt;class T, class U&gt;
intrusive_ptr&lt;T&gt; dynamic_pointer_cast(intrusive_ptr&lt;U&gt; const &amp; r);</pre> intrusive_ptr&lt;T&gt; dynamic_pointer_cast(intrusive_ptr&lt;U&gt; const &amp; r);</pre>
<BLOCKQUOTE> <blockquote>
<P><B>Returns:</B> <code>intrusive_ptr&lt;T&gt;(dynamic_cast&lt;T*&gt;(r.get()))</code>.</P> <p><b>Returns:</b> <code>intrusive_ptr&lt;T&gt;(dynamic_cast&lt;T*&gt;(r.get()))</code>.</p>
<P><B>Throws:</B> nothing.</P> <p><b>Throws:</b> nothing.</p>
</BLOCKQUOTE> </blockquote>
<h3><a name="insertion-operator">operator&lt;&lt;</a></h3> <h3><a name="insertion-operator">operator&lt;&lt;</a></h3>
<pre>template&lt;class E, class T, class Y&gt; <pre>template&lt;class E, class T, class Y&gt;
std::basic_ostream&lt;E, T&gt; &amp; operator&lt;&lt; (std::basic_ostream&lt;E, T&gt; &amp; os, intrusive_ptr&lt;Y&gt; const &amp; p);</pre> std::basic_ostream&lt;E, T&gt; &amp; operator&lt;&lt; (std::basic_ostream&lt;E, T&gt; &amp; os, intrusive_ptr&lt;Y&gt; const &amp; p);</pre>
<BLOCKQUOTE> <blockquote>
<p><STRONG>Effects:</STRONG> <code>os &lt;&lt; p.get();</code>.</p> <p><b>Effects:</b> <code>os &lt;&lt; p.get();</code>.</p>
<P><B>Returns:</B> <code>os</code>.</P> <p><b>Returns:</b> <code>os</code>.</p>
</BLOCKQUOTE> </blockquote>
<hr> <hr>
<p>$Date$</p>
<p> <p>
$Date$</p> <small>Copyright &copy; 2003-2005, 2013 Peter Dimov. Distributed under the Boost Software License, Version
<p> 1.0. See accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or
<small>Copyright <20> 2003-2005 Peter Dimov. Distributed under the Boost Software License, Version copy at <a href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>.</small></p>
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> </body>
</html> </html>

View File

@@ -1,12 +1,12 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html> <html>
<head> <head>
<title>intrusive_ref_counter</title> <title>intrusive_ref_counter</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head> </head>
<body text="#000000" bgColor="#ffffff"> <body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
<h1><A href="../../index.htm"><IMG height="86" alt="boost.png (6897 bytes)" src="../../boost.png" width="277" align="middle" <h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
border="0"></A>basic_intrusive_ref_counter class template</h1> width="277" align="middle" border="0">basic_intrusive_ref_counter class template</h1>
<p> <p>
<A href="#Introduction">Introduction</A><br> <A href="#Introduction">Introduction</A><br>
<A href="#Synopsis">Synopsis</A><br> <A href="#Synopsis">Synopsis</A><br>
@@ -14,11 +14,11 @@
</p> </p>
<h2><a name="Introduction">Introduction</a></h2> <h2><a name="Introduction">Introduction</a></h2>
<p>The <STRONG>intrusive_ref_counter</STRONG> class template implements a reference counter for a derived <p>The <STRONG>intrusive_ref_counter</STRONG> class template implements a reference counter for a derived
user&apos;s class that is intended to be used with <STRONG><a href="intrusive_ptr.html">intrusive_ptr</a></STRONG>. 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 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> 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. <p>The class template is parameterized on <STRONG>DerivedT</STRONG> and <STRONG>CounterPolicyT</STRONG> parameters.
The first parameter is the user&apos;s class that derives from <STRONG>intrusive_ref_counter</STRONG>. This type 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> 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. <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 Boost.SmartPtr provides two such policies: <STRONG>thread_unsafe_counter</STRONG> and <STRONG>thread_safe_counter</STRONG>. The former
@@ -85,10 +85,9 @@
<P><B>Notes:</B> The returned value may not be actual in multi-threaded applications.</P> <P><B>Notes:</B> The returned value may not be actual in multi-threaded applications.</P>
</BLOCKQUOTE> </BLOCKQUOTE>
<hr> <hr>
<p>$Date$</p>
<p> <p>
$Date$</p> <small>Copyright &copy; 2013 Andrey Semashev. Distributed under the Boost Software License, Version
<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 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> copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
</body> </body>

View File

@@ -1,12 +1,13 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html> <html>
<head> <head>
<title>make_shared and allocate_shared</title> <title>make_shared and allocate_shared</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head> </head>
<body text="#000000" bgColor="#ffffff"> <body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
<h1><A href="../../index.htm"><IMG height="86" alt="boost.png (6897 bytes)" src="../../boost.png" width="277" align="middle" <h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
border="0"></A>make_shared and allocate_shared function templates</h1> width="277" align="middle" border="0">make_shared and allocate_shared
function templates</h1>
<p><A href="#Introduction">Introduction</A><br> <p><A href="#Introduction">Introduction</A><br>
<A href="#Synopsis">Synopsis</A><br> <A href="#Synopsis">Synopsis</A><br>
<A href="#functions">Free Functions</A><br> <A href="#functions">Free Functions</A><br>
@@ -79,7 +80,7 @@ template&lt;class T, class A, class... Args&gt;
where <code>pv</code> is a <code>void*</code> pointing to storage suitable where <code>pv</code> is a <code>void*</code> pointing to storage suitable
to hold an object of type <code>T</code>, to hold an object of type <code>T</code>,
shall be well-formed. <code>A</code> shall be an <em>Allocator</em>, shall be well-formed. <code>A</code> shall be an <em>Allocator</em>,
as described in section 20.1.5 (<stong>Allocator requirements</strong>) of the C++ Standard. 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> The copy constructor and destructor of <code>A</code> shall not throw.</p>
<p><b>Effects:</b> Allocates memory suitable for an object of type <code>T</code> <p><b>Effects:</b> Allocates memory suitable for an object of type <code>T</code>
and constructs an object in it via the placement new expression <code>new( pv ) T()</code> and constructs an object in it via the placement new expression <code>new( pv ) T()</code>
@@ -109,8 +110,7 @@ template&lt;class T, class A, class... Args&gt;
<pre>boost::shared_ptr&lt;std::string&gt; x = boost::make_shared&lt;std::string&gt;("hello, world!"); <pre>boost::shared_ptr&lt;std::string&gt; x = boost::make_shared&lt;std::string&gt;("hello, world!");
std::cout << *x;</pre> std::cout << *x;</pre>
<hr> <hr>
<p> <p>$Date$</p>
$Date: 2008-05-19 15:42:39 -0400 (Mon, 19 May 2008) $</p>
<p><small>Copyright 2008 Peter Dimov. Copyright 2008 Frank Mori Hess. <p><small>Copyright 2008 Peter Dimov. Copyright 2008 Frank Mori Hess.
Distributed under the Boost Software License, Distributed under the Boost Software License,
Version 1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> Version 1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A>

View File

@@ -1,257 +1,272 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html> <html>
<head> <head>
<title>make_shared and allocate_shared</title> <title>make_shared and allocate_shared for arrays</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head> </head>
<body text="#000000" bgColor="#ffffff" link="#0000ff" vlink="#0000ff"> <body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
<h1><IMG height="86" alt="boost.png (6897 bytes)" src="../../boost.png" <h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
width="277" align="middle" border="0">make_shared and allocate_shared width="277" align="middle" border="0">make_shared and allocate_shared
for arrays</h1> for arrays</h1>
<p><A href="#Introduction">Introduction</A><br> <p><a href="#introduction">Introduction</a><br>
<A href="#Synopsis">Synopsis</A><br> <a href="#synopsis">Synopsis</a><br>
<A href="#functions">Free Functions</A><br> <a href="#common">Common Requirements</a><br>
<A href="#example">Example</A><br> <a href="#functions">Free Functions</a><br>
<A href="#history">History</A><br></p> <a href="#history">History</a><br>
<h2><a name="Introduction">Introduction</a></h2> <a href="#references">References</a></p>
<h2><a name="introduction">Introduction</a></h2>
<p>Originally the Boost function templates <code>make_shared</code> and <p>Originally the Boost function templates <code>make_shared</code> and
<code>allocate_shared</code> were for efficient allocation of single <code>allocate_shared</code> were for efficient allocation of shared
objects only. There was a need to have efficient, single, allocation of objects only. There was a need to have efficient allocation of
arrays. One criticism of <a href="shared_array.htm">shared_array</a> was shared arrays. One criticism of class template <code>shared_array</code>
always the lack of a <a href="make_shared.html">make_shared</a> utility was always the lack of a <a href="make_shared.html">make_shared</a>
which ensures only a single allocation for an array.</p> utility which ensures only a single allocation.</p>
<p>The header files &lt;boost/smart_ptr/make_shared_array.hpp&gt; and <p>The header files &lt;boost/smart_ptr/make_shared_array.hpp&gt; and
&lt;boost/smart_ptr/allocate_shared_array.hpp&gt; provide new function &lt;boost/smart_ptr/allocate_shared_array.hpp&gt; provide function
templates, <code>make_shared</code> and <code>allocate_shared</code>, templates, overloads of <code>make_shared</code> and
to address this need. <code>make_shared</code> uses the global <code>allocate_shared</code> for array types, to address this need.
operator <code>new</code> to allocate memory, whereas <code>make_shared</code> uses the global operator <code>new</code> to
<code>allocate_shared</code> uses an user-supplied allocator, allocate memory, whereas <code>allocate_shared</code> uses an
allowing finer control.</p> user-supplied allocator, allowing finer control.</p>
<h2><a name="Synopsis">Synopsis</a></h2> <h2><a name="synopsis">Synopsis</a></h2>
<pre>namespace boost { <pre>namespace boost {
template&lt;typename U&gt; // U = T[] template&lt;typename U&gt; // U is T[]
shared_ptr&lt;U&gt; <a href="#functions">make_shared</a>(size_t size); shared_ptr&lt;U&gt; <a href="#functions">make_shared</a>(size_t size);
template&lt;typename U, typename A&gt; // U = T[] template&lt;typename U, typename A&gt; // U is T[]
shared_ptr&lt;U&gt; <a href="#functions">allocate_shared</a>(const A&amp; allocator, size_t size); shared_ptr&lt;U&gt; <a href="#functions">allocate_shared</a>(const A&amp; allocator, size_t size);
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) &amp;&amp; !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) template&lt;typename U&gt; // U is T[N]
template&lt;typename U, typename... Args&gt; // U = T[] shared_ptr&lt;U&gt; <a href="#functions">make_shared</a>();
shared_ptr&lt;U&gt; <a href="#functions">make_shared</a>(size_t size, Args&amp;&amp;... args);
template&lt;typename U, typename... Args&gt; // U = T[N] template&lt;typename U, typename A&gt; // U is T[N]
shared_ptr&lt;U&gt; <a href="#functions">make_shared</a>(Args&amp;&amp;... args); shared_ptr&lt;U&gt; <a href="#functions">allocate_shared</a>(const A&amp; allocator);
template&lt;typename U, typename A, typename... Args&gt; // U = T[] template&lt;typename U&gt; // U is T[]
shared_ptr&lt;U&gt; <a href="#functions">allocate_shared</a>(const A&amp; allocator, size_t size, Args&amp;&amp;... args); shared_ptr&lt;U&gt; <a href="#functions">make_shared</a>(size_t size, const T&amp; value);
template&lt;typename U, typename A, typename... Args&gt; // U = T[N] template&lt;typename U, typename A&gt; // U is T[]
shared_ptr&lt;U&gt; <a href="#functions">allocate_shared</a>(const A&amp; allocator, Args&amp;&amp;... args); shared_ptr&lt;U&gt; <a href="#functions">allocate_shared</a>(const A&amp; allocator, size_t size, const T&amp; value);
#endif
#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) template&lt;typename U&gt; // U is T[N]
template&lt;typename U, typename... Args&gt; // U = T[N] shared_ptr&lt;U&gt; <a href="#functions">make_shared</a>(const T&amp; value);
shared_ptr&lt;U&gt; <a href="#functions">make_shared</a>(const T (&amp;list)[N]);
template&lt;typename U, typename... Args&gt; // U = T[][N] template&lt;typename U, typename A&gt; // U is T[N]
shared_ptr&lt;U&gt; <a href="#functions">make_shared</a>(size_t size, const T (&amp;list)[N]); shared_ptr&lt;U&gt; <a href="#functions">allocate_shared</a>(const A&amp; allocator, const T&amp; value);
template&lt;typename U, typename... Args&gt; // U = T[M][N] template&lt;typename U&gt; // U is T[]
shared_ptr&lt;U&gt; <a href="#functions">make_shared</a>(const T (&amp;list)[N]);
template&lt;typename U, typename A, typename... Args&gt; // U = T[N]
shared_ptr&lt;T[&gt; <a href="#functions">allocate_shared</a>(const A&amp; allocator, const T (&amp;list)[N]);
template&lt;typename U, typename A, typename... Args&gt; // U = T[][N]
shared_ptr&lt;U&gt; <a href="#functions">allocate_shared</a>(const A&amp; allocator, size_t size, const T (&amp;list)[N]);
template&lt;typename U, typename A, typename... Args&gt; // U = T[M][N]
shared_ptr&lt;U&gt; <a href="#functions">allocate_shared</a>(const A&amp; allocator, const T (&amp;list)[N]);
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
template&lt;typename U, typename... Args&gt; // U = T[]
shared_ptr&lt;U&gt; <a href="#functions">make_shared</a>(initializer_list&lt;T&gt; list);
template&lt;typename U, typename A, typename... Args&gt; // U = T[]
shared_ptr&lt;U&gt; <a href="#functions">allocate_shared</a>(const A&amp; allocator, initializer_list&lt;T&gt; list);
#endif
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template&lt;typename U&gt; // U = T[]
shared_ptr&lt;U&gt; <a href="#functions">make_shared</a>(size_t size, T&amp;&amp; value);
template&lt;typename U&gt; // U = T[N]
shared_ptr&lt;U&gt; <a href="#functions">make_shared</a>(T&amp;&amp; value);
template&lt;typename U, typename A&gt; // U = T[]
shared_ptr&lt;U&gt; <a href="#functions">allocate_shared</a>(const A&amp; allocator, size_t size, T&amp;&amp; value);
template&lt;typename U, typename A&gt; // U = T[N]
shared_ptr&lt;U&gt; <a href="#functions">allocate_shared</a>(const A&amp; allocator, T&amp;&amp; value);
#endif
#endif
template&lt;typename U&gt; // U = T[]
shared_ptr&lt;U&gt; <a href="#functions">make_shared_noinit</a>(size_t size); shared_ptr&lt;U&gt; <a href="#functions">make_shared_noinit</a>(size_t size);
template&lt;typename U&gt; // U = T[N] template&lt;typename U, typename A&gt; // U is T[]
shared_ptr&lt;U&gt; <a href="#functions">make_shared_noinit</a>();
template&lt;typename U, typename A&gt; // U = T[]
shared_ptr&lt;U&gt; <a href="#functions">allocate_shared_noinit</a>(const A&amp; allocator, size_t size); shared_ptr&lt;U&gt; <a href="#functions">allocate_shared_noinit</a>(const A&amp; allocator, size_t size);
template&lt;typename U, typename A&gt; // U = T[N] template&lt;typename U&gt; // U is T[N]
shared_ptr&lt;U&gt; <a href="#functions">make_shared_noinit</a>();
template&lt;typename U, typename A&gt; // U is T[N]
shared_ptr&lt;U&gt; <a href="#functions">allocate_shared_noinit</a>(const A&amp; allocator); shared_ptr&lt;U&gt; <a href="#functions">allocate_shared_noinit</a>(const A&amp; allocator);
}</pre> }</pre>
<h2><a name="functions">Free Functions</a></h2> <h2><a name="common">Common Requirements</a></h2>
<pre>template&lt;typename U, typename... Args&gt; // U = T[] <pre>template&lt;typename U&gt;
shared_ptr&lt;U&gt; make_shared(size_t size, Args&amp;&amp;... args); shared_ptr&lt;U&gt; make_shared(<em>args</em>);
template&lt;typename U, typename A&gt;
template&lt;typename U, typename A, typename... Args&gt; // U = T[] shared_ptr&lt;U&gt; allocate_shared(const A&amp; allocator, <em>args</em>);
shared_ptr&lt;U&gt; allocate_shared(const A&amp; allocator, size_t size, Args&amp;&amp;... args);</pre> template&lt;typename U&gt;
shared_ptr&lt;U&gt; make_shared_noinit(<em>args</em>);
template&lt;typename U, typename A&gt;
shared_ptr&lt;U&gt; allocate_shared_noinit(const A&amp; allocator, <em>args</em>);</pre>
<blockquote> <blockquote>
<p><b>Requires:</b> The expression <p><b>Requires:</b> <code>U</code> is of the form <code>T[]</code> or
<code>new(pointer) T(forward&lt;Args&gt;(args)...)</code>, where <code>T[N]</code>. <code>A</code> shall be an <em>Allocator</em>, as
<code>pointer</code> is a <code>void*</code> pointing to storage described in section 17.6.3.5 [<strong>Allocator
suitable to hold an object of type <code>T</code>, shall be requirements</strong>] of the C++ Standard. The copy constructor and
well-formed. <code>A</code> shall be an <em>Allocator</em>, as destructor of <code>A</code> shall not throw exceptions.</p>
described in section 20.1.5 (<strong>Allocator requirements</strong>) <p><b>Effects:</b> Allocates memory for an object of type <code>U</code>
of the C++ Standard. The copy constructor and destructor of (or <code>T[size]</code> when <code>U</code> is <code>T[]</code>,
<code>A</code> shall not throw.</p> where <code>size</code> is determined from <code><em>args</em></code>
<p><b>Effects:</b> Allocates memory suitable for an array of type as specified by the concrete overload). The object is initialized as
<code>T</code> and size <code>size</code> and constructs an array specified by the concrete overload. The templates
of objects in it via the placement new expression <code>allocate_shared</code> and <code>allocate_shared_noinit</code>
<code>new(pointer) T()</code> or use a copy of <code>allocator</code> to allocate memory. If an
<code>new(pointer) T(args...)</code>. exception is thrown, the functions have no effect.</p>
<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 <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> owns the address of the newly constructed object.</p>
and size <code>size</code>.</p> <p><b>Postconditions:</b> <code>r.get() != 0 &amp;&amp;
<p><b>Postconditions:</b> r.use_count() == 1</code>, where <code>r</code> is the return
<code>get() != 0 &amp;&amp; use_count() == 1</code>.</p> value.</p>
<p><b>Throws:</b> <code>bad_alloc</code>, or an exception thrown from <p><b>Throws:</b> <code>bad_alloc</code>, an exception thrown from
<code>A::allocate</code> or the constructor of <code>T</code>.</p> <code>A::allocate</code>, or from the initialization of the
<p><b>Notes:</b> This implementation allocates the memory required for object.</p>
the returned <code>shared_ptr</code> and an array of type <p><b>Remarks:</b></p>
<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&lt;typename U, typename... Args&gt; // U = T[N]
shared_ptr&lt;U&gt; make_shared(Args&amp;&amp;... args);
template&lt;typename U, typename A, typename... Args&gt; // U = T[N]
shared_ptr&lt;U&gt; allocate_shared(const A&amp; allocator, Args&amp;&amp;... args);</pre>
<blockquote> <blockquote>
<p><b>Description:</b> These overloads of the utilities above are for a <p>This implementation performs no more than one memory
fixed size array.</p> allocation. This provides efficiency to equivalent to an intrusive
smart pointer.</p>
<p>When an object of an array type <code>T</code> is specified to be
initialized to a value of the same type <code>value</code>, this
shall be interpreted to mean that each array element of the object
is initialized to the corresponding element from
<code>value</code>.</p>
<p>When an object of an array type is specified to be
value-initialized, this shall be interpreted to mean that each
array element of the object is value-initialized.</p>
<p>Array elements are initialized in ascending order of their
addresses.</p>
<p>When a subobject of a non-array type <code>T</code> is specified to
be initialized to a value <code>value</code>,
<code>make_shared</code> shall perform this initialization via the
expression <code>::new(ptr) T(value)</code>, where <code>ptr</code>
has type <code>void*</code> and points to storage suitable to hold
an object of type <code>T</code>.</p>
<p>When a subobject of non-array type <code>T</code> is specified to
be initialized to a value <code>value</code>,
<code>allocate_shared</code> shall perform this initialization via
the expression <code>allocator_traits&lt;A2&gt;::construct(a2, ptr,
value)</code>, where <code>ptr</code> points to storage suitable to
hold an object of type <code>T</code> and <code>a2</code> of type A2
is a rebound copy of the allocator <code>allocator</code> passed to
<code>allocate_shared</code> such that its <code>value_type</code>
is <code>T</code>.</p>
<p>When a subobject of non-array type <code>T</code> is specified to
be value-initialized, <code>make_shared</code> shall perform this
initialization via the expression <code>::new(ptr) T()</code>, where
<code>ptr</code> has type <code>void*</code> and points to storage
suitable to hold an object of type <code>T</code>.</p>
<p>When a subobject of non-array type <code>T</code> is specified to
be value-initialized, <code>allocate_shared</code> shall perform
this initialization via the expression
<code>allocator_traits&lt;A2&gt;::construct(a2, ptr)</code>, where
<code>ptr</code> points to storage suitable to hold an object
of type <code>T</code> and <code>a2</code> of type A2 is a rebound
copy of the allocator <code>allocator</code> passed to
<code>allocate_shared</code> such that its <code>value_type</code>
is <code>T</code>.</p>
<p>When a subobject of non-array type <code>T</code> is specified to
be default-initialized, <code>make_shared_noinit</code> and
<code>allocate_shared_noinit</code> shall perform this
initialization via the expression <code>::new(ptr) T</code>, where
<code>ptr</code> has type <code>void*</code> and points to storage
suitable to hold an object of type <code>T</code>.</p>
<p>When the lifetime of the object managed by the return value ends,
or when the initialization of an array element throws an exception,
the initialized elements should be destroyed in the reverse order
of their construction.</p>
</blockquote> </blockquote>
<pre>template&lt;typename U, typename... Args&gt; // U = T[] <p><b>Notes:</b> These functions will typically allocate more memory
shared_ptr&lt;U&gt; make_shared(initializer_list&lt;T&gt; list); than <code>sizeof(U)</code> to allow for internal bookkeeping
structures such as the reference counts.</p>
template&lt;typename U, typename A, typename... Args&gt; // U = T[] </blockquote>
shared_ptr&lt;U&gt; allocate_shared(const A&amp; allocator, initializer_list&lt;T&gt; list);</pre> <h2><a name="functions">Free Functions</a></h2>
<pre>template&lt;typename U&gt;
shared_ptr&lt;U&gt; make_shared(size_t size);
template&lt;typename U, typename A&gt;
shared_ptr&lt;U&gt; allocate_shared(const A&amp; allocator, size_t size);</pre>
<blockquote> <blockquote>
<p><b>Description:</b> These overloads initialize the array elements <p><b>Returns:</b> A <code>shared_ptr</code> to a value-initialized
from the initializer list.</p> object of type <code>T[size]</code>.</p>
</blockquote> <p><b>Remarks:</b> These overloads shall only participate in overload
<pre>template&lt;typename U, typename... Args&gt; // U = T[N] resolution when <code>U</code> is of the form <code>T[]</code>.</p>
shared_ptr&lt;U&gt; make_shared(const T (&amp;list)[N]); <p><b>Examples:</b></p>
template&lt;typename U, typename A, typename... Args&gt; // U = T[N]
shared_ptr&lt;U&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 U, typename... Args&gt; // U = T[][N]
shared_ptr&lt;U&gt; make_shared(size_t size, const T (&amp;list)[N]);
template&lt;typename U, typename A, typename... Args&gt; // U = T[][N]
shared_ptr&lt;U&gt; allocate_shared(const A&amp; allocator, size_t size, const T (&amp;list)[N]);</pre>
<blockquote>
<p><b>Description:</b> These overloads initialize inner array elements
from the initializer list.</p>
</blockquote>
<pre>template&lt;typename U, typename... Args&gt; // U = T[M][N]
shared_ptr&lt;U&gt; make_shared(const T (&amp;list)[N]);
template&lt;typename U, typename A, typename... Args&gt; // U = T[M][N]
shared_ptr&lt;U&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 U&gt; // U = T[]
shared_ptr&lt;U&gt; make_shared(size_t size, T&amp;&amp; value);
template&lt;typename U, typename A&gt; // U = T[]
shared_ptr&lt;U&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 U&gt; // U = T[N]
shared_ptr&lt;U&gt; make_shared(T&amp;&amp; value);
template&lt;typename U, typename A&gt; // U = T[N]
shared_ptr&lt;U&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>
</blockquote>
<pre>template&lt;typename U&gt; // U = T[]
shared_ptr&lt;U&gt; make_shared_noinit(size_t size);
template&lt;typename U, typename A&gt; // U = T[]
shared_ptr&lt;U&gt; allocate_shared_noinit(const A&amp; allocator, size_t size);</pre>
<blockquote>
<p><b>Description:</b> These overloads do not perform any value
initialization of elements.</p>
</blockquote>
<pre>template&lt;typename U&gt; // U = T[N]
shared_ptr&lt;U&gt; make_shared_noinit();
template&lt;typename U, typename A&gt; // U = T[N]
shared_ptr&lt;U&gt; allocate_shared_noinit(const A&amp; 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> <blockquote>
<pre>boost::shared_ptr&lt;int[]&gt; a1 = boost::make_shared&lt;int[]&gt;(size); <pre>boost::shared_ptr&lt;int[]&gt; a1 = boost::make_shared&lt;int[]&gt;(size);
boost::shared_ptr&lt;point[]&gt; a2 = boost::make_shared&lt;point[]&gt;(size, x, y); boost::shared_ptr&lt;int[][2]&gt; a2 = boost::make_shared&lt;int[][2]&gt;(size);</pre>
boost::shared_ptr&lt;point[5]&gt; a3 = boost::make_shared&lt;point[5]&gt;(x, y); </blockquote>
boost::shared_ptr&lt;int[]&gt; a4 = boost::make_shared&lt;int[]&gt;({1, 2, 3}); </blockquote>
boost::shared_ptr&lt;int[3]&gt; a5 = boost::make_shared&lt;int[3]&gt;({1, 2, 3}); <pre>template&lt;typename U&gt;
boost::shared_ptr&lt;int[][3]&gt; a6 = boost::make_shared&lt;int[][3]&gt;(size, {1, 2, 3}); shared_ptr&lt;U&gt; make_shared();
boost::shared_ptr&lt;int[5][3]&gt; a7 = boost::make_shared&lt;int[5][3]&gt;({1, 2, 3}); template&lt;typename U, typename A&gt;
boost::shared_ptr&lt;point[]&gt; a8 = boost::make_shared&lt;point[]&gt;(size, {x, y}); shared_ptr&lt;U&gt; allocate_shared(const A&amp; allocator);</pre>
boost::shared_ptr&lt;point[5]&gt; a9 = boost::make_shared&lt;point[5]&gt;({x, y}); <blockquote>
boost::shared_ptr&lt;int[]&gt; a10 = boost::make_shared_noinit&lt;int[]&gt;(size); <p><b>Returns:</b> A <code>shared_ptr</code> to a value-initialized
boost::shared_ptr&lt;int[5]&gt; a11 = boost::make_shared_noinit&lt;int[5]&gt;();</pre> object of type <code>T[N]</code>.</p>
<p><b>Remarks:</b> These overloads shall only participate in overload
resolution when <code>U</code> is of the form <code>T[N]</code>.</p>
<p><b>Examples:</b></p>
<blockquote>
<pre>boost::shared_ptr&lt;int[8]&gt; a1 = boost::make_shared&lt;int[8]&gt;();
boost::shared_ptr&lt;int[4][2]&gt; a2 = boost::make_shared&lt;int[4][2]&gt;();</pre>
</blockquote>
</blockquote>
<pre>template&lt;typename U&gt;
shared_ptr&lt;U&gt; make_shared(size_t size, const T&amp; value);
template&lt;typename U, typename A&gt;
shared_ptr&lt;U&gt; allocate_shared(const A&amp; allocator, size_t size, const T&amp; value);</pre>
<blockquote>
<p><b>Returns:</b> A <code>shared_ptr</code> to an object of type
<code>T[size]</code>, where each array element of type <code>T</code>
is initialized to <code>value</code>.</p>
<p><b>Remarks:</b> These overloads shall only participate in overload
resolution when <code>U</code> is of the form <code>T[]</code>.</p>
<p><b>Examples:</b></p>
<blockquote>
<pre>boost::shared_ptr&lt;int[]&gt; a1 = boost::make_shared&lt;int[]&gt;(size, 1);
boost::shared_ptr&lt;int[][2]&gt; a2 = boost::make_shared&lt;int[][2]&gt;(size, {1, 2});</pre>
</blockquote>
</blockquote>
<pre>template&lt;typename U&gt;
shared_ptr&lt;U&gt; make_shared(const T&amp; value);
template&lt;typename U, typename A&gt;
shared_ptr&lt;U&gt; allocate_shared(const A&amp; allocator, const T&amp; value);</pre>
<blockquote>
<p><b>Returns:</b> A <code>shared_ptr</code> to an object of type
<code>T[N]</code>, where each array element of type <code>T</code> is
initialized to <code>value</code>.</p>
<p><b>Remarks:</b> These overloads shall only participate in overload
resolution when <code>U</code> is of the form <code>T[N]</code>.</p>
<p><b>Examples:</b></p>
<blockquote>
<pre>boost::shared_ptr&lt;int[8]&gt; a1 = boost::make_shared&lt;int[8]&gt;(1);
boost::shared_ptr&lt;int[4][2]&gt; a2 = boost::make_shared&lt;int[4][2]&gt;({1, 2});</pre>
</blockquote>
</blockquote>
<pre>template&lt;typename U&gt;
shared_ptr&lt;U&gt; make_shared_noinit(size_t size);
template&lt;typename U, typename A&gt;
shared_ptr&lt;U&gt; allocate_shared_noinit(const A&amp; allocator, size_t size);</pre>
<blockquote>
<p><b>Returns:</b> A <code>shared_ptr</code> to a default-initialized
object of type <code>T[size]</code>.</p>
<p><b>Remarks:</b> These overloads shall only participate in overload
resolution when <code>U</code> is of the form <code>T[]</code>.</p>
<p><b>Examples:</b></p>
<blockquote>
<pre>boost::shared_ptr&lt;int[]&gt; a1 = boost::make_shared_noinit&lt;int[]&gt;(size);
boost::shared_ptr&lt;int[][2]&gt; a2 = boost::make_shared_noinit&lt;int[][2]&gt;(size);</pre>
</blockquote>
</blockquote>
<pre>template&lt;typename U&gt;
shared_ptr&lt;U&gt; make_shared_noinit();
template&lt;typename U, typename A&gt;
shared_ptr&lt;U&gt; allocate_shared_noinit(const A&amp; allocator);</pre>
<blockquote>
<p><b>Returns:</b> A <code>shared_ptr</code> to a default-initialized
object of type <code>T[N]</code>.</p>
<p><b>Remarks:</b> These overloads shall only participate in overload
resolution when <code>U</code> is of the form <code>T[N]</code>.</p>
<p><b>Examples:</b></p>
<blockquote>
<pre>boost::shared_ptr&lt;int[8]&gt; a1 = boost::make_shared_noinit&lt;int[8]&gt;();
boost::shared_ptr&lt;int[4][2]&gt; a2 = boost::make_shared_noinit&lt;int[4][2]&gt;();</pre>
</blockquote>
</blockquote> </blockquote>
<h2><a name="history">History</a></h2> <h2><a name="history">History</a></h2>
<p>February 2014. Glen Fernandes updated overloads of make_shared and
allocate_shared to conform to the specification in C++ standard paper
<a href="#N3870">N3870</a> including resolving C++ standard library
defect report 2070.</p>
<p>November 2012. Glen Fernandes contributed implementations of <p>November 2012. Glen Fernandes contributed implementations of
make_shared and allocate_shared for arrays.</p> make_shared and allocate_shared for arrays.</p>
<h2><a name="references">References</a></h2>
<p><a name="N3870">N3870</a>,
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3870.html">
Extending make_shared to Support Arrays, Revision 1</a>, Peter Dimov
&amp; Glen Fernandes, January, 2014.</p>
<hr> <hr>
<p>$Date: 2012-10-30 10:12:25 -0800 (Tue, 30 Oct 2012) $</p> <p>$Date$</p>
<p><small>Copyright 2012 Glen Fernandes. Distributed under the Boost <p><small>Copyright 2012-2014 Glen Fernandes. Distributed under the
Software License, Version 1.0. See accompanying file 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="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy at
<A href="http://www.boost.org/LICENSE_1_0.txt"> <a href="http://www.boost.org/LICENSE_1_0.txt">
http://www.boost.org/LICENSE_1_0.txt</A>.</small></p> http://www.boost.org/LICENSE_1_0.txt</a>.</small></p>
</body> </body>
</html> </html>

152
make_unique.html Normal file
View File

@@ -0,0 +1,152 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>make_unique</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_unique</h1>
<p><a href="#introduction">Introduction</a><br>
<a href="#synopsis">Synopsis</a><br>
<a href="#common">Common Requirements</a><br>
<a href="#functions">Free Functions</a><br>
<a href="#history">History</a></p>
<h2><a name="introduction">Introduction</a></h2>
<p>The header file &lt;boost/make_unique.hpp&gt; provides overloaded
function template <code>make_unique</code> for convenient creation of
<code>unique_ptr</code> objects.</p>
<h2><a name="synopsis">Synopsis</a></h2>
<pre>namespace boost {
template&lt;typename U&gt; // U is not array
unique_ptr&lt;U&gt; <a href="#functions">make_unique</a>();
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template&lt;typename U, typename... Args&gt; // U is not array
unique_ptr&lt;U&gt; <a href="#functions">make_unique</a>(Args&amp;&amp;... args);
#endif
template&lt;typename U&gt; // U is not array
unique_ptr&lt;U&gt; <a href="#functions">make_unique</a>(U&amp;&amp; value);
template&lt;typename U&gt; // U is T[]
unique_ptr&lt;U&gt; <a href="#functions">make_unique</a>(size_t size);
template&lt;typename U&gt; // U is not array
unique_ptr&lt;U&gt; <a href="#functions">make_unique_noinit</a>();
template&lt;typename U&gt; // U is T[]
unique_ptr&lt;U&gt; <a href="#functions">make_unique_noinit</a>(size_t size);
}</pre>
<h2><a name="common">Common Requirements</a></h2>
<pre>template&lt;typename U&gt;
unique_ptr&lt;U&gt; make_unique(<em>args</em>);
template&lt;typename U&gt;
unique_ptr&lt;U&gt; make_unique_noinit(<em>args</em>);</pre>
<blockquote>
<p><b>Effects:</b> Allocates memory for an object of type <code>U</code>
(or <code>T[size]</code> when <code>U</code> is <code>T[]</code>,
where <code>size</code> is determined from <code>args</code> as
specified by the concrete overload). The object is initialized from
<code>args</code> as specified by the concrete overload. If an
exception is thrown, the functions have no effect.</p>
<p><b>Returns:</b> A <code>unique_ptr</code> instance that stores and
owns the address of the newly constructed object.</p>
<p><b>Postconditions:</b> <code>r.get() != 0</code>, where
<code>r</code> is the return value.</p>
<p><b>Throws:</b> <code>bad_alloc</code>, or an exception thrown from
the initialization of the object.</p>
<p><b>Remarks:</b></p>
<blockquote>
<p>When an object of a non-array type <code>T</code> is specified to
be initialized to a value <code>value</code>, or to
<code>T(list...)</code>, where <code>list...</code> is a list of
constructor arguments, <code>make_unique</code> shall perform this
initialization via the expression <code>new T(value)</code> or
<code>new T(list...)</code> respectively.</p>
<p>When an object of type <code>T</code> is specified to be
value-initialized, <code>make_unique</code> shall perform this
initialization via the expression <code>new T()</code>.</p>
<p>When an object of type <code>T</code> is specified to be
default-initialized, <code>make_unique_noinit</code> shall perform
this initialization via the expression <code>new T</code>.</p>
</blockquote>
</blockquote>
<h2><a name="functions">Free Functions</a></h2>
<pre>template&lt;typename U, typename... Args&gt;
unique_ptr&lt;U&gt; make_unique(Args&amp;&amp;... args);</pre>
<blockquote>
<p><b>Returns:</b> A unique_ptr to an object of type <code>U</code>,
initialized to <code>U(forward&lt;Args&gt;(args)...)</code>.</p>
<p><b>Remarks:</b> This overload shall only participate in overload
resolution when <code>U</code> is not an array type.</p>
<p><b>Examples:</b></p>
<blockquote>
<pre>unique_ptr&lt;float&gt; p1 = boost::make_unique&lt;float&gt;();
unique_ptr&lt;point&gt; p2 = boost::make_unique&lt;point&gt;(x, y);</pre>
</blockquote>
</blockquote>
<pre>template&lt;typename U&gt;
unique_ptr&lt;U&gt; make_unique(U&amp;&amp; value);</pre>
<blockquote>
<p><b>Returns:</b> A unique_ptr to an object of type <code>U</code>,
initialized to <code>move(value)</code>.</p>
<p><b>Remarks:</b> This overload shall only participate in overload
resolution when <code>U</code> is not an array type.</p>
<p><b>Examples:</b></p>
<blockquote>
<pre>unique_ptr&lt;string&gt; p1 = boost::make_unique&lt;string&gt;({'a', 'b'});
unique_ptr&lt;point&gt; p2 = boost::make_unique&lt;point&gt;({-10, 25});</pre>
</blockquote>
</blockquote>
<pre>template&lt;typename U&gt;
unique_ptr&lt;U&gt; make_unique(size_t size);</pre>
<blockquote>
<p><b>Returns:</b> A unique_ptr to a value-initialized object of type
<code>T[size]</code>.</p>
<p><b>Remarks:</b> This overload shall only participate in overload
resolution when <code>U</code> is of the form <code>T[]</code>.</p>
<p><b>Examples:</b></p>
<blockquote>
<pre>unique_ptr&lt;double[]&gt; p1 = boost::make_unique&lt;double[]&gt;(4);
unique_ptr&lt;int[][2]&gt; p2 = boost::make_unique&lt;int[][2]&gt;(2);</pre>
</blockquote>
</blockquote>
<pre>template&lt;typename U&gt;
unique_ptr&lt;U&gt; make_unique_noinit();</pre>
<blockquote>
<p><b>Returns:</b> A unique_ptr to a default-initialized object of
type <code>U</code>.</p>
<p><b>Remarks:</b> This overload shall only participate in overload
resolution when <code>U</code> is not an array type.</p>
<p><b>Examples:</b></p>
<blockquote>
<pre>unique_ptr&lt;float&gt; p1 = boost::make_unique_noinit&lt;float&gt;();
unique_ptr&lt;point&gt; p2 = boost::make_unique_noinit&lt;point&gt;();</pre>
</blockquote>
</blockquote>
<pre>template&lt;typename U&gt;
unique_ptr&lt;U&gt; make_unique_noinit(size_t size);</pre>
<blockquote>
<p><b>Returns:</b> A unique_ptr to a default-initialized object of
type <code>T[size]</code>.</p>
<p><b>Remarks:</b> This overload shall only participate in overload
resolution when <code>U</code> is of the form <code>T[]</code>.</p>
<p><b>Examples:</b></p>
<blockquote>
<pre>unique_ptr&lt;double[]&gt; p1 = boost::make_unique_noinit&lt;double[]&gt;(4);
unique_ptr&lt;int[][2]&gt; p2 = boost::make_unique_noinit&lt;int[][2]&gt;(2);</pre>
</blockquote>
</blockquote>
<h2><a name="history">History</a></h2>
<p>January 2014. Glen Fernandes contributed implementations of
make_unique for objects and arrays.</p>
<hr>
<p>$Date$</p>
<p><small>Copyright 2012-2014 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>

View File

@@ -1,11 +1,12 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html> <html>
<head> <head>
<title>pointer_cast.hpp</title> <title>pointer_cast</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head> </head>
<body> <body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
<h1><IMG height="86" alt="C++ Boost" src="../../boost.png" width="277" align="middle" border="0">Pointer <h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
cast functions</h1> width="277" align="middle" border="0">pointer_cast</h1>
<p>The pointer cast functions (<code>boost::static_pointer_cast</code> <code>boost::dynamic_pointer_cast</code> <p>The pointer cast functions (<code>boost::static_pointer_cast</code> <code>boost::dynamic_pointer_cast</code>
<code>boost::reinterpret_pointer_cast</code> <code>boost::const_pointer_cast</code>) <code>boost::reinterpret_pointer_cast</code> <code>boost::const_pointer_cast</code>)
provide a way to write generic pointer castings for raw pointers. The functions provide a way to write generic pointer castings for raw pointers. The functions
@@ -97,7 +98,7 @@ int main()
<P>The example demonstrates how the generic pointer casts help us create pointer <P>The example demonstrates how the generic pointer casts help us create pointer
independent code.</P> independent code.</P>
<hr> <hr>
<p>Revised: $Date$</p> <p>$Date$</p>
<p>Copyright 2005 Ion Gazta<74>aga. Use, modification, and distribution are subject to <p>Copyright 2005 Ion Gazta<74>aga. Use, modification, and distribution are subject to
the Boost Software License, Version 1.0. (See accompanying file <A href="../../LICENSE_1_0.txt"> the Boost Software License, Version 1.0. (See accompanying file <A href="../../LICENSE_1_0.txt">
LICENSE_1_0.txt</A> or a copy at &lt;<A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>&gt;.)</p> LICENSE_1_0.txt</A> or a copy at &lt;<A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>&gt;.)</p>

View File

@@ -1,12 +1,12 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html> <html>
<head> <head>
<title>pointer_to_other.hpp</title> <title>pointer_to_other</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head> </head>
<body bgcolor="#ffffff" text="#000000"> <body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
<h1><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" WIDTH="277" HEIGHT="86">Header <h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
<a href="../../boost/pointer_to_other.hpp">boost/pointer_to_other.hpp</a></h1> width="277" align="middle" border="0">pointer_to_other</h1>
<p> <p>
The pointer to other utility provides a way, given a source pointer type, The pointer to other utility provides a way, given a source pointer type,
to obtain a pointer of the same type to another pointee type. The utility is to obtain a pointer of the same type to another pointee type. The utility is
@@ -99,7 +99,7 @@ class memory_allocator
};</pre> };</pre>
<p>As we can see, using pointer_to_other we can create pointer independent code.</p> <p>As we can see, using pointer_to_other we can create pointer independent code.</p>
<hr> <hr>
<p>Last revised: $Date$</p> <p>$Date$</p>
<p><small>Copyright 2005, 2006 Ion Gazta<74>aga and Peter Dimov. Use, modification, <p><small>Copyright 2005, 2006 Ion Gazta<74>aga and Peter Dimov. Use, modification,
and distribution are subject to the Boost Software License, Version 1.0.<br> and distribution are subject to the Boost Software License, Version 1.0.<br>
(See accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or a (See accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or a

View File

@@ -1,12 +1,12 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html> <html>
<head> <head>
<title>scoped_array</title> <title>scoped_array</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head> </head>
<body bgcolor="#ffffff" text="#000000"> <body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
<h1><A href="../../index.htm"><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="277" height="86" <h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
border="0"></A>scoped_array class template</h1> width="277" align="middle" border="0">scoped_array class template</h1>
<p>The <b>scoped_array</b> class template stores a pointer to a dynamically <p>The <b>scoped_array</b> class template stores a pointer to a dynamically
allocated array. (Dynamically allocated arrays are allocated with the C++ <b>new[]</b> allocated array. (Dynamically allocated arrays are allocated with the C++ <b>new[]</b>
expression.) The array pointed to is guaranteed to be deleted, either on expression.) The array pointed to is guaranteed to be deleted, either on
@@ -106,8 +106,7 @@
<p>Equivalent to <b>a.swap(b)</b>. Matches the interface of <b>std::swap</b>. <p>Equivalent to <b>a.swap(b)</b>. Matches the interface of <b>std::swap</b>.
Provided as an aid to generic programming.</p> Provided as an aid to generic programming.</p>
<hr> <hr>
<p>Revised <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan--> <p>$Date$</p>
09 January 2003<!--webbot bot="Timestamp" endspan i-checksum="32310"--></p>
<p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. <p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
Copyright 2002-2005 Peter Dimov. Distributed under the Boost Software License, Version Copyright 2002-2005 Peter Dimov. Distributed under the Boost Software License, Version
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or 1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or

View File

@@ -1,12 +1,12 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html> <html>
<head> <head>
<title>scoped_ptr</title> <title>scoped_ptr</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head> </head>
<body bgcolor="#ffffff" text="#000000"> <body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
<h1><A href="../../index.htm"><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="277" height="86" <h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
border="0"></A>scoped_ptr class template</h1> width="277" align="middle" border="0">scoped_ptr class template</h1>
<p>The <b>scoped_ptr</b> class template stores a pointer to a dynamically allocated <p>The <b>scoped_ptr</b> class template stores a pointer to a dynamically allocated
object. (Dynamically allocated objects are allocated with the C++ <b>new</b> expression.) object. (Dynamically allocated objects are allocated with the C++ <b>new</b> expression.)
The object pointed to is guaranteed to be deleted, either on destruction of the <b>scoped_ptr</b>, The object pointed to is guaranteed to be deleted, either on destruction of the <b>scoped_ptr</b>,
@@ -171,8 +171,7 @@ Buckle my shoe</pre>
given context. Use <STRONG>std::auto_ptr</STRONG> where transfer of ownership given context. Use <STRONG>std::auto_ptr</STRONG> where transfer of ownership
is required. (supplied by Dave Abrahams)</p> is required. (supplied by Dave Abrahams)</p>
<hr> <hr>
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B %Y" startspan --> <p>$Date</p>
09 January 2003<!--webbot bot="Timestamp" endspan i-checksum="32310" --></p>
<p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. <p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
Copyright 2002-2005 Peter Dimov. Distributed under the Boost Software License, Version Copyright 2002-2005 Peter Dimov. Distributed under the Boost Software License, Version
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or 1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or

View File

@@ -1,12 +1,12 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html> <html>
<head> <head>
<title>shared_array</title> <title>shared_array</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head> </head>
<body bgcolor="#ffffff" text="#000000"> <body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
<h1><A href="../../index.htm"><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="277" height="86" <h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
border="0"></A>shared_array class template</h1> width="277" align="middle" border="0">shared_array class template</h1>
<p>The <b>shared_array</b> class template stores a pointer to a dynamically <p>The <b>shared_array</b> class template stores a pointer to a dynamically
allocated array. (Dynamically allocated array are allocated with the C++ <b>new[]</b> allocated array. (Dynamically allocated array are allocated with the C++ <b>new[]</b>
expression.) The object pointed to is guaranteed to be deleted when the last <b>shared_array</b> expression.) The object pointed to is guaranteed to be deleted when the last <b>shared_array</b>
@@ -174,9 +174,7 @@ template&lt;class T&gt;
<p>Equivalent to <b>a.swap(b)</b>. Matches the interface of <b>std::swap</b>. <p>Equivalent to <b>a.swap(b)</b>. Matches the interface of <b>std::swap</b>.
Provided as an aid to generic programming.</p> Provided as an aid to generic programming.</p>
<hr> <hr>
<p>Revised <p>$Date$</p>
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan -->
09 January 2003<!--webbot bot="Timestamp" endspan i-checksum="32310" --></p>
<p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. <p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
Copyright 2002-2005 Peter Dimov. Distributed under the Boost Software License, Version Copyright 2002-2005 Peter Dimov. Distributed under the Boost Software License, Version
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or 1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or

View File

@@ -1,28 +1,29 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html> <html>
<head> <head>
<title>shared_ptr</title> <title>shared_ptr</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head> </head>
<body> <body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
<h1>boost::shared_ptr class template</h1> <h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
<p><a href="#Introduction">Introduction</a><br /> width="277" align="middle" border="0">shared_ptr class template</h1>
<a href="#BestPractices">Best Practices</a><br /> <p><a href="#Introduction">Introduction</a><br>
<a href="#Synopsis">Synopsis</a><br /> <a href="#BestPractices">Best Practices</a><br>
<a href="#Members">Members</a><br /> <a href="#Synopsis">Synopsis</a><br>
<a href="#functions">Free Functions</a><br /> <a href="#Members">Members</a><br>
<a href="#example">Example</a><br /> <a href="#functions">Free Functions</a><br>
<a href="#HandleBody">Handle/Body Idiom</a><br /> <a href="#example">Example</a><br>
<a href="#ThreadSafety">Thread Safety</a><br /> <a href="#HandleBody">Handle/Body Idiom</a><br>
<a href="#FAQ">Frequently Asked Questions</a><br /> <a href="#ThreadSafety">Thread Safety</a><br>
<a href="smarttests.htm">Smart Pointer Timings</a><br /> <a href="#FAQ">Frequently Asked Questions</a><br>
<a href="smarttests.htm">Smart Pointer Timings</a><br>
<a href="sp_techniques.html">Programming Techniques</a></p> <a href="sp_techniques.html">Programming Techniques</a></p>
<h2 id="Introduction">Introduction</h2> <h2 id="Introduction">Introduction</h2>
<p>The <code>shared_ptr</code> class template stores a pointer to a dynamically allocated <p>The <code>shared_ptr</code> class template stores a pointer to a dynamically allocated
object, typically with a C++ <em>new-expression</em>. The object pointed to is object, typically with a C++ <em>new-expression</em>. The object pointed to is
guaranteed to be deleted when the last <code>shared_ptr</code> pointing to it is guaranteed to be deleted when the last <code>shared_ptr</code> pointing to it is
destroyed or reset.</p> destroyed or reset.</p>
<blockquote><em>Example:</em><br /><pre>shared_ptr&lt;X&gt; p1( new X ); <blockquote><em>Example:</em><br><pre>shared_ptr&lt;X&gt; p1( new X );
shared_ptr&lt;void&gt; p2( new int(5) ); shared_ptr&lt;void&gt; p2( new int(5) );
</pre></blockquote> </pre></blockquote>
@@ -61,7 +62,7 @@ shared_ptr&lt;void&gt; p2( new int(5) );
the template parameter. There is almost no difference between using an unsized array, <code>T[]</code>, the template parameter. There is almost no difference between using an unsized array, <code>T[]</code>,
and a sized array, <code>T[N]</code>; the latter just enables <code>operator[]</code> to perform a range check and a sized array, <code>T[N]</code>; the latter just enables <code>operator[]</code> to perform a range check
on the index.</p> on the index.</p>
<blockquote><em>Example:</em><br /><pre>shared_ptr&lt;double[1024]&gt; p1( new double[1024] ); <blockquote><em>Example:</em><br><pre>shared_ptr&lt;double[1024]&gt; p1( new double[1024] );
shared_ptr&lt;double[]&gt; p2( new double[n] ); shared_ptr&lt;double[]&gt; p2( new double[n] );
</pre></blockquote> </pre></blockquote>
@@ -835,7 +836,8 @@ int * p = a.release();
object through it. <code>shared_ptr</code> is "as close to raw pointers as possible object through it. <code>shared_ptr</code> is "as close to raw pointers as possible
but no closer". but no closer".
</p> </p>
<hr /> <hr>
<p>$Date$</p>
<p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. <p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
Copyright 2002-2005, 2012, 2013 Peter Dimov. Distributed under the Boost Software License, Copyright 2002-2005, 2012, 2013 Peter Dimov. Distributed under the Boost Software License,
Version 1.0. See accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> Version 1.0. See accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a>

View File

@@ -4,9 +4,9 @@
<title>Smart Pointers</title> <title>Smart Pointers</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head> </head>
<body bgcolor="#ffffff" text="#000000"> <body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
<h1><A href="../../index.htm"><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="277" height="86" <h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
border="0"></A>Smart Pointers</h1> width="277" align="middle" border="0">Smart Pointers</h1>
<p><a href="#Introduction">Introduction</a><br> <p><a href="#Introduction">Introduction</a><br>
<a href="#common_requirements">Common Requirements</a><br> <a href="#common_requirements">Common Requirements</a><br>
<a href="#Exception_Safety">Exception Safety</a><br> <a href="#Exception_Safety">Exception Safety</a><br>
@@ -62,19 +62,24 @@
described in Bjarne Stroustrup's "The C++ Programming Language", 3rd edition, described in Bjarne Stroustrup's "The C++ Programming Language", 3rd edition,
Section 14.4, Resource Management.</p> Section 14.4, Resource Management.</p>
<p>Additionally, the smart pointer library provides efficient factory functions <p>Additionally, the smart pointer library provides efficient factory functions
for creating <code>shared_ptr</code> objects:</p> for creating smart pointer objects:</p>
<div align="left"> <div align="left">
<table border="1" cellpadding="4" cellspacing="0"> <table border="1" cellpadding="4" cellspacing="0">
<tr> <tr>
<td><a href="make_shared.html"><b>make_shared and allocate_shared</b></a></td> <td><a href="make_shared.html"><b>make_shared, allocate_shared</b></a> for objects</td>
<td><a href="../../boost/make_shared.hpp">&lt;boost/make_shared.hpp&gt;</a></td> <td><a href="../../boost/make_shared.hpp">&lt;boost/make_shared.hpp&gt;</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> <tr>
<td><a href="make_shared_array.html"><b>make_shared and allocate_shared for arrays</b></a></td> <td><a href="make_shared_array.html"><b>make_shared, allocate_shared</b></a> for arrays</td>
<td><a href="../../boost/make_shared.hpp">&lt;boost/make_shared.hpp&gt;</a></td> <td><a href="../../boost/make_shared.hpp">&lt;boost/make_shared.hpp&gt;</a></td>
<td>Efficient creation of <code>shared_ptr</code> arrays.</td> <td>Efficient creation of <code>shared_ptr</code> arrays.</td>
</tr> </tr>
<tr>
<td><a href="make_unique.html"><b>make_unique</b></a></td>
<td><a href="../../boost/make_unique.hpp">&lt;boost/make_unique.hpp&gt;</a></td>
<td>Creation of <code>unique_ptr</code> objects and 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
@@ -131,6 +136,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>February 2014. Glen Fernandes updated overloads of <b>make_shared</b> and
<b>allocate_shared</b> to conform to the specification in C++ standard paper
<a href="#D&amp;F-14">[D&amp;F-14]</a>, and implemented <b>make_unique</b> for
arrays and objects. Peter Dimov and Glen Fernandes updated the scalar and
array implementations, respectively, to resolve C++ standard library defect
2070.</p>
<p>November 2012. Glen Fernandes provided implementations of <b>make_shared</b> <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 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 array that can be initialized with constructor arguments or initializer lists
@@ -190,6 +201,9 @@
the full committee, <b>counted_ptr</b> was rejected and surprising the full committee, <b>counted_ptr</b> was rejected and surprising
transfer-of-ownership semantics were added to <b>auto_ptr</b>.</p> transfer-of-ownership semantics were added to <b>auto_ptr</b>.</p>
<h2><a name="References">References</a></h2> <h2><a name="References">References</a></h2>
<p>[<a name="D&amp;F-14">D&amp;F-14</a>] Peter Dimov &amp; Glen Fernandes, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3870.html">
Extending make_shared to Support Arrays, Revision 1</a>, C++ committee document N3870,
January, 2014.</p>
<p>[<a name="Col-94">Col-94</a>] Gregory Colvin, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1994/N0555.pdf"> <p>[<a name="Col-94">Col-94</a>] Gregory Colvin, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1994/N0555.pdf">
Exception Safe Smart Pointers</a>, C++ committee document 94-168/N0555, Exception Safe Smart Pointers</a>, C++ committee document 94-168/N0555,
July, 1994.</p> July, 1994.</p>

View File

@@ -7,9 +7,9 @@
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head> </head>
<body bgcolor="#FFFFFF"> <body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
<h1><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" WIDTH="277" HEIGHT="86">Smart Pointer Timings</h1> <h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png" width="277" align="middle" border="0">Smart Pointer Timings</h1>
<p>In late January 2000, Mark Borgerding put forward a suggestion to boost for <p>In late January 2000, Mark Borgerding put forward a suggestion to boost for
a new design of smart pointer whereby an intrusive doubly linked list is used a new design of smart pointer whereby an intrusive doubly linked list is used
@@ -533,9 +533,8 @@ Gavin Collings,
spreads its information as in the case of linked pointer.</li> spreads its information as in the case of linked pointer.</li>
</ul> </ul>
<hr> <hr>
<p>Revised <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan -->19 August 2001<!--webbot bot="Timestamp" endspan i-checksum="14767" --> <p>$Date$</p>
</p> <p>&copy; Copyright Gavin Collings 2000. Permission to copy, use, modify, sell
<p><EFBFBD> Copyright Gavin Collings 2000. Permission to copy, use, modify, sell
and distribute this document is granted provided this copyright notice appears in all and distribute this document is granted provided this copyright notice appears in all
copies. This document is provided &quot;as is&quot; without express or implied warranty, copies. This document is provided &quot;as is&quot; without express or implied warranty,
and with no claim as to its suitability for any purpose.</p> and with no claim as to its suitability for any purpose.</p>

View File

@@ -1,12 +1,12 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html> <html>
<head> <head>
<title>Smart Pointer Programming Techniques</title> <title>Smart Pointer Programming Techniques</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head> </head>
<body text="#000000" bgColor="#ffffff"> <body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
<h1><A href="../../index.htm"><IMG height="86" alt="boost.png (6897 bytes)" src="../../boost.png" width="277" align="middle" <h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
border="0"></A>Smart Pointer Programming Techniques</h1> width="277" align="middle" border="0">Smart Pointer Programming Techniques</h1>
<p><A href="#incomplete">Using incomplete classes for implementation hiding</A><br> <p><A href="#incomplete">Using incomplete classes for implementation hiding</A><br>
<A href="#pimpl">The "Pimpl" idiom</A><br> <A href="#pimpl">The "Pimpl" idiom</A><br>
<A href="#abstract">Using abstract classes for implementation hiding</A><br> <A href="#abstract">Using abstract classes for implementation hiding</A><br>
@@ -758,7 +758,7 @@ public:
all weak pointers will automatically expire.</p> all weak pointers will automatically expire.</p>
<hr> <hr>
<p>$Date$</p> <p>$Date$</p>
<p><small>Copyright <EFBFBD> 2003 Peter Dimov. Distributed under the Boost Software License, Version <p><small>Copyright &copy; 2003 Peter Dimov. Distributed under the Boost Software License, Version
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or 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> copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
</body> </body>

View File

@@ -1,6 +1,6 @@
# Boost.SmartPtr Library test Jamfile # Boost.SmartPtr Library test Jamfile
# #
# Copyright (c) 2003-2007 Peter Dimov # Copyright (c) 2003-2013 Peter Dimov
# Copyright (c) 2003 Dave Abrahams # Copyright (c) 2003 Dave Abrahams
# #
# Distributed under the Boost Software License, Version 1.0. (See # Distributed under the Boost Software License, Version 1.0. (See
@@ -78,6 +78,11 @@ import testing ;
[ run sp_array_cast_test.cpp ] [ run sp_array_cast_test.cpp ]
[ run sp_zero_compare_test.cpp ] [ run sp_zero_compare_test.cpp ]
[ run sp_nullptr_test.cpp ] [ run sp_nullptr_test.cpp ]
[ run sa_nullptr_test.cpp ]
[ run shared_ptr_alloc3_test.cpp ]
[ run shared_ptr_alloc11_test.cpp ]
[ run allocate_shared_alloc11_test.cpp ]
[ run allocate_shared_construct11_test.cpp ]
[ compile-fail array_fail_spa_sp_c.cpp ] [ compile-fail array_fail_spa_sp_c.cpp ]
[ compile-fail array_fail_sp_spa_c.cpp ] [ compile-fail array_fail_sp_spa_c.cpp ]
@@ -136,22 +141,26 @@ import testing ;
[ compile-fail array_fail_array_access.cpp ] [ compile-fail array_fail_array_access.cpp ]
[ run make_shared_array_test.cpp ] [ run make_shared_array_test.cpp ]
[ run make_shared_arrays_test.cpp ] [ run make_shared_arrays_test.cpp : : : <toolset>gcc-4.6.3_0x:<cxxflags>-fno-deduce-init-list ]
[ 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_throws_test.cpp ]
[ run make_shared_array_esft_test.cpp ] [ run make_shared_array_esft_test.cpp ]
[ run make_shared_array_args_test.cpp ] [ run make_shared_array_noinit_test.cpp ]
[ run make_shared_array_value_test.cpp ]
[ run allocate_shared_array_test.cpp ] [ run allocate_shared_array_test.cpp ]
[ run allocate_shared_arrays_test.cpp ] [ run allocate_shared_arrays_test.cpp : : : <toolset>gcc-4.6.3_0x:<cxxflags>-fno-deduce-init-list ]
[ 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_throws_test.cpp ]
[ run allocate_shared_array_esft_test.cpp ] [ run allocate_shared_array_esft_test.cpp ]
[ run allocate_shared_array_args_test.cpp ] [ run allocate_shared_array_noinit_test.cpp ]
[ run allocate_shared_array_value_test.cpp ]
[ run allocate_shared_array_construct_test.cpp ]
[ run make_unique_test.cpp ]
[ run make_unique_args_test.cpp ]
[ run make_unique_value_test.cpp ]
[ run make_unique_noinit_test.cpp ]
[ run make_unique_throws_test.cpp ]
[ run make_unique_array_test.cpp ]
[ run make_unique_array_noinit_test.cpp ]
[ run make_unique_array_throws_test.cpp ]
; ;
} }

View File

@@ -0,0 +1,241 @@
// allocate_shared_alloc11_test.cpp
//
// allocate_shared with a minimal C++11 allocator
//
// Copyright 2007-2009, 2014 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 <boost/weak_ptr.hpp>
#include <boost/config.hpp>
#include <cstddef>
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
template< class T > class cxx11_allocator
{
public:
typedef T value_type;
cxx11_allocator()
{
}
template< class Y > cxx11_allocator( cxx11_allocator<Y> const & )
{
}
T * allocate( std::size_t n )
{
return static_cast< T* >( ::operator new( n * sizeof( T ) ) );
}
void deallocate( T * p, std::size_t n )
{
::operator delete( p );
}
};
class X
{
private:
X( X const & );
X & operator=( X const & );
void * operator new( std::size_t n )
{
BOOST_ERROR( "private X::new called" );
return ::operator new( n );
}
void operator delete( void * p )
{
BOOST_ERROR( "private X::delete called" );
::operator delete( 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::shared_ptr< int > pi = boost::allocate_shared< int >( cxx11_allocator<int>() );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( *pi == 0 );
}
{
boost::shared_ptr< int > pi = boost::allocate_shared< int >( cxx11_allocator<int>(), 5 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( *pi == 5 );
}
BOOST_TEST( X::instances == 0 );
{
boost::shared_ptr< X > pi = boost::allocate_shared< X >( cxx11_allocator<void>() );
boost::weak_ptr<X> wp( pi );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( pi->v == 0 );
pi.reset();
BOOST_TEST( X::instances == 0 );
}
{
boost::shared_ptr< X > pi = boost::allocate_shared< X >( cxx11_allocator<void>(), 1 );
boost::weak_ptr<X> wp( pi );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( pi->v == 1 );
pi.reset();
BOOST_TEST( X::instances == 0 );
}
{
boost::shared_ptr< X > pi = boost::allocate_shared< X >( cxx11_allocator<void>(), 1, 2 );
boost::weak_ptr<X> wp( pi );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( pi->v == 1+2 );
pi.reset();
BOOST_TEST( X::instances == 0 );
}
{
boost::shared_ptr< X > pi = boost::allocate_shared< X >( cxx11_allocator<void>(), 1, 2, 3 );
boost::weak_ptr<X> wp( pi );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( pi->v == 1+2+3 );
pi.reset();
BOOST_TEST( X::instances == 0 );
}
{
boost::shared_ptr< X > pi = boost::allocate_shared< X >( cxx11_allocator<void>(), 1, 2, 3, 4 );
boost::weak_ptr<X> wp( pi );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( pi->v == 1+2+3+4 );
pi.reset();
BOOST_TEST( X::instances == 0 );
}
{
boost::shared_ptr< X > pi = boost::allocate_shared< X >( cxx11_allocator<void>(), 1, 2, 3, 4, 5 );
boost::weak_ptr<X> wp( pi );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( pi->v == 1+2+3+4+5 );
pi.reset();
BOOST_TEST( X::instances == 0 );
}
{
boost::shared_ptr< X > pi = boost::allocate_shared< X >( cxx11_allocator<void>(), 1, 2, 3, 4, 5, 6 );
boost::weak_ptr<X> wp( pi );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( pi->v == 1+2+3+4+5+6 );
pi.reset();
BOOST_TEST( X::instances == 0 );
}
{
boost::shared_ptr< X > pi = boost::allocate_shared< X >( cxx11_allocator<void>(), 1, 2, 3, 4, 5, 6, 7 );
boost::weak_ptr<X> wp( pi );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( pi->v == 1+2+3+4+5+6+7 );
pi.reset();
BOOST_TEST( X::instances == 0 );
}
{
boost::shared_ptr< X > pi = boost::allocate_shared< X >( cxx11_allocator<void>(), 1, 2, 3, 4, 5, 6, 7, 8 );
boost::weak_ptr<X> wp( pi );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( pi->v == 1+2+3+4+5+6+7+8 );
pi.reset();
BOOST_TEST( X::instances == 0 );
}
{
boost::shared_ptr< X > pi = boost::allocate_shared< X >( cxx11_allocator<void>(), 1, 2, 3, 4, 5, 6, 7, 8, 9 );
boost::weak_ptr<X> wp( pi );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( pi->v == 1+2+3+4+5+6+7+8+9 );
pi.reset();
BOOST_TEST( X::instances == 0 );
}
return boost::report_errors();
}
#else // !defined( BOOST_NO_CXX11_ALLOCATOR )
int main()
{
return 0;
}
#endif

View File

@@ -1,173 +0,0 @@
// 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();
}

View File

@@ -0,0 +1,167 @@
/*
* Copyright (c) 2012-2014 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>
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
#include <boost/smart_ptr/allocate_shared_array.hpp>
template<typename T>
class creator {
public:
typedef T value_type;
#if defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
template<typename U>
struct rebind {
typedef creator<U> other;
};
#endif
creator() {
}
template<typename U>
creator(const creator<U>&) {
}
T* allocate(std::size_t size) {
void* p1 = ::operator new(size * sizeof(T));
return static_cast<T*>(p1);
}
void deallocate(T* memory, std::size_t) {
void* p1 = memory;
::operator delete(p1);
}
template<typename U>
void construct(U* memory) {
void* p1 = memory;
::new(p1) U();
}
template<typename U>
void destroy(U* memory) {
memory->~U();
}
};
class type {
friend class creator<type>;
public:
static unsigned int instances;
static const type object;
protected:
explicit type() {
instances++;
}
type(const type&) {
instances++;
}
~type() {
instances--;
}
};
unsigned int type::instances;
const type type::object;
int main() {
BOOST_TEST(type::instances == 1);
{
boost::shared_ptr<type[]> a1 = boost::allocate_shared<type[]>(creator<void>(), 3);
BOOST_TEST(a1.use_count() == 1);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(type::instances == 4);
a1.reset();
BOOST_TEST(type::instances == 1);
}
BOOST_TEST(type::instances == 1);
{
boost::shared_ptr<type[3]> a1 = boost::allocate_shared<type[3]>(creator<void>());
BOOST_TEST(a1.use_count() == 1);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(type::instances == 4);
a1.reset();
BOOST_TEST(type::instances == 1);
}
BOOST_TEST(type::instances == 1);
{
boost::shared_ptr<type[][2]> a1 = boost::allocate_shared<type[][2]>(creator<void>(), 2);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1.use_count() == 1);
BOOST_TEST(type::instances == 5);
a1.reset();
BOOST_TEST(type::instances == 1);
}
BOOST_TEST(type::instances == 1);
{
boost::shared_ptr<type[2][2]> a1 = boost::allocate_shared<type[2][2]>(creator<void>());
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1.use_count() == 1);
BOOST_TEST(type::instances == 5);
a1.reset();
BOOST_TEST(type::instances == 1);
}
BOOST_TEST(type::instances == 1);
{
boost::shared_ptr<const type[]> a1 = boost::allocate_shared<const type[]>(creator<void>(), 3);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1.use_count() == 1);
BOOST_TEST(type::instances == 4);
a1.reset();
BOOST_TEST(type::instances == 1);
}
BOOST_TEST(type::instances == 1);
{
boost::shared_ptr<const type[3]> a1 = boost::allocate_shared<const type[3]>(creator<void>());
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1.use_count() == 1);
BOOST_TEST(type::instances == 4);
a1.reset();
BOOST_TEST(type::instances == 1);
}
BOOST_TEST(type::instances == 1);
{
boost::shared_ptr<const type[][2]> a1 = boost::allocate_shared<const type[][2]>(creator<void>(), 2);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1.use_count() == 1);
BOOST_TEST(type::instances == 5);
a1.reset();
BOOST_TEST(type::instances == 1);
}
BOOST_TEST(type::instances == 1);
{
boost::shared_ptr<const type[2][2]> a1 = boost::allocate_shared<const type[2][2]>(creator<void>());
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1.use_count() == 1);
BOOST_TEST(type::instances == 5);
a1.reset();
BOOST_TEST(type::instances == 1);
}
return boost::report_errors();
}
#else
int main() {
return 0;
}
#endif

View File

@@ -1,114 +0,0 @@
/*
* 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();
}

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012 Glen Joseph Fernandes * Copyright (c) 2012-2014 Glen Joseph Fernandes
* glenfe at live dot com * glenfe at live dot com
* *
* Distributed under the Boost Software License, * Distributed under the Boost Software License,
@@ -14,12 +14,15 @@ class type
: public boost::enable_shared_from_this<type> { : public boost::enable_shared_from_this<type> {
public: public:
static unsigned int instances; static unsigned int instances;
explicit type() { explicit type() {
instances++; instances++;
} }
~type() { ~type() {
instances--; instances--;
} }
private: private:
type(const type&); type(const type&);
type& operator=(const type&); type& operator=(const type&);
@@ -38,6 +41,7 @@ int main() {
BOOST_TEST(type::instances == 3); BOOST_TEST(type::instances == 3);
} }
} }
BOOST_TEST(type::instances == 0); BOOST_TEST(type::instances == 0);
{ {
boost::shared_ptr<type[]> a1 = boost::allocate_shared_noinit<type[]>(std::allocator<type>(), 3); boost::shared_ptr<type[]> a1 = boost::allocate_shared_noinit<type[]>(std::allocator<type>(), 3);
@@ -48,5 +52,6 @@ int main() {
BOOST_TEST(type::instances == 3); BOOST_TEST(type::instances == 3);
} }
} }
return boost::report_errors(); return boost::report_errors();
} }

View File

@@ -1,84 +0,0 @@
/*
* 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();
}

View File

@@ -0,0 +1,181 @@
/*
* Copyright (c) 2012-2014 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() {
instances++;
}
~type() {
instances--;
}
private:
type(const type&);
type& operator=(const type&);
};
unsigned int type::instances = 0;
int main() {
{
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<int[][2]> a1 = boost::allocate_shared_noinit<int[][2]>(std::allocator<int>(), 2);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1.use_count() == 1);
}
{
boost::shared_ptr<int[2][2]> a1 = boost::allocate_shared_noinit<int[2][2]>(std::allocator<int>());
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1.use_count() == 1);
}
{
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::shared_ptr<const int[][2]> a1 = boost::allocate_shared_noinit<const int[][2]>(std::allocator<int>(), 2);
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>());
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1.use_count() == 1);
}
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<type[][2]> a1 = boost::allocate_shared_noinit<type[][2]>(std::allocator<type>(), 2);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1.use_count() == 1);
BOOST_TEST(type::instances == 4);
a1.reset();
BOOST_TEST(type::instances == 0);
}
BOOST_TEST(type::instances == 0);
{
boost::shared_ptr<type[2][2]> a1 = boost::allocate_shared_noinit<type[2][2]>(std::allocator<type>());
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1.use_count() == 1);
BOOST_TEST(type::instances == 4);
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);
}
BOOST_TEST(type::instances == 0);
{
boost::shared_ptr<const type[][2]> a1 = boost::allocate_shared_noinit<const type[][2]>(std::allocator<type>(), 2);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1.use_count() == 1);
BOOST_TEST(type::instances == 4);
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>());
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1.use_count() == 1);
BOOST_TEST(type::instances == 4);
a1.reset();
BOOST_TEST(type::instances == 0);
}
return boost::report_errors();
}

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012 Glen Joseph Fernandes * Copyright (c) 2012-2014 Glen Joseph Fernandes
* glenfe at live dot com * glenfe at live dot com
* *
* Distributed under the Boost Software License, * Distributed under the Boost Software License,
@@ -14,17 +14,18 @@
class type { class type {
public: public:
static unsigned int instances; static unsigned int instances;
explicit type(int = 0, int = 0)
: member() { explicit type() {
instances++; instances++;
} }
~type() { ~type() {
instances--; instances--;
} }
private: private:
type(const type&); type(const type&);
type& operator=(const type&); type& operator=(const type&);
double member;
}; };
unsigned int type::instances = 0; unsigned int type::instances = 0;
@@ -40,6 +41,38 @@ int main() {
BOOST_TEST(a1[1] == 0); BOOST_TEST(a1[1] == 0);
BOOST_TEST(a1[2] == 0); BOOST_TEST(a1[2] == 0);
} }
{
boost::shared_ptr<int[3]> a1 = boost::allocate_shared<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_TEST(a1[0] == 0);
BOOST_TEST(a1[1] == 0);
BOOST_TEST(a1[2] == 0);
}
{
boost::shared_ptr<int[][2]> a1 = boost::allocate_shared<int[][2]>(std::allocator<int>(), 2);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1.use_count() == 1);
BOOST_TEST(a1[0][0] == 0);
BOOST_TEST(a1[0][1] == 0);
BOOST_TEST(a1[1][0] == 0);
BOOST_TEST(a1[1][1] == 0);
}
{
boost::shared_ptr<int[2][2]> a1 = boost::allocate_shared<int[2][2]>(std::allocator<int>());
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1.use_count() == 1);
BOOST_TEST(a1[0][0] == 0);
BOOST_TEST(a1[0][1] == 0);
BOOST_TEST(a1[1][0] == 0);
BOOST_TEST(a1[1][1] == 0);
}
{ {
boost::shared_ptr<const int[]> a1 = boost::allocate_shared<const int[]>(std::allocator<int>(), 3); boost::shared_ptr<const int[]> a1 = boost::allocate_shared<const int[]>(std::allocator<int>(), 3);
const int* a2 = a1.get(); const int* a2 = a1.get();
@@ -50,6 +83,38 @@ int main() {
BOOST_TEST(a1[1] == 0); BOOST_TEST(a1[1] == 0);
BOOST_TEST(a1[2] == 0); BOOST_TEST(a1[2] == 0);
} }
{
boost::shared_ptr<const int[3]> a1 = boost::allocate_shared<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(a1[0] == 0);
BOOST_TEST(a1[1] == 0);
BOOST_TEST(a1[2] == 0);
}
{
boost::shared_ptr<const int[][2]> a1 = boost::allocate_shared<const int[][2]>(std::allocator<int>(), 2);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1.use_count() == 1);
BOOST_TEST(a1[0][0] == 0);
BOOST_TEST(a1[0][1] == 0);
BOOST_TEST(a1[1][0] == 0);
BOOST_TEST(a1[1][1] == 0);
}
{
boost::shared_ptr<const int[2][2]> a1 = boost::allocate_shared<const int[2][2]>(std::allocator<int>());
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1.use_count() == 1);
BOOST_TEST(a1[0][0] == 0);
BOOST_TEST(a1[0][1] == 0);
BOOST_TEST(a1[1][0] == 0);
BOOST_TEST(a1[1][1] == 0);
}
BOOST_TEST(type::instances == 0); BOOST_TEST(type::instances == 0);
{ {
boost::shared_ptr<type[]> a1 = boost::allocate_shared<type[]>(std::allocator<type>(), 3); boost::shared_ptr<type[]> a1 = boost::allocate_shared<type[]>(std::allocator<type>(), 3);
@@ -62,6 +127,40 @@ int main() {
a1.reset(); a1.reset();
BOOST_TEST(type::instances == 0); BOOST_TEST(type::instances == 0);
} }
BOOST_TEST(type::instances == 0);
{
boost::shared_ptr<type[3]> a1 = boost::allocate_shared<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<type[][2]> a1 = boost::allocate_shared<type[][2]>(std::allocator<type>(), 2);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1.use_count() == 1);
BOOST_TEST(type::instances == 4);
a1.reset();
BOOST_TEST(type::instances == 0);
}
BOOST_TEST(type::instances == 0);
{
boost::shared_ptr<type[2][2]> a1 = boost::allocate_shared<type[2][2]>(std::allocator<type>());
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1.use_count() == 1);
BOOST_TEST(type::instances == 4);
a1.reset();
BOOST_TEST(type::instances == 0);
}
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); boost::shared_ptr<const type[]> a1 = boost::allocate_shared<const type[]>(std::allocator<type>(), 3);
@@ -73,34 +172,10 @@ int main() {
a1.reset(); a1.reset();
BOOST_TEST(type::instances == 0); BOOST_TEST(type::instances == 0);
} }
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
BOOST_TEST(type::instances == 0); BOOST_TEST(type::instances == 0);
{ {
boost::shared_ptr<type[]> a1 = boost::allocate_shared<type[]>(std::allocator<type>(), 3, 1, 5); boost::shared_ptr<const type[3]> a1 = boost::allocate_shared<const 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[]> 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(); const type* a2 = a1.get();
BOOST_TEST(a1.use_count() == 1); BOOST_TEST(a1.use_count() == 1);
BOOST_TEST(a2 != 0); BOOST_TEST(a2 != 0);
@@ -109,91 +184,26 @@ int main() {
a1.reset(); a1.reset();
BOOST_TEST(type::instances == 0); BOOST_TEST(type::instances == 0);
} }
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); boost::shared_ptr<const type[][2]> a1 = boost::allocate_shared<const type[][2]>(std::allocator<type>(), 2);
const type* a2 = a1.get(); BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1.use_count() == 1); BOOST_TEST(a1.use_count() == 1);
BOOST_TEST(a2 != 0); BOOST_TEST(type::instances == 4);
BOOST_TEST(size_t(a2) % boost::alignment_of<type>::value == 0);
BOOST_TEST(type::instances == 3);
a1.reset(); a1.reset();
BOOST_TEST(type::instances == 0); 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_TEST(type::instances == 0);
{ {
boost::shared_ptr<type[]> a1 = boost::allocate_shared_noinit<type[]>(std::allocator<type>(), 3); boost::shared_ptr<const type[2][2]> a1 = boost::allocate_shared<const type[2][2]>(std::allocator<type>());
type* a2 = a1.get(); BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1.use_count() == 1); BOOST_TEST(a1.use_count() == 1);
BOOST_TEST(a2 != 0); BOOST_TEST(type::instances == 4);
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(); a1.reset();
BOOST_TEST(type::instances == 0); BOOST_TEST(type::instances == 0);
} }
return boost::report_errors(); return boost::report_errors();
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012 Glen Joseph Fernandes * Copyright (c) 2012-2014 Glen Joseph Fernandes
* glenfe at live dot com * glenfe at live dot com
* *
* Distributed under the Boost Software License, * Distributed under the Boost Software License,
@@ -12,15 +12,18 @@
class type { class type {
public: public:
static unsigned int instances; static unsigned int instances;
explicit type() { explicit type() {
if (instances == 5) { if (instances == 5) {
throw true; throw true;
} }
instances++; instances++;
} }
~type() { ~type() {
instances--; instances--;
} }
private: private:
type(const type&); type(const type&);
type& operator=(const type&); type& operator=(const type&);
@@ -36,6 +39,7 @@ int main() {
} catch (...) { } catch (...) {
BOOST_TEST(type::instances == 0); BOOST_TEST(type::instances == 0);
} }
BOOST_TEST(type::instances == 0); BOOST_TEST(type::instances == 0);
try { try {
boost::allocate_shared<type[][2]>(std::allocator<type>(), 3); boost::allocate_shared<type[][2]>(std::allocator<type>(), 3);
@@ -43,7 +47,7 @@ int main() {
} catch (...) { } catch (...) {
BOOST_TEST(type::instances == 0); BOOST_TEST(type::instances == 0);
} }
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
BOOST_TEST(type::instances == 0); BOOST_TEST(type::instances == 0);
try { try {
boost::allocate_shared<type[6]>(std::allocator<type>()); boost::allocate_shared<type[6]>(std::allocator<type>());
@@ -51,6 +55,7 @@ int main() {
} catch (...) { } catch (...) {
BOOST_TEST(type::instances == 0); BOOST_TEST(type::instances == 0);
} }
BOOST_TEST(type::instances == 0); BOOST_TEST(type::instances == 0);
try { try {
boost::allocate_shared<type[3][2]>(std::allocator<type>()); boost::allocate_shared<type[3][2]>(std::allocator<type>());
@@ -58,7 +63,7 @@ int main() {
} catch (...) { } catch (...) {
BOOST_TEST(type::instances == 0); BOOST_TEST(type::instances == 0);
} }
#endif
BOOST_TEST(type::instances == 0); BOOST_TEST(type::instances == 0);
try { try {
boost::allocate_shared_noinit<type[]>(std::allocator<type>(), 6); boost::allocate_shared_noinit<type[]>(std::allocator<type>(), 6);
@@ -66,6 +71,7 @@ int main() {
} catch (...) { } catch (...) {
BOOST_TEST(type::instances == 0); BOOST_TEST(type::instances == 0);
} }
BOOST_TEST(type::instances == 0); BOOST_TEST(type::instances == 0);
try { try {
boost::allocate_shared_noinit<type[][2]>(std::allocator<type>(), 3); boost::allocate_shared_noinit<type[][2]>(std::allocator<type>(), 3);
@@ -73,5 +79,22 @@ int main() {
} catch (...) { } catch (...) {
BOOST_TEST(type::instances == 0); BOOST_TEST(type::instances == 0);
} }
BOOST_TEST(type::instances == 0);
try {
boost::allocate_shared_noinit<type[6]>(std::allocator<type>());
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[3][2]>(std::allocator<type>());
BOOST_ERROR("allocate_shared_noinit did not throw");
} catch (...) {
BOOST_TEST(type::instances == 0);
}
return boost::report_errors(); return boost::report_errors();
} }

View File

@@ -0,0 +1,46 @@
/*
* Copyright (c) 2012-2014 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() {
{
boost::shared_ptr<int[]> a1 = boost::allocate_shared<int[]>(std::allocator<int>(), 4, 1);
BOOST_TEST(a1[0] == 1);
BOOST_TEST(a1[1] == 1);
BOOST_TEST(a1[2] == 1);
BOOST_TEST(a1[3] == 1);
}
{
boost::shared_ptr<int[4]> a1 = boost::allocate_shared<int[4]>(std::allocator<int>(), 1);
BOOST_TEST(a1[0] == 1);
BOOST_TEST(a1[1] == 1);
BOOST_TEST(a1[2] == 1);
BOOST_TEST(a1[3] == 1);
}
{
boost::shared_ptr<const int[]> a1 = boost::allocate_shared<const int[]>(std::allocator<int>(), 4, 1);
BOOST_TEST(a1[0] == 1);
BOOST_TEST(a1[1] == 1);
BOOST_TEST(a1[2] == 1);
BOOST_TEST(a1[3] == 1);
}
{
boost::shared_ptr<const int[4]> a1 = boost::allocate_shared<const int[4]>(std::allocator<int>(), 1);
BOOST_TEST(a1[0] == 1);
BOOST_TEST(a1[1] == 1);
BOOST_TEST(a1[2] == 1);
BOOST_TEST(a1[3] == 1);
}
return boost::report_errors();
}

View File

@@ -1,94 +0,0 @@
/*
* 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();
}

View File

@@ -1,23 +0,0 @@
/*
* 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();
}

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012 Glen Joseph Fernandes * Copyright (c) 2012-2014 Glen Joseph Fernandes
* glenfe at live dot com * glenfe at live dot com
* *
* Distributed under the Boost Software License, * Distributed under the Boost Software License,
@@ -9,152 +9,40 @@
#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:
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() { int main() {
#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
{ {
boost::shared_ptr<int[][2][2]> a1 = boost::allocate_shared<int[][2][2]>(std::allocator<int>(), 2); boost::shared_ptr<int[][2]> a1 = boost::allocate_shared<int[][2]>(std::allocator<int>(), 2, {0, 1});
BOOST_TEST(a1.get() != 0); BOOST_TEST(a1[0][0] == 0);
BOOST_TEST(a1.use_count() == 1); BOOST_TEST(a1[0][1] == 1);
BOOST_TEST(a1[0][0][1] == 0); BOOST_TEST(a1[1][0] == 0);
BOOST_TEST(a1[0][1][0] == 0); BOOST_TEST(a1[1][1] == 1);
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::shared_ptr<int[2][2]> a1 = boost::allocate_shared<int[2][2]>(std::allocator<int>(), { 0, 1 });
BOOST_TEST(a1.get() != 0); BOOST_TEST(a1[0][0] == 0);
BOOST_TEST(a1.use_count() == 1); BOOST_TEST(a1[0][1] == 1);
BOOST_TEST(a1[0][0][1] == 0); BOOST_TEST(a1[1][0] == 0);
BOOST_TEST(a1[0][1][0] == 0); BOOST_TEST(a1[1][1] == 1);
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::shared_ptr<const int[][2]> a1 = boost::allocate_shared<const int[][2]>(std::allocator<int>(), 2, { 0, 1 });
BOOST_TEST(a1.get() != 0); BOOST_TEST(a1[0][0] == 0);
BOOST_TEST(a1.use_count() == 1); BOOST_TEST(a1[0][1] == 1);
BOOST_TEST(type::instances == 8); BOOST_TEST(a1[1][0] == 0);
a1.reset(); BOOST_TEST(a1[1][1] == 1);
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::shared_ptr<const int[2][2]> a1 = boost::allocate_shared<const int[2][2]>(std::allocator<int>(), { 0, 1 });
BOOST_TEST(a1.get() != 0); BOOST_TEST(a1[0][0] == 0);
BOOST_TEST(a1.use_count() == 1); BOOST_TEST(a1[0][1] == 1);
BOOST_TEST(type::instances == 8); BOOST_TEST(a1[1][0] == 0);
a1.reset(); BOOST_TEST(a1[1][1] == 1);
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 #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(); return boost::report_errors();
} }

View File

@@ -0,0 +1,240 @@
// allocate_shared_construct11_test.cpp
//
// Test whether allocate_shared uses construct/destroy in C++11
//
// Copyright 2007-2009, 2014 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 <boost/weak_ptr.hpp>
#include <cstddef>
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
template< class T > class cxx11_allocator
{
public:
typedef T value_type;
cxx11_allocator()
{
}
template< class Y > cxx11_allocator( cxx11_allocator<Y> const & )
{
}
T * allocate( std::size_t n )
{
return static_cast< T* >( ::operator new( n * sizeof( T ) ) );
}
void deallocate( T * p, std::size_t n )
{
::operator delete( p );
}
template<class... Args> void construct( T * p, Args&&... args )
{
::new( static_cast< void* >( p ) ) T( std::forward<Args>( args )... );
}
void destroy( T * p )
{
p->~T();
}
};
class X
{
private:
X( X const & );
X & operator=( X const & );
void * operator new( std::size_t n )
{
BOOST_ERROR( "private X::new called" );
return ::operator new( n );
}
void operator delete( void * p )
{
BOOST_ERROR( "private X::delete called" );
::operator delete( p );
}
public:
static int instances;
int v;
protected:
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;
}
friend class cxx11_allocator<X>;
};
int X::instances = 0;
int main()
{
BOOST_TEST( X::instances == 0 );
{
boost::shared_ptr< X > pi = boost::allocate_shared< X >( cxx11_allocator<void>() );
boost::weak_ptr<X> wp( pi );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( pi->v == 0 );
pi.reset();
BOOST_TEST( X::instances == 0 );
}
{
boost::shared_ptr< X > pi = boost::allocate_shared< X >( cxx11_allocator<void>(), 1 );
boost::weak_ptr<X> wp( pi );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( pi->v == 1 );
pi.reset();
BOOST_TEST( X::instances == 0 );
}
{
boost::shared_ptr< X > pi = boost::allocate_shared< X >( cxx11_allocator<void>(), 1, 2 );
boost::weak_ptr<X> wp( pi );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( pi->v == 1+2 );
pi.reset();
BOOST_TEST( X::instances == 0 );
}
{
boost::shared_ptr< X > pi = boost::allocate_shared< X >( cxx11_allocator<void>(), 1, 2, 3 );
boost::weak_ptr<X> wp( pi );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( pi->v == 1+2+3 );
pi.reset();
BOOST_TEST( X::instances == 0 );
}
{
boost::shared_ptr< X > pi = boost::allocate_shared< X >( cxx11_allocator<void>(), 1, 2, 3, 4 );
boost::weak_ptr<X> wp( pi );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( pi->v == 1+2+3+4 );
pi.reset();
BOOST_TEST( X::instances == 0 );
}
{
boost::shared_ptr< X > pi = boost::allocate_shared< X >( cxx11_allocator<void>(), 1, 2, 3, 4, 5 );
boost::weak_ptr<X> wp( pi );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( pi->v == 1+2+3+4+5 );
pi.reset();
BOOST_TEST( X::instances == 0 );
}
{
boost::shared_ptr< X > pi = boost::allocate_shared< X >( cxx11_allocator<void>(), 1, 2, 3, 4, 5, 6 );
boost::weak_ptr<X> wp( pi );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( pi->v == 1+2+3+4+5+6 );
pi.reset();
BOOST_TEST( X::instances == 0 );
}
{
boost::shared_ptr< X > pi = boost::allocate_shared< X >( cxx11_allocator<void>(), 1, 2, 3, 4, 5, 6, 7 );
boost::weak_ptr<X> wp( pi );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( pi->v == 1+2+3+4+5+6+7 );
pi.reset();
BOOST_TEST( X::instances == 0 );
}
{
boost::shared_ptr< X > pi = boost::allocate_shared< X >( cxx11_allocator<void>(), 1, 2, 3, 4, 5, 6, 7, 8 );
boost::weak_ptr<X> wp( pi );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( pi->v == 1+2+3+4+5+6+7+8 );
pi.reset();
BOOST_TEST( X::instances == 0 );
}
{
boost::shared_ptr< X > pi = boost::allocate_shared< X >( cxx11_allocator<void>(), 1, 2, 3, 4, 5, 6, 7, 8, 9 );
boost::weak_ptr<X> wp( pi );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( pi->v == 1+2+3+4+5+6+7+8+9 );
pi.reset();
BOOST_TEST( X::instances == 0 );
}
return boost::report_errors();
}
#else // !defined( BOOST_NO_CXX11_ALLOCATOR )
int main()
{
return 0;
}
#endif

View File

@@ -51,14 +51,18 @@ protected:
base(): use_count_(0) base(): use_count_(0)
{ {
++instances;
} }
virtual ~base() virtual ~base()
{ {
--instances;
} }
public: public:
static long instances;
long use_count() const long use_count() const
{ {
return use_count_; return use_count_;
@@ -91,6 +95,8 @@ public:
#endif #endif
}; };
long base::instances = 0;
} // namespace N } // namespace N
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
@@ -161,19 +167,27 @@ void pointer_constructor()
BOOST_TEST(px.get() == 0); BOOST_TEST(px.get() == 0);
} }
BOOST_TEST( N::base::instances == 0 );
{ {
X * p = new X; X * p = new X;
BOOST_TEST(p->use_count() == 0); BOOST_TEST(p->use_count() == 0);
BOOST_TEST( N::base::instances == 1 );
boost::intrusive_ptr<X> px(p); boost::intrusive_ptr<X> px(p);
BOOST_TEST(px.get() == p); BOOST_TEST(px.get() == p);
BOOST_TEST(px->use_count() == 1); BOOST_TEST(px->use_count() == 1);
} }
BOOST_TEST( N::base::instances == 0 );
{ {
X * p = new X; X * p = new X;
BOOST_TEST(p->use_count() == 0); BOOST_TEST(p->use_count() == 0);
BOOST_TEST( N::base::instances == 1 );
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
using boost::intrusive_ptr_add_ref; using boost::intrusive_ptr_add_ref;
#endif #endif
@@ -184,6 +198,8 @@ void pointer_constructor()
BOOST_TEST(px.get() == p); BOOST_TEST(px.get() == p);
BOOST_TEST(px->use_count() == 1); BOOST_TEST(px->use_count() == 1);
} }
BOOST_TEST( N::base::instances == 0 );
} }
void copy_constructor() void copy_constructor()
@@ -224,17 +240,27 @@ void copy_constructor()
BOOST_TEST(px.get() == py.get()); BOOST_TEST(px.get() == py.get());
} }
BOOST_TEST( N::base::instances == 0 );
{ {
boost::intrusive_ptr<X> px(new X); boost::intrusive_ptr<X> px(new X);
boost::intrusive_ptr<X> px2(px); boost::intrusive_ptr<X> px2(px);
BOOST_TEST( px2.get() == px.get() ); BOOST_TEST( px2.get() == px.get() );
BOOST_TEST( N::base::instances == 1 );
} }
BOOST_TEST( N::base::instances == 0 );
{ {
boost::intrusive_ptr<Y> py(new Y); boost::intrusive_ptr<Y> py(new Y);
boost::intrusive_ptr<X> px(py); boost::intrusive_ptr<X> px(py);
BOOST_TEST( px.get() == py.get() ); BOOST_TEST( px.get() == py.get() );
BOOST_TEST( N::base::instances == 1 );
} }
BOOST_TEST( N::base::instances == 0 );
} }
void test() void test()
@@ -250,10 +276,15 @@ namespace n_destructor
{ {
void test() void test()
{
BOOST_TEST( N::base::instances == 0 );
{ {
boost::intrusive_ptr<X> px(new X); boost::intrusive_ptr<X> px(new X);
BOOST_TEST(px->use_count() == 1); BOOST_TEST(px->use_count() == 1);
BOOST_TEST( N::base::instances == 1 );
{ {
boost::intrusive_ptr<X> px2(px); boost::intrusive_ptr<X> px2(px);
BOOST_TEST(px->use_count() == 2); BOOST_TEST(px->use_count() == 2);
@@ -262,6 +293,9 @@ void test()
BOOST_TEST(px->use_count() == 1); BOOST_TEST(px->use_count() == 1);
} }
BOOST_TEST( N::base::instances == 0 );
}
} // namespace n_destructor } // namespace n_destructor
namespace n_assignment namespace n_assignment
@@ -288,6 +322,174 @@ void test()
} // namespace n_assignment } // namespace n_assignment
namespace n_reset
{
void test()
{
BOOST_TEST( N::base::instances == 0 );
{
boost::intrusive_ptr<X> px;
BOOST_TEST( px.get() == 0 );
px.reset();
BOOST_TEST( px.get() == 0 );
X * p = new X;
BOOST_TEST( p->use_count() == 0 );
BOOST_TEST( N::base::instances == 1 );
px.reset( p );
BOOST_TEST( px.get() == p );
BOOST_TEST( px->use_count() == 1 );
px.reset();
BOOST_TEST( px.get() == 0 );
}
BOOST_TEST( N::base::instances == 0 );
{
boost::intrusive_ptr<X> px( new X );
BOOST_TEST( N::base::instances == 1 );
px.reset( 0 );
BOOST_TEST( px.get() == 0 );
}
BOOST_TEST( N::base::instances == 0 );
{
boost::intrusive_ptr<X> px( new X );
BOOST_TEST( N::base::instances == 1 );
px.reset( 0, false );
BOOST_TEST( px.get() == 0 );
}
BOOST_TEST( N::base::instances == 0 );
{
boost::intrusive_ptr<X> px( new X );
BOOST_TEST( N::base::instances == 1 );
px.reset( 0, true );
BOOST_TEST( px.get() == 0 );
}
BOOST_TEST( N::base::instances == 0 );
{
X * p = new X;
BOOST_TEST( p->use_count() == 0 );
BOOST_TEST( N::base::instances == 1 );
boost::intrusive_ptr<X> px;
BOOST_TEST( px.get() == 0 );
px.reset( p, true );
BOOST_TEST( px.get() == p );
BOOST_TEST( px->use_count() == 1 );
}
BOOST_TEST( N::base::instances == 0 );
{
X * p = new X;
BOOST_TEST( p->use_count() == 0 );
BOOST_TEST( N::base::instances == 1 );
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
using boost::intrusive_ptr_add_ref;
#endif
intrusive_ptr_add_ref( p );
BOOST_TEST( p->use_count() == 1 );
boost::intrusive_ptr<X> px;
BOOST_TEST( px.get() == 0 );
px.reset( p, false );
BOOST_TEST( px.get() == p );
BOOST_TEST( px->use_count() == 1 );
}
BOOST_TEST( N::base::instances == 0 );
{
boost::intrusive_ptr<X> px( new X );
BOOST_TEST( px.get() != 0 );
BOOST_TEST( px->use_count() == 1 );
BOOST_TEST( N::base::instances == 1 );
X * p = new X;
BOOST_TEST( p->use_count() == 0 );
BOOST_TEST( N::base::instances == 2 );
px.reset( p );
BOOST_TEST( px.get() == p );
BOOST_TEST( px->use_count() == 1 );
BOOST_TEST( N::base::instances == 1 );
}
BOOST_TEST( N::base::instances == 0 );
{
boost::intrusive_ptr<X> px( new X );
BOOST_TEST( px.get() != 0 );
BOOST_TEST( px->use_count() == 1 );
BOOST_TEST( N::base::instances == 1 );
X * p = new X;
BOOST_TEST( p->use_count() == 0 );
BOOST_TEST( N::base::instances == 2 );
px.reset( p, true );
BOOST_TEST( px.get() == p );
BOOST_TEST( px->use_count() == 1 );
BOOST_TEST( N::base::instances == 1 );
}
BOOST_TEST( N::base::instances == 0 );
{
boost::intrusive_ptr<X> px( new X );
BOOST_TEST( px.get() != 0 );
BOOST_TEST( px->use_count() == 1 );
BOOST_TEST( N::base::instances == 1 );
X * p = new X;
BOOST_TEST( p->use_count() == 0 );
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
using boost::intrusive_ptr_add_ref;
#endif
intrusive_ptr_add_ref( p );
BOOST_TEST( p->use_count() == 1 );
BOOST_TEST( N::base::instances == 2 );
px.reset( p, false );
BOOST_TEST( px.get() == p );
BOOST_TEST( px->use_count() == 1 );
BOOST_TEST( N::base::instances == 1 );
}
BOOST_TEST( N::base::instances == 0 );
}
} // namespace n_reset
namespace n_access namespace n_access
{ {
@@ -330,6 +532,30 @@ void test()
BOOST_TEST(get_pointer(px) == px.get()); BOOST_TEST(get_pointer(px) == px.get());
} }
{
boost::intrusive_ptr<X> px;
X* detached = px.detach();
BOOST_TEST( px.get() == 0 );
BOOST_TEST( detached == 0 );
}
{
X * p = new X;
BOOST_TEST( p->use_count() == 0 );
boost::intrusive_ptr<X> px( p );
BOOST_TEST( px.get() == p );
BOOST_TEST( px->use_count() == 1 );
X * detached = px.detach();
BOOST_TEST( px.get() == 0 );
BOOST_TEST( detached == p );
BOOST_TEST( detached->use_count() == 1 );
delete detached;
}
} }
} // namespace n_access } // namespace n_access
@@ -548,6 +774,7 @@ int main()
n_constructors::test(); n_constructors::test();
n_destructor::test(); n_destructor::test();
n_assignment::test(); n_assignment::test();
n_reset::test();
n_access::test(); n_access::test();
n_swap::test(); n_swap::test();
n_comparison::test(); n_comparison::test();

View File

@@ -1,172 +0,0 @@
// make_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 <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::make_shared< 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::make_shared< 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::make_shared< 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::make_shared< 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::make_shared< 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::make_shared< 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::make_shared< 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::make_shared< 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::make_shared< 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::make_shared< 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();
}

View File

@@ -1,114 +0,0 @@
/*
* 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/make_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::make_shared<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::make_shared<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::make_shared<type[][2]>(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::make_shared<type[2][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::make_shared<type[][2][2]>(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::make_shared<type[2][2][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::make_shared<type[][2][2][2]>(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::make_shared<type[2][2][2][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);
}
#endif
return boost::report_errors();
}

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012 Glen Joseph Fernandes * Copyright (c) 2012-2014 Glen Joseph Fernandes
* glenfe at live dot com * glenfe at live dot com
* *
* Distributed under the Boost Software License, * Distributed under the Boost Software License,
@@ -14,12 +14,15 @@ class type
: public boost::enable_shared_from_this<type> { : public boost::enable_shared_from_this<type> {
public: public:
static unsigned int instances; static unsigned int instances;
explicit type() { explicit type() {
instances++; instances++;
} }
~type() { ~type() {
instances--; instances--;
} }
private: private:
type(const type&); type(const type&);
type& operator=(const type&); type& operator=(const type&);
@@ -38,6 +41,7 @@ int main() {
BOOST_TEST(type::instances == 3); BOOST_TEST(type::instances == 3);
} }
} }
BOOST_TEST(type::instances == 0); BOOST_TEST(type::instances == 0);
{ {
boost::shared_ptr<type[]> a1 = boost::make_shared_noinit<type[]>(3); boost::shared_ptr<type[]> a1 = boost::make_shared_noinit<type[]>(3);
@@ -48,5 +52,6 @@ int main() {
BOOST_TEST(type::instances == 3); BOOST_TEST(type::instances == 3);
} }
} }
return boost::report_errors(); return boost::report_errors();
} }

View File

@@ -1,84 +0,0 @@
/*
* 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/make_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::make_shared<int[4]>({ 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::make_shared<const int[4]>({ 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::make_shared<type[4]>({ 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::make_shared<const type[4]>({ 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::make_shared<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::make_shared<const 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::make_shared<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::make_shared<const 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();
}

View File

@@ -0,0 +1,181 @@
/*
* Copyright (c) 2012-2014 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/make_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() {
instances++;
}
~type() {
instances--;
}
private:
type(const type&);
type& operator=(const type&);
};
unsigned int type::instances = 0;
int main() {
{
boost::shared_ptr<int[]> a1 = boost::make_shared_noinit<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::make_shared_noinit<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[][2]> a1 = boost::make_shared_noinit<int[][2]>(2);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1.use_count() == 1);
}
{
boost::shared_ptr<int[2][2]> a1 = boost::make_shared_noinit<int[2][2]>();
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1.use_count() == 1);
}
{
boost::shared_ptr<const int[]> a1 = boost::make_shared_noinit<const 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::make_shared_noinit<const 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[][2]> a1 = boost::make_shared_noinit<const int[][2]>(2);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1.use_count() == 1);
}
{
boost::shared_ptr<const int[2][2]> a1 = boost::make_shared_noinit<const int[2][2]>();
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1.use_count() == 1);
}
BOOST_TEST(type::instances == 0);
{
boost::shared_ptr<type[]> a1 = boost::make_shared_noinit<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::make_shared_noinit<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[3]> w1 = a1;
a1.reset();
BOOST_TEST(type::instances == 0);
}
BOOST_TEST(type::instances == 0);
{
boost::shared_ptr<type[][2]> a1 = boost::make_shared_noinit<type[][2]>(2);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1.use_count() == 1);
BOOST_TEST(type::instances == 4);
a1.reset();
BOOST_TEST(type::instances == 0);
}
BOOST_TEST(type::instances == 0);
{
boost::shared_ptr<type[2][2]> a1 = boost::make_shared_noinit<type[2][2]>();
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1.use_count() == 1);
BOOST_TEST(type::instances == 4);
a1.reset();
BOOST_TEST(type::instances == 0);
}
BOOST_TEST(type::instances == 0);
{
boost::shared_ptr<const type[]> a1 = boost::make_shared_noinit<const 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::make_shared_noinit<const 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[][2]> a1 = boost::make_shared_noinit<const type[][2]>(2);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1.use_count() == 1);
BOOST_TEST(type::instances == 4);
a1.reset();
BOOST_TEST(type::instances == 0);
}
BOOST_TEST(type::instances == 0);
{
boost::shared_ptr<const type[2][2]> a1 = boost::make_shared_noinit<const type[2][2]>();
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1.use_count() == 1);
BOOST_TEST(type::instances == 4);
a1.reset();
BOOST_TEST(type::instances == 0);
}
return boost::report_errors();
}

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012 Glen Joseph Fernandes * Copyright (c) 2012-2014 Glen Joseph Fernandes
* glenfe at live dot com * glenfe at live dot com
* *
* Distributed under the Boost Software License, * Distributed under the Boost Software License,
@@ -14,17 +14,18 @@
class type { class type {
public: public:
static unsigned int instances; static unsigned int instances;
explicit type(int = 0, int = 0)
: member() { explicit type() {
instances++; instances++;
} }
~type() { ~type() {
instances--; instances--;
} }
private: private:
type(const type&); type(const type&);
type& operator=(const type&); type& operator=(const type&);
double member;
}; };
unsigned int type::instances = 0; unsigned int type::instances = 0;
@@ -40,6 +41,38 @@ int main() {
BOOST_TEST(a1[1] == 0); BOOST_TEST(a1[1] == 0);
BOOST_TEST(a1[2] == 0); BOOST_TEST(a1[2] == 0);
} }
{
boost::shared_ptr<int[3]> a1 = boost::make_shared<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<int[][2]> a1 = boost::make_shared<int[][2]>(2);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1.use_count() == 1);
BOOST_TEST(a1[0][0] == 0);
BOOST_TEST(a1[0][1] == 0);
BOOST_TEST(a1[1][0] == 0);
BOOST_TEST(a1[1][1] == 0);
}
{
boost::shared_ptr<int[2][2]> a1 = boost::make_shared<int[2][2]>();
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1.use_count() == 1);
BOOST_TEST(a1[0][0] == 0);
BOOST_TEST(a1[0][1] == 0);
BOOST_TEST(a1[1][0] == 0);
BOOST_TEST(a1[1][1] == 0);
}
{ {
boost::shared_ptr<const int[]> a1 = boost::make_shared<const int[]>(3); boost::shared_ptr<const int[]> a1 = boost::make_shared<const int[]>(3);
const int* a2 = a1.get(); const int* a2 = a1.get();
@@ -50,6 +83,38 @@ int main() {
BOOST_TEST(a1[1] == 0); BOOST_TEST(a1[1] == 0);
BOOST_TEST(a1[2] == 0); BOOST_TEST(a1[2] == 0);
} }
{
boost::shared_ptr<const int[3]> a1 = boost::make_shared<const 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::shared_ptr<const int[][2]> a1 = boost::make_shared<const int[][2]>(2);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1.use_count() == 1);
BOOST_TEST(a1[0][0] == 0);
BOOST_TEST(a1[0][1] == 0);
BOOST_TEST(a1[1][0] == 0);
BOOST_TEST(a1[1][1] == 0);
}
{
boost::shared_ptr<const int[2][2]> a1 = boost::make_shared<const int[2][2]>();
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1.use_count() == 1);
BOOST_TEST(a1[0][0] == 0);
BOOST_TEST(a1[0][1] == 0);
BOOST_TEST(a1[1][0] == 0);
BOOST_TEST(a1[1][1] == 0);
}
BOOST_TEST(type::instances == 0); BOOST_TEST(type::instances == 0);
{ {
boost::shared_ptr<type[]> a1 = boost::make_shared<type[]>(3); boost::shared_ptr<type[]> a1 = boost::make_shared<type[]>(3);
@@ -62,6 +127,40 @@ int main() {
a1.reset(); a1.reset();
BOOST_TEST(type::instances == 0); BOOST_TEST(type::instances == 0);
} }
BOOST_TEST(type::instances == 0);
{
boost::shared_ptr<type[3]> a1 = boost::make_shared<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[3]> w1 = a1;
a1.reset();
BOOST_TEST(type::instances == 0);
}
BOOST_TEST(type::instances == 0);
{
boost::shared_ptr<type[][2]> a1 = boost::make_shared<type[][2]>(2);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1.use_count() == 1);
BOOST_TEST(type::instances == 4);
a1.reset();
BOOST_TEST(type::instances == 0);
}
BOOST_TEST(type::instances == 0);
{
boost::shared_ptr<type[2][2]> a1 = boost::make_shared<type[2][2]>();
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1.use_count() == 1);
BOOST_TEST(type::instances == 4);
a1.reset();
BOOST_TEST(type::instances == 0);
}
BOOST_TEST(type::instances == 0); BOOST_TEST(type::instances == 0);
{ {
boost::shared_ptr<const type[]> a1 = boost::make_shared<const type[]>(3); boost::shared_ptr<const type[]> a1 = boost::make_shared<const type[]>(3);
@@ -73,34 +172,10 @@ int main() {
a1.reset(); a1.reset();
BOOST_TEST(type::instances == 0); BOOST_TEST(type::instances == 0);
} }
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
BOOST_TEST(type::instances == 0); BOOST_TEST(type::instances == 0);
{ {
boost::shared_ptr<type[]> a1 = boost::make_shared<type[]>(3, 1, 5); boost::shared_ptr<const type[3]> a1 = boost::make_shared<const 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::make_shared<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[3]> w1 = a1;
a1.reset();
BOOST_TEST(type::instances == 0);
}
BOOST_TEST(type::instances == 0);
{
boost::shared_ptr<const type[]> a1 = boost::make_shared<const type[]>(3, 1, 5);
const type* a2 = a1.get(); const type* a2 = a1.get();
BOOST_TEST(a1.use_count() == 1); BOOST_TEST(a1.use_count() == 1);
BOOST_TEST(a2 != 0); BOOST_TEST(a2 != 0);
@@ -109,91 +184,26 @@ int main() {
a1.reset(); a1.reset();
BOOST_TEST(type::instances == 0); BOOST_TEST(type::instances == 0);
} }
BOOST_TEST(type::instances == 0); BOOST_TEST(type::instances == 0);
{ {
boost::shared_ptr<const type[3]> a1 = boost::make_shared<const type[3]>(1, 5); boost::shared_ptr<const type[][2]> a1 = boost::make_shared<const type[][2]>(2);
const type* a2 = a1.get(); BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1.use_count() == 1); BOOST_TEST(a1.use_count() == 1);
BOOST_TEST(a2 != 0); BOOST_TEST(type::instances == 4);
BOOST_TEST(size_t(a2) % boost::alignment_of<type>::value == 0);
BOOST_TEST(type::instances == 3);
a1.reset(); a1.reset();
BOOST_TEST(type::instances == 0); BOOST_TEST(type::instances == 0);
} }
#endif
{
boost::shared_ptr<int[]> a1 = boost::make_shared_noinit<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::make_shared_noinit<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<const int[]> a1 = boost::make_shared_noinit<const 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::make_shared_noinit<const 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(type::instances == 0); BOOST_TEST(type::instances == 0);
{ {
boost::shared_ptr<type[]> a1 = boost::make_shared_noinit<type[]>(3); boost::shared_ptr<const type[2][2]> a1 = boost::make_shared<const type[2][2]>();
type* a2 = a1.get(); BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1.use_count() == 1); BOOST_TEST(a1.use_count() == 1);
BOOST_TEST(a2 != 0); BOOST_TEST(type::instances == 4);
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::make_shared_noinit<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[3]> w1 = a1;
a1.reset();
BOOST_TEST(type::instances == 0);
}
BOOST_TEST(type::instances == 0);
{
boost::shared_ptr<const type[]> a1 = boost::make_shared_noinit<const 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::make_shared_noinit<const 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(); a1.reset();
BOOST_TEST(type::instances == 0); BOOST_TEST(type::instances == 0);
} }
return boost::report_errors(); return boost::report_errors();
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012 Glen Joseph Fernandes * Copyright (c) 2012-2014 Glen Joseph Fernandes
* glenfe at live dot com * glenfe at live dot com
* *
* Distributed under the Boost Software License, * Distributed under the Boost Software License,
@@ -12,15 +12,18 @@
class type { class type {
public: public:
static unsigned int instances; static unsigned int instances;
explicit type() { explicit type() {
if (instances == 5) { if (instances == 5) {
throw true; throw true;
} }
instances++; instances++;
} }
~type() { ~type() {
instances--; instances--;
} }
private: private:
type(const type&); type(const type&);
type& operator=(const type&); type& operator=(const type&);
@@ -36,6 +39,7 @@ int main() {
} catch (...) { } catch (...) {
BOOST_TEST(type::instances == 0); BOOST_TEST(type::instances == 0);
} }
BOOST_TEST(type::instances == 0); BOOST_TEST(type::instances == 0);
try { try {
boost::make_shared<type[][2]>(3); boost::make_shared<type[][2]>(3);
@@ -43,7 +47,7 @@ int main() {
} catch (...) { } catch (...) {
BOOST_TEST(type::instances == 0); BOOST_TEST(type::instances == 0);
} }
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
BOOST_TEST(type::instances == 0); BOOST_TEST(type::instances == 0);
try { try {
boost::make_shared<type[6]>(); boost::make_shared<type[6]>();
@@ -51,6 +55,7 @@ int main() {
} catch (...) { } catch (...) {
BOOST_TEST(type::instances == 0); BOOST_TEST(type::instances == 0);
} }
BOOST_TEST(type::instances == 0); BOOST_TEST(type::instances == 0);
try { try {
boost::make_shared<type[3][2]>(); boost::make_shared<type[3][2]>();
@@ -58,7 +63,7 @@ int main() {
} catch (...) { } catch (...) {
BOOST_TEST(type::instances == 0); BOOST_TEST(type::instances == 0);
} }
#endif
BOOST_TEST(type::instances == 0); BOOST_TEST(type::instances == 0);
try { try {
boost::make_shared_noinit<type[]>(6); boost::make_shared_noinit<type[]>(6);
@@ -66,6 +71,7 @@ int main() {
} catch (...) { } catch (...) {
BOOST_TEST(type::instances == 0); BOOST_TEST(type::instances == 0);
} }
BOOST_TEST(type::instances == 0); BOOST_TEST(type::instances == 0);
try { try {
boost::make_shared_noinit<type[][2]>(3); boost::make_shared_noinit<type[][2]>(3);
@@ -73,5 +79,22 @@ int main() {
} catch (...) { } catch (...) {
BOOST_TEST(type::instances == 0); BOOST_TEST(type::instances == 0);
} }
BOOST_TEST(type::instances == 0);
try {
boost::make_shared_noinit<type[6]>();
BOOST_ERROR("make_shared_noinit did not throw");
} catch (...) {
BOOST_TEST(type::instances == 0);
}
BOOST_TEST(type::instances == 0);
try {
boost::make_shared_noinit<type[3][2]>();
BOOST_ERROR("make_shared_noinit did not throw");
} catch (...) {
BOOST_TEST(type::instances == 0);
}
return boost::report_errors(); return boost::report_errors();
} }

View File

@@ -0,0 +1,46 @@
/*
* Copyright (c) 2012-2014 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/make_shared_array.hpp>
int main() {
{
boost::shared_ptr<int[]> a1 = boost::make_shared<int[]>(4, 1);
BOOST_TEST(a1[0] == 1);
BOOST_TEST(a1[1] == 1);
BOOST_TEST(a1[2] == 1);
BOOST_TEST(a1[3] == 1);
}
{
boost::shared_ptr<int[4]> a1 = boost::make_shared<int[4]>(1);
BOOST_TEST(a1[0] == 1);
BOOST_TEST(a1[1] == 1);
BOOST_TEST(a1[2] == 1);
BOOST_TEST(a1[3] == 1);
}
{
boost::shared_ptr<const int[]> a1 = boost::make_shared<const int[]>(4, 1);
BOOST_TEST(a1[0] == 1);
BOOST_TEST(a1[1] == 1);
BOOST_TEST(a1[2] == 1);
BOOST_TEST(a1[3] == 1);
}
{
boost::shared_ptr<const int[4]> a1 = boost::make_shared<const int[4]>(1);
BOOST_TEST(a1[0] == 1);
BOOST_TEST(a1[1] == 1);
BOOST_TEST(a1[2] == 1);
BOOST_TEST(a1[3] == 1);
}
return boost::report_errors();
}

View File

@@ -1,94 +0,0 @@
/*
* 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/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_UNIFIED_INITIALIZATION_SYNTAX)
{
boost::shared_ptr<int[4]> a1 = boost::make_shared<int[4]>({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::make_shared<int[2][2]>({ {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::make_shared<int[][2]>(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::make_shared<int[][2][2]>(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::make_shared<int[2][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][2]> a1 = boost::make_shared<int[2][2][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);
}
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
{
boost::shared_ptr<int[]> a1 = boost::make_shared<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::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();
}

View File

@@ -1,23 +0,0 @@
/*
* 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/make_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::make_shared<int[][2]>({ {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();
}

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012 Glen Joseph Fernandes * Copyright (c) 2012-2014 Glen Joseph Fernandes
* glenfe at live dot com * glenfe at live dot com
* *
* Distributed under the Boost Software License, * Distributed under the Boost Software License,
@@ -9,152 +9,40 @@
#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:
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() { int main() {
#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
{ {
boost::shared_ptr<int[][2][2]> a1 = boost::make_shared<int[][2][2]>(2); boost::shared_ptr<int[][2]> a1 = boost::make_shared<int[][2]>(2, {0, 1});
BOOST_TEST(a1.get() != 0); BOOST_TEST(a1[0][0] == 0);
BOOST_TEST(a1.use_count() == 1); BOOST_TEST(a1[0][1] == 1);
BOOST_TEST(a1[0][0][1] == 0); BOOST_TEST(a1[1][0] == 0);
BOOST_TEST(a1[0][1][0] == 0); BOOST_TEST(a1[1][1] == 1);
BOOST_TEST(a1[1][0][0] == 0);
} }
{ {
boost::shared_ptr<const int[][2][2]> a1 = boost::make_shared<const int[][2][2]>(2); boost::shared_ptr<int[2][2]> a1 = boost::make_shared<int[2][2]>({ 0, 1 });
BOOST_TEST(a1.get() != 0); BOOST_TEST(a1[0][0] == 0);
BOOST_TEST(a1.use_count() == 1); BOOST_TEST(a1[0][1] == 1);
BOOST_TEST(a1[0][0][1] == 0); BOOST_TEST(a1[1][0] == 0);
BOOST_TEST(a1[0][1][0] == 0); BOOST_TEST(a1[1][1] == 1);
BOOST_TEST(a1[1][0][0] == 0);
} }
BOOST_TEST(type::instances == 0);
{ {
boost::shared_ptr<type[][2][2]> a1 = boost::make_shared<type[][2][2]>(2); boost::shared_ptr<const int[][2]> a1 = boost::make_shared<const int[][2]>(2, { 0, 1 });
BOOST_TEST(a1.get() != 0); BOOST_TEST(a1[0][0] == 0);
BOOST_TEST(a1.use_count() == 1); BOOST_TEST(a1[0][1] == 1);
BOOST_TEST(type::instances == 8); BOOST_TEST(a1[1][0] == 0);
a1.reset(); BOOST_TEST(a1[1][1] == 1);
BOOST_TEST(type::instances == 0);
} }
BOOST_TEST(type::instances == 0);
{ {
boost::shared_ptr<const type[][2][2]> a1 = boost::make_shared<const type[][2][2]>(2); boost::shared_ptr<const int[2][2]> a1 = boost::make_shared<const int[2][2]>({ 0, 1 });
BOOST_TEST(a1.get() != 0); BOOST_TEST(a1[0][0] == 0);
BOOST_TEST(a1.use_count() == 1); BOOST_TEST(a1[0][1] == 1);
BOOST_TEST(type::instances == 8); BOOST_TEST(a1[1][0] == 0);
a1.reset(); BOOST_TEST(a1[1][1] == 1);
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::make_shared<type[][2][2]>(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::make_shared<type[2][2][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]> a1 = boost::make_shared<const type[][2][2]>(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::make_shared<const type[2][2][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);
} }
#endif #endif
{
boost::shared_ptr<int[][2][2]> a1 = boost::make_shared_noinit<int[][2][2]>(2);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1.use_count() == 1);
}
{
boost::shared_ptr<int[2][2][2]> a1 = boost::make_shared_noinit<int[2][2][2]>();
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1.use_count() == 1);
}
{
boost::shared_ptr<const int[][2][2]> a1 = boost::make_shared_noinit<const int[][2][2]>(2);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1.use_count() == 1);
}
{
boost::shared_ptr<const int[2][2][2]> a1 = boost::make_shared_noinit<const int[2][2][2]>();
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1.use_count() == 1);
}
BOOST_TEST(type::instances == 0);
{
boost::shared_ptr<type[][2][2]> a1 = boost::make_shared_noinit<type[][2][2]>(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::make_shared_noinit<type[2][2][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::make_shared_noinit<const type[][2][2]>(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::make_shared_noinit<const type[2][2][2]>();
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(); return boost::report_errors();
} }

View File

@@ -0,0 +1,146 @@
/*
* Copyright (c) 2014 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/config.hpp>
#if !defined(BOOST_NO_CXX11_SMART_PTR)
#include <boost/detail/lightweight_test.hpp>
#include <boost/smart_ptr/make_unique_object.hpp>
class type {
public:
static unsigned int instances;
explicit type(int v1 = 0,
int v2 = 0,
int v3 = 0,
int v4 = 0,
int v5 = 0,
int v6 = 0,
int v7 = 0,
int v8 = 0,
int v9 = 0)
: sum(v1 + v2 + v3 + v4 + v5 + v6 + v7 + v8 + v9) {
instances++;
}
~type() {
instances--;
}
const int sum;
private:
type(const type&);
type& operator=(const type&);
};
unsigned int type::instances = 0;
int main() {
BOOST_TEST(type::instances == 0);
{
std::unique_ptr<type> a1 = boost::make_unique<type>();
BOOST_TEST(a1.get() != 0);
BOOST_TEST(type::instances == 1);
BOOST_TEST(a1->sum == 0);
a1.reset();
BOOST_TEST(type::instances == 0);
}
#if !defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES )
{
std::unique_ptr<type> a1 = boost::make_unique<type>(1);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(type::instances == 1);
BOOST_TEST(a1->sum == 1);
a1.reset();
BOOST_TEST(type::instances == 0);
}
{
std::unique_ptr<type> a1 = boost::make_unique<type>(1, 2);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(type::instances == 1);
BOOST_TEST(a1->sum == 1 + 2);
a1.reset();
BOOST_TEST(type::instances == 0);
}
{
std::unique_ptr<type> a1 = boost::make_unique<type>(1, 2, 3);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(type::instances == 1);
BOOST_TEST(a1->sum == 1 + 2 + 3);
a1.reset();
BOOST_TEST(type::instances == 0);
}
{
std::unique_ptr<type> a1 = boost::make_unique<type>(1, 2, 3, 4);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(type::instances == 1);
BOOST_TEST(a1->sum == 1 + 2 + 3 + 4);
a1.reset();
BOOST_TEST(type::instances == 0);
}
{
std::unique_ptr<type> a1 = boost::make_unique<type>(1, 2, 3, 4, 5);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(type::instances == 1);
BOOST_TEST(a1->sum == 1 + 2 + 3 + 4 + 5);
a1.reset();
BOOST_TEST(type::instances == 0);
}
{
std::unique_ptr<type> a1 = boost::make_unique<type>(1, 2, 3, 4, 5, 6);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(type::instances == 1);
BOOST_TEST(a1->sum == 1 + 2 + 3 + 4 + 5 + 6);
a1.reset();
BOOST_TEST(type::instances == 0);
}
{
std::unique_ptr<type> a1 = boost::make_unique<type>(1, 2, 3, 4, 5, 6, 7);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(type::instances == 1);
BOOST_TEST(a1->sum == 1 + 2 + 3 + 4 + 5 + 6 + 7);
a1.reset();
BOOST_TEST(type::instances == 0);
}
{
std::unique_ptr<type> a1 = boost::make_unique<type>(1, 2, 3, 4, 5, 6, 7, 8);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(type::instances == 1);
BOOST_TEST(a1->sum == 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8);
a1.reset();
BOOST_TEST(type::instances == 0);
}
{
std::unique_ptr<type> a1 = boost::make_unique<type>(1, 2, 3, 4, 5, 6, 7, 8, 9);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(type::instances == 1);
BOOST_TEST(a1->sum == 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9);
a1.reset();
BOOST_TEST(type::instances == 0);
}
#endif
return boost::report_errors();
}
#else
int main() {
return 0;
}
#endif

View File

@@ -0,0 +1,88 @@
/*
* Copyright (c) 2012-2014 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/config.hpp>
#if !defined(BOOST_NO_CXX11_SMART_PTR)
#include <boost/detail/lightweight_test.hpp>
#include <boost/smart_ptr/make_unique_array.hpp>
class 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() {
{
std::unique_ptr<int[]> a1 = boost::make_unique_noinit<int[]>(3);
BOOST_TEST(a1.get() != 0);
}
{
std::unique_ptr<int[][2]> a1 = boost::make_unique_noinit<int[][2]>(2);
BOOST_TEST(a1.get() != 0);
}
BOOST_TEST(type::instances == 0);
{
std::unique_ptr<type[]> a1 = boost::make_unique_noinit<type[]>(3);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(type::instances == 3);
a1.reset();
BOOST_TEST(type::instances == 0);
}
BOOST_TEST(type::instances == 0);
{
std::unique_ptr<type[][2]> a1 = boost::make_unique_noinit<type[][2]>(2);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(type::instances == 4);
a1.reset();
BOOST_TEST(type::instances == 0);
}
BOOST_TEST(type::instances == 0);
{
std::unique_ptr<const type[]> a1 = boost::make_unique_noinit<const type[]>(3);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(type::instances == 3);
a1.reset();
BOOST_TEST(type::instances == 0);
}
BOOST_TEST(type::instances == 0);
{
std::unique_ptr<const type[][2]> a1 = boost::make_unique_noinit<const type[][2]>(2);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(type::instances == 4);
a1.reset();
BOOST_TEST(type::instances == 0);
}
return boost::report_errors();
}
#else
int main() {
return 0;
}
#endif

View File

@@ -0,0 +1,112 @@
/*
* Copyright (c) 2014 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/config.hpp>
#if !defined(BOOST_NO_CXX11_SMART_PTR)
#include <boost/detail/lightweight_test.hpp>
#include <boost/smart_ptr/make_unique_array.hpp>
class 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() {
{
std::unique_ptr<int[]> a1 = boost::make_unique<int[]>(3);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1[0] == 0);
BOOST_TEST(a1[1] == 0);
BOOST_TEST(a1[2] == 0);
}
{
std::unique_ptr<int[][2]> a1 = boost::make_unique<int[][2]>(2);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1[0][0] == 0);
BOOST_TEST(a1[0][1] == 0);
BOOST_TEST(a1[1][0] == 0);
BOOST_TEST(a1[1][1] == 0);
}
{
std::unique_ptr<const int[]> a1 = boost::make_unique<const int[]>(3);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1[0] == 0);
BOOST_TEST(a1[1] == 0);
BOOST_TEST(a1[2] == 0);
}
{
std::unique_ptr<const int[][2]> a1 = boost::make_unique<const int[][2]>(2);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1[0][0] == 0);
BOOST_TEST(a1[0][1] == 0);
BOOST_TEST(a1[1][0] == 0);
BOOST_TEST(a1[1][1] == 0);
}
BOOST_TEST(type::instances == 0);
{
std::unique_ptr<type[]> a1 = boost::make_unique<type[]>(3);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(type::instances == 3);
a1.reset();
BOOST_TEST(type::instances == 0);
}
BOOST_TEST(type::instances == 0);
{
std::unique_ptr<type[][2]> a1 = boost::make_unique<type[][2]>(2);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(type::instances == 4);
a1.reset();
BOOST_TEST(type::instances == 0);
}
BOOST_TEST(type::instances == 0);
{
std::unique_ptr<const type[]> a1 = boost::make_unique<const type[]>(3);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(type::instances == 3);
a1.reset();
BOOST_TEST(type::instances == 0);
}
BOOST_TEST(type::instances == 0);
{
std::unique_ptr<const type[][2]> a1 = boost::make_unique<const type[][2]>(2);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(type::instances == 4);
a1.reset();
BOOST_TEST(type::instances == 0);
}
return boost::report_errors();
}
#else
int main() {
return 0;
}
#endif

View File

@@ -0,0 +1,77 @@
/*
* Copyright (c) 2014 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/config.hpp>
#if !defined(BOOST_NO_CXX11_SMART_PTR)
#include <boost/detail/lightweight_test.hpp>
#include <boost/smart_ptr/make_unique_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::make_unique<type[]>(6);
BOOST_ERROR("make_unique did not throw");
} catch (...) {
BOOST_TEST(type::instances == 0);
}
BOOST_TEST(type::instances == 0);
try {
boost::make_unique<type[][2]>(3);
BOOST_ERROR("make_unique did not throw");
} catch (...) {
BOOST_TEST(type::instances == 0);
}
BOOST_TEST(type::instances == 0);
try {
boost::make_unique_noinit<type[]>(6);
BOOST_ERROR("make_unique_noinit did not throw");
} catch (...) {
BOOST_TEST(type::instances == 0);
}
BOOST_TEST(type::instances == 0);
try {
boost::make_unique_noinit<type[][2]>(3);
BOOST_ERROR("make_unique_noinit did not throw");
} catch (...) {
BOOST_TEST(type::instances == 0);
}
return boost::report_errors();
}
#else
int main() {
return 0;
}
#endif

View File

@@ -0,0 +1,65 @@
/*
* Copyright (c) 2012-2014 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/config.hpp>
#if !defined(BOOST_NO_CXX11_SMART_PTR)
#include <boost/detail/lightweight_test.hpp>
#include <boost/smart_ptr/make_unique_object.hpp>
class 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() {
{
std::unique_ptr<int> a1 = boost::make_unique_noinit<int>();
BOOST_TEST(a1.get() != 0);
}
BOOST_TEST(type::instances == 0);
{
std::unique_ptr<type> a1 = boost::make_unique_noinit<type>();
BOOST_TEST(a1.get() != 0);
BOOST_TEST(type::instances == 1);
a1.reset();
BOOST_TEST(type::instances == 0);
}
BOOST_TEST(type::instances == 0);
{
std::unique_ptr<const type> a1 = boost::make_unique_noinit<const type>();
BOOST_TEST(a1.get() != 0);
BOOST_TEST(type::instances == 1);
a1.reset();
BOOST_TEST(type::instances == 0);
}
return boost::report_errors();
}
#else
int main() {
return 0;
}
#endif

72
test/make_unique_test.cpp Normal file
View File

@@ -0,0 +1,72 @@
/*
* Copyright (c) 2014 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/config.hpp>
#if !defined(BOOST_NO_CXX11_SMART_PTR)
#include <boost/detail/lightweight_test.hpp>
#include <boost/smart_ptr/make_unique_object.hpp>
class 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() {
{
std::unique_ptr<int> a1 = boost::make_unique<int>();
BOOST_TEST(a1.get() != 0);
BOOST_TEST(*a1 == 0);
}
{
std::unique_ptr<const int> a1 = boost::make_unique<const int>();
BOOST_TEST(a1.get() != 0);
BOOST_TEST(*a1 == 0);
}
BOOST_TEST(type::instances == 0);
{
std::unique_ptr<type> a1 = boost::make_unique<type>();
BOOST_TEST(a1.get() != 0);
BOOST_TEST(type::instances == 1);
a1.reset();
BOOST_TEST(type::instances == 0);
}
BOOST_TEST(type::instances == 0);
{
std::unique_ptr<const type> a1 = boost::make_unique<const type>();
BOOST_TEST(a1.get() != 0);
BOOST_TEST(type::instances == 1);
a1.reset();
BOOST_TEST(type::instances == 0);
}
return boost::report_errors();
}
#else
int main() {
return 0;
}
#endif

View File

@@ -0,0 +1,53 @@
/*
* Copyright (c) 2014 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/config.hpp>
#if !defined(BOOST_NO_CXX11_SMART_PTR)
#include <boost/detail/lightweight_test.hpp>
#include <boost/smart_ptr/make_unique_object.hpp>
class type {
public:
static unsigned int instances;
explicit type() {
if (instances == 0) {
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::make_unique<type>();
BOOST_ERROR("make_unique did not throw");
} catch (...) {
BOOST_TEST(type::instances == 0);
}
return boost::report_errors();
}
#else
int main() {
return 0;
}
#endif

View File

@@ -0,0 +1,58 @@
/*
* Copyright (c) 2014 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/config.hpp>
#if !defined(BOOST_NO_CXX11_SMART_PTR)
#include <boost/detail/lightweight_test.hpp>
#include <boost/smart_ptr/make_unique_object.hpp>
struct type {
int x;
int y;
};
int main() {
{
std::unique_ptr<type> a1 = boost::make_unique<type>();
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1->x == 0);
BOOST_TEST(a1->y == 0);
}
{
std::unique_ptr<const type> a1 = boost::make_unique<const type>();
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1->x == 0);
BOOST_TEST(a1->y == 0);
}
#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
{
std::unique_ptr<type> a1 = boost::make_unique<type>({ 1, 2 });
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1->x == 1);
BOOST_TEST(a1->y == 2);
}
{
std::unique_ptr<const type> a1 = boost::make_unique<const type>({ 1, 2 });
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1->x == 1);
BOOST_TEST(a1->y == 2);
}
#endif
return boost::report_errors();
}
#else
int main() {
return 0;
}
#endif

112
test/sa_nullptr_test.cpp Normal file
View File

@@ -0,0 +1,112 @@
//
// shared_array nullptr test
//
// Copyright 2012, 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/shared_array.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <cstddef>
#include <memory>
#if !defined( BOOST_NO_CXX11_NULLPTR )
struct X
{
static int instances;
X()
{
++instances;
}
~X()
{
--instances;
}
private:
X( X const & );
X & operator=( X const & );
};
int X::instances = 0;
int main()
{
{
boost::shared_array<int> p( nullptr );
BOOST_TEST( p.get() == 0 );
BOOST_TEST( p.use_count() == 0 );
BOOST_TEST( p == nullptr );
BOOST_TEST( nullptr == p );
BOOST_TEST( !( p != nullptr ) );
BOOST_TEST( !( nullptr != p ) );
}
{
boost::shared_array<int> p( new int[ 1 ] );
BOOST_TEST( p.get() != 0 );
BOOST_TEST( p.use_count() == 1 );
BOOST_TEST( p != nullptr );
BOOST_TEST( nullptr != p );
BOOST_TEST( !( p == nullptr ) );
BOOST_TEST( !( nullptr == p ) );
p = nullptr;
BOOST_TEST( p.get() == 0 );
BOOST_TEST( p.use_count() == 0 );
BOOST_TEST( p == nullptr );
BOOST_TEST( nullptr == p );
BOOST_TEST( !( p != nullptr ) );
BOOST_TEST( !( nullptr != p ) );
}
{
BOOST_TEST( X::instances == 0 );
boost::shared_array<X> p( new X[ 2 ] );
BOOST_TEST( X::instances == 2 );
BOOST_TEST( p.get() != 0 );
BOOST_TEST( p.use_count() == 1 );
BOOST_TEST( p != nullptr );
BOOST_TEST( nullptr != p );
BOOST_TEST( !( p == nullptr ) );
BOOST_TEST( !( nullptr == p ) );
p = nullptr;
BOOST_TEST( X::instances == 0 );
BOOST_TEST( p.get() == 0 );
BOOST_TEST( p.use_count() == 0 );
BOOST_TEST( p == nullptr );
BOOST_TEST( nullptr == p );
BOOST_TEST( !( p != nullptr ) );
BOOST_TEST( !( nullptr != p ) );
}
return boost::report_errors();
}
#else
int main()
{
return 0;
}
#endif

View File

@@ -0,0 +1,116 @@
#include <boost/config.hpp>
// shared_ptr_alloc11_test.cpp
//
// Test the allocator constructor with a C++11 minimal allocator
//
// Copyright (c) 2005, 2014 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/shared_ptr.hpp>
#include <memory>
#include <cstddef>
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
template< class T > class cxx11_allocator
{
public:
typedef T value_type;
cxx11_allocator()
{
}
template< class Y > cxx11_allocator( cxx11_allocator<Y> const & )
{
}
T * allocate( std::size_t n )
{
return static_cast< T* >( ::operator new( n * sizeof( T ) ) );
}
void deallocate( T * p, std::size_t n )
{
::operator delete( p );
}
};
//
struct D;
struct X
{
static int instances;
X(): deleted_( false )
{
++instances;
}
~X()
{
BOOST_TEST( deleted_ );
--instances;
}
private:
friend struct D;
bool deleted_;
X( X const & );
X & operator=( X const & );
};
int X::instances = 0;
struct D
{
void operator()( X * px ) const
{
px->deleted_ = true;
delete px;
}
};
int main()
{
BOOST_TEST( X::instances == 0 );
boost::shared_ptr<void> pv( new X, D(), cxx11_allocator<X>() );
BOOST_TEST( X::instances == 1 );
pv.reset();
BOOST_TEST( X::instances == 0 );
pv.reset( new X, D(), cxx11_allocator<void>() );
BOOST_TEST( X::instances == 1 );
pv.reset();
BOOST_TEST( X::instances == 0 );
return boost::report_errors();
}
#else // !defined( BOOST_NO_CXX11_ALLOCATOR )
int main()
{
return 0;
}
#endif

View File

@@ -91,7 +91,7 @@ public:
::operator delete( p ); ::operator delete( p );
} }
pointer allocate( size_type n, void const * ) pointer allocate( size_type n, void const * = 0 )
{ {
T * p = static_cast< T* >( ::operator new( n * sizeof( T ) ) ); T * p = static_cast< T* >( ::operator new( n * sizeof( T ) ) );
@@ -107,7 +107,7 @@ public:
void construct( pointer p, T const & t ) void construct( pointer p, T const & t )
{ {
new( p ) T( t ); ::new( p ) T( t );
} }
void destroy( pointer p ) void destroy( pointer p )

View File

@@ -0,0 +1,78 @@
#include <boost/config.hpp>
// shared_ptr_alloc3_test.cpp
//
// Copyright (c) 2005, 2014 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/shared_ptr.hpp>
#include <memory>
#include <cstddef>
//
struct D;
struct X
{
static int instances;
X(): deleted_( false )
{
++instances;
}
~X()
{
BOOST_TEST( deleted_ );
--instances;
}
private:
friend struct D;
bool deleted_;
X( X const & );
X & operator=( X const & );
};
int X::instances = 0;
struct D
{
void operator()( X * px ) const
{
px->deleted_ = true;
delete px;
}
};
int main()
{
BOOST_TEST( X::instances == 0 );
boost::shared_ptr<void> pv( new X, D(), std::allocator<X>() );
BOOST_TEST( X::instances == 1 );
pv.reset();
BOOST_TEST( X::instances == 0 );
pv.reset( new X, D(), std::allocator<void>() );
BOOST_TEST( X::instances == 1 );
pv.reset();
BOOST_TEST( X::instances == 0 );
return boost::report_errors();
}

View File

@@ -1,12 +1,12 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html> <html>
<head> <head>
<title>weak_ptr</title> <title>weak_ptr</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head> </head>
<body text="#000000" bgColor="#ffffff"> <body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
<h1><A href="../../index.htm"><IMG height="86" alt="boost.png (6897 bytes)" src="../../boost.png" width="277" align="middle" <h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
border="0"></A>weak_ptr class template</h1> width="277" align="middle" border="0">weak_ptr class template</h1>
<p><A href="#Introduction">Introduction</A><br> <p><A href="#Introduction">Introduction</A><br>
<A href="#Synopsis">Synopsis</A><br> <A href="#Synopsis">Synopsis</A><br>
<A href="#Members">Members</A><br> <A href="#Members">Members</A><br>
@@ -107,14 +107,14 @@ if(shared_ptr&lt;int&gt; r = q.<A href="#lock" >lock</A>())
<blockquote> <blockquote>
<p>Provides the type of the template parameter T.</p> <p>Provides the type of the template parameter T.</p>
</blockquote> </blockquote>
<h3><a name="default-constructor">constructors</a></h3> <h3><a name="constructors">constructors</a></h3>
<pre>weak_ptr();</pre> <pre><a name="default-constructor">weak_ptr();</a></pre>
<blockquote> <blockquote>
<p><b>Effects:</b> Constructs an <EM>empty</EM> <b>weak_ptr</b>.</p> <p><b>Effects:</b> Constructs an <EM>empty</EM> <b>weak_ptr</b>.</p>
<p><b>Postconditions:</b> <code>use_count() == 0</code>.</p> <p><b>Postconditions:</b> <code>use_count() == 0</code>.</p>
<p><b>Throws:</b> nothing.</p> <p><b>Throws:</b> nothing.</p>
</blockquote><a name="constructors"></a> </blockquote>
<pre>template&lt;class Y&gt; weak_ptr</A>(shared_ptr&lt;Y&gt; const &amp; r); <pre>template&lt;class Y&gt; weak_ptr(shared_ptr&lt;Y&gt; const &amp; r);
weak_ptr(weak_ptr const &amp; r); weak_ptr(weak_ptr const &amp; r);
template&lt;class Y&gt; weak_ptr(weak_ptr&lt;Y&gt; const &amp; r);</pre> template&lt;class Y&gt; weak_ptr(weak_ptr&lt;Y&gt; const &amp; r);</pre>
<blockquote> <blockquote>
@@ -230,8 +230,6 @@ public:
} }
}; };
</pre> </pre>
<p><br>
</p>
<hr> <hr>
<p>$Date$</p> <p>$Date$</p>
<p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. <p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.