mirror of
https://github.com/boostorg/smart_ptr.git
synced 2025-10-04 19:51:02 +02:00
Compare commits
420 Commits
boost-1.49
...
boost-1.56
Author | SHA1 | Date | |
---|---|---|---|
|
0bab2cc658 | ||
|
d28b0d07fc | ||
|
1c83d65701 | ||
|
1d41a328f7 | ||
|
b1beb11a45 | ||
|
bf3e9cc7af | ||
|
506239bef5 | ||
|
d6841e6d71 | ||
|
56ae9f86c1 | ||
|
1a74757cfa | ||
|
07e222217b | ||
|
71c9165119 | ||
|
f32669400c | ||
|
b550e028f5 | ||
|
ed2eaddc5d | ||
|
d523c3423e | ||
|
1968d17d2f | ||
|
e1e99c5ba3 | ||
|
d586469d60 | ||
|
fbb851097f | ||
|
75add10b1d | ||
|
71b2f87e35 | ||
|
c759321782 | ||
|
3e625c07e8 | ||
|
7ff1c65494 | ||
|
75cab39801 | ||
|
38cb523713 | ||
|
5f1d4eae4f | ||
|
adc0cdddff | ||
|
dcfa031de7 | ||
|
8c9e8b5556 | ||
|
d9333e5375 | ||
|
3d279e6c6d | ||
|
c003fba3a0 | ||
|
0c29e86728 | ||
|
016af907bd | ||
|
0337743c8c | ||
|
208bfd78f9 | ||
|
2c32bf91b7 | ||
|
b7ee788845 | ||
|
a56378ee35 | ||
|
443302306e | ||
|
f5402a937e | ||
|
fe04bea979 | ||
|
8fbb5e9e7f | ||
|
0401afc106 | ||
|
b69ca7aaa5 | ||
|
dffbf7c931 | ||
|
5dabdf635c | ||
|
3dbde36076 | ||
|
97a9aac5f0 | ||
|
bd5b684fd3 | ||
|
6ede4ec4c6 | ||
|
aab1328e06 | ||
|
451c71c1bd | ||
|
6341b8802a | ||
|
e274885fd2 | ||
|
82fe5f5095 | ||
|
8c50214e3f | ||
|
21198d07fd | ||
|
b4c8cf3958 | ||
|
77aeaee7a7 | ||
|
677a0777d2 | ||
|
7c7250379b | ||
|
142eb95986 | ||
|
d9f24f882e | ||
|
0fd3947e19 | ||
|
43bc30e576 | ||
|
e0ec2a0aaa | ||
|
5320981cbb | ||
|
d676bac36a | ||
|
ec1c6ed414 | ||
|
ce36b11fd5 | ||
|
eee70bdcab | ||
|
97eed20d9b | ||
|
6b6b63ef37 | ||
|
1bdabdb96b | ||
|
0876e67ac7 | ||
|
fdcb2572a3 | ||
|
71d99e89e9 | ||
|
2dc506f4bc | ||
|
7161dc5842 | ||
|
ec97270c01 | ||
|
b7a759f00f | ||
|
4f2392ffa5 | ||
|
80a06c8883 | ||
|
d0a458616f | ||
|
def81b1941 | ||
|
4f276715ce | ||
|
a47bbfe95c | ||
|
90fe855f1b | ||
|
991436303d | ||
|
b274ed4cc3 | ||
|
870a989fcf | ||
|
5f7a5a5912 | ||
|
82db88f4fa | ||
|
c8df85434e | ||
|
68517b43bd | ||
|
72ac0e8bfd | ||
|
6c7578e206 | ||
|
3149446fe8 | ||
|
b11d734f73 | ||
|
6f5f8babf4 | ||
|
7d7f32c3a9 | ||
|
cb697fe9cb | ||
|
8422135bf2 | ||
|
fd60899dfb | ||
|
a11ab16010 | ||
|
9b9cad3f5b | ||
|
7ce5b6b2a9 | ||
|
7e3ae44bc2 | ||
|
57dc400fbf | ||
|
5f485c2952 | ||
|
260af64027 | ||
|
f837c7f56c | ||
|
54fb49a5be | ||
|
c23bd41c44 | ||
|
a64cc5c41c | ||
|
e1f170cd49 | ||
|
52a5c422a1 | ||
|
d46e3c7cbd | ||
|
5008957bd0 | ||
|
6d73b4aa54 | ||
|
540149f019 | ||
|
9f5822f427 | ||
|
d229ae870c | ||
|
3ac6dbbf08 | ||
|
af5141d492 | ||
|
975d04ac62 | ||
|
90e74511f7 | ||
|
f27b780724 | ||
|
51ab46a07d | ||
|
e8595a05af | ||
|
154a274916 | ||
|
2b033ce05d | ||
|
63a05a3576 | ||
|
aede0039bf | ||
|
72e5fb6fd7 | ||
|
f91e7e9ce7 | ||
|
7fef3bb40b | ||
|
ad658fa5ec | ||
|
83b3b703e0 | ||
|
7806737b52 | ||
|
87e5debdc2 | ||
|
db78d9b2be | ||
|
630e4f49f3 | ||
|
a68db557e8 | ||
|
4de3f36839 | ||
|
4e46cb0609 | ||
|
73153d5797 | ||
|
d7fa365843 | ||
|
6e0ee30543 | ||
|
fed15ad8c5 | ||
|
bba3b446bd | ||
|
4c8a558982 | ||
|
a41b81f1c8 | ||
|
c103ace77a | ||
|
04f456f86d | ||
|
3a188af8d6 | ||
|
b701ed0225 | ||
|
5e9bb19688 | ||
|
a4f853bfbc | ||
|
832ed079b9 | ||
|
d9b29beebe | ||
|
182452e057 | ||
|
5f69684c8f | ||
|
70ffd2921f | ||
|
00aee2c7dc | ||
|
85d8056368 | ||
|
106832df66 | ||
|
2549b818c5 | ||
|
be06392771 | ||
|
56b0853887 | ||
|
f5e6e4063e | ||
|
8767b9580e | ||
|
0e6ddb843e | ||
|
14be9eb90f | ||
|
fa91b7d020 | ||
|
382fb54a52 | ||
|
e4f24e4d3d | ||
|
7d1c527ac0 | ||
|
fc20a29c99 | ||
|
0dc1faa6d3 | ||
|
7b9354fcf3 | ||
|
a7d96b4762 | ||
|
6eefc6bf81 | ||
|
172afff6ca | ||
|
9355404d10 | ||
|
d61e675caf | ||
|
240c66e633 | ||
|
6df3a0295e | ||
|
e497aec58a | ||
|
2d56e85174 | ||
|
579b347267 | ||
|
82e178f043 | ||
|
3178d38137 | ||
|
46d119c385 | ||
|
e39fcad839 | ||
|
e5950adc43 | ||
|
de6dc3a26e | ||
|
06c4dacaf2 | ||
|
72095a4804 | ||
|
dcc1713c59 | ||
|
32a28ec462 | ||
|
f6d5257597 | ||
|
ef817e91d2 | ||
|
43b43aa83a | ||
|
d3a549e93a | ||
|
e8be24c003 | ||
|
c55ffa1cab | ||
|
66f34142be | ||
|
63834f7233 | ||
|
049d0698b7 | ||
|
5ba3312519 | ||
|
bb700870c0 | ||
|
6a218a5ef2 | ||
|
e36689bd5e | ||
|
1c070b3a32 | ||
|
647f67aabf | ||
|
c14369aac9 | ||
|
7ab4f6ce92 | ||
|
bbf0245248 | ||
|
619b168614 | ||
|
4ba8d879f1 | ||
|
c28bef2e9b | ||
|
5f0155cca6 | ||
|
db542de908 | ||
|
5fc6fe474b | ||
|
d42ce87557 | ||
|
67f5e9825e | ||
|
fd52dbc411 | ||
|
6e269872df | ||
|
ecceb710de | ||
|
9863467152 | ||
|
b306c9751f | ||
|
6b0d96af96 | ||
|
c03bfd0b4d | ||
|
8093967da7 | ||
|
7a4ad75f5d | ||
|
f390d9e265 | ||
|
ea22982865 | ||
|
09e77bc8df | ||
|
b3f2ebedbc | ||
|
1209531fe0 | ||
|
6c2ed927e4 | ||
|
7a733263da | ||
|
08e5894510 | ||
|
3551d17566 | ||
|
32fe0b8f26 | ||
|
2d3cc0db7d | ||
|
188602581d | ||
|
88c2baa20b | ||
|
1adf546ddb | ||
|
5e5ff387fa | ||
|
ea55019260 | ||
|
500913db6d | ||
|
19283a3548 | ||
|
cfd4152291 | ||
|
f5adfb0963 | ||
|
8597433028 | ||
|
4da0e2b7fc | ||
|
2346941b15 | ||
|
39ff002d2e | ||
|
fceea2e584 | ||
|
b17205ded7 | ||
|
d74c09dd5a | ||
|
97d32745aa | ||
|
c7b6e56b30 | ||
|
7835914d83 | ||
|
98b92fa83a | ||
|
392885a56a | ||
|
b4594eab3b | ||
|
ddfcc5f417 | ||
|
3f458c68f4 | ||
|
79b229adcd | ||
|
94b6487ca1 | ||
|
cf769b94a7 | ||
|
215771c83d | ||
|
2805ae9362 | ||
|
7adb1cc1ec | ||
|
da9524d637 | ||
|
6b2556edfb | ||
|
cb0797acf0 | ||
|
e8103f9774 | ||
|
71eb435412 | ||
|
4a2dad1574 | ||
|
babc72757d | ||
|
c19cbc1892 | ||
|
d065e4d971 | ||
|
777b86a661 | ||
|
aae5440854 | ||
|
227d2e3255 | ||
|
8bf183b373 | ||
|
5017da2514 | ||
|
3b0b10d06d | ||
|
25e11b20d3 | ||
|
fa513340d7 | ||
|
0e90213746 | ||
|
980070e63f | ||
|
5bdde37414 | ||
|
2aaa913b11 | ||
|
58a46f4e55 | ||
|
8cc50a5ce9 | ||
|
2731957b5b | ||
|
fe06c120b9 | ||
|
c1f41aa925 | ||
|
ffa3327817 | ||
|
999c284109 | ||
|
d512eaaa0f | ||
|
730980f3ee | ||
|
3d50db11b9 | ||
|
aa7562c3e5 | ||
|
c57245d710 | ||
|
945c013a12 | ||
|
df544871d7 | ||
|
89190ca17e | ||
|
5d9312239c | ||
|
93b5cace12 | ||
|
e50c849ab3 | ||
|
dbea328b8b | ||
|
c06ba497a3 | ||
|
734b5d1354 | ||
|
0467af1b83 | ||
|
dc5406aa5a | ||
|
6e873de0fa | ||
|
322bcd7efa | ||
|
bb72e0a092 | ||
|
d8eb2fc105 | ||
|
e7d3987cfb | ||
|
6662ae7242 | ||
|
2ba7b6b99b | ||
|
a30e291022 | ||
|
0b6cab9f2f | ||
|
8c15401ea7 | ||
|
03ae5cdbc6 | ||
|
0c22e55f3e | ||
|
10dcb8db7c | ||
|
f2d4b67a48 | ||
|
16084637a6 | ||
|
3e447c919c | ||
|
b0f72d7b3d | ||
|
4c98df7c57 | ||
|
c2048732d8 | ||
|
5979c1d4bd | ||
|
1029ae0ea5 | ||
|
27a312228c | ||
|
2c29f1e5a9 | ||
|
df364f37f2 | ||
|
33ba2c4722 | ||
|
faf212f4aa | ||
|
57a5441ebf | ||
|
017ab7e2ee | ||
|
e4cb5e131f | ||
|
fbe4ddf4a2 | ||
|
288fb7efcf | ||
|
9d9e6350f2 | ||
|
7e9664396a | ||
|
b4b415553c | ||
|
f76a8d95d8 | ||
|
634866c28a | ||
|
b18b47770d | ||
|
69aa01ec00 | ||
|
e3d2f2ee6b | ||
|
593093e46d | ||
|
9196247dea | ||
|
53d5d086ea | ||
|
1426b0bbdd | ||
|
4fabf9b352 | ||
|
a2fc6e12da | ||
|
c3b51e201b | ||
|
825786d59a | ||
|
37f10d500d | ||
|
3c84388186 | ||
|
a46d405778 | ||
|
2e53b1eb38 | ||
|
37c9a235a5 | ||
|
7083e76666 | ||
|
7aac2f3263 | ||
|
458dffdab9 | ||
|
f7919f0b9f | ||
|
ae34be773f | ||
|
1b91c1dbea | ||
|
577528812a | ||
|
e78efdbb96 | ||
|
3824a6b156 | ||
|
b691be0af9 | ||
|
fa597b877e | ||
|
d0a9d76494 | ||
|
979e76b7e0 | ||
|
c97eebabf7 | ||
|
030a848c5f | ||
|
18bfaea996 | ||
|
502de325ee | ||
|
9f49538b37 | ||
|
2ee5eb70f3 | ||
|
32eb028e13 | ||
|
e824e23ec2 | ||
|
f5cc79f58d | ||
|
28d7e348c1 | ||
|
fc12543814 | ||
|
4b4a62513f | ||
|
0368a37fde | ||
|
3dacec8e1d | ||
|
5758e51948 | ||
|
287d329276 | ||
|
d34d638998 | ||
|
6f2bdddfa0 | ||
|
9227371881 | ||
|
e88dd9fc77 | ||
|
fa3c56747d | ||
|
fbc6919eae | ||
|
dc3ffc5f4b | ||
|
0610947c4a | ||
|
9c55fbc6c2 | ||
|
68c939ec5a | ||
|
a378c8c278 | ||
|
905a3711db | ||
|
ed32efcc51 | ||
|
eb0ff40d62 | ||
|
ad1b344405 |
@@ -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>
|
||||
<head>
|
||||
<title>Smart Pointer Changes</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
</head>
|
||||
<body bgcolor="#ffffff" text="#000000">
|
||||
<h1><A href="../../index.htm"><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="277" height="86"
|
||||
border="0"></A>Smart Pointer Changes</h1>
|
||||
<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">Smart Pointer Changes</h1>
|
||||
<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
|
||||
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>
|
||||
</ul>
|
||||
<hr>
|
||||
<p>Revised 1 February 2002</p>
|
||||
<p>$Date$</p>
|
||||
<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
|
||||
copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
|
||||
|
@@ -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>
|
||||
<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">
|
||||
</head>
|
||||
<body bgcolor="white" style="MARGIN-LEFT: 5%; MARGIN-RIGHT: 5%">
|
||||
<table border="0" width="100%">
|
||||
<tr>
|
||||
<td width="277"><A href="../../index.htm"> <img src="../../boost.png" alt="boost.png (6897 bytes)" width="277" height="86" border="0"></A>
|
||||
</td>
|
||||
<td align="center">
|
||||
<h1>enable_shared_from_this.hpp</h1>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" height="64"> </td>
|
||||
</tr>
|
||||
</table>
|
||||
<h3><a name="Purpose">Purpose</a></h3>
|
||||
<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">enable_shared_from_this</h1>
|
||||
<h2><a name="Purpose">Purpose</a></h2>
|
||||
<p>
|
||||
The header <STRONG><boost/enable_shared_from_this.hpp></STRONG> defines
|
||||
the class template <STRONG>enable_shared_from_this</STRONG>. It is used as a
|
||||
@@ -27,7 +17,7 @@
|
||||
<P><STRONG>enable_shared_from_this<T></STRONG> defines two member functions
|
||||
called <STRONG>shared_from_this</STRONG> that return a <STRONG>shared_ptr<T></STRONG>
|
||||
and <STRONG>shared_ptr<T const></STRONG>, depending on constness, to <STRONG>this</STRONG>.</P>
|
||||
<h3><a name="Example">Example</a></h3>
|
||||
<h2><a name="Example">Example</a></h2>
|
||||
<pre>
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
@@ -86,9 +76,9 @@ public:
|
||||
<b>Postconditions:</b> <tt>r.get() == this</tt>.
|
||||
</p>
|
||||
</blockquote>
|
||||
<p>$Date$</p>
|
||||
<p>
|
||||
<br>
|
||||
<small>Copyright <20> 2002, 2003 by Peter Dimov. Distributed under the Boost Software License, Version
|
||||
<small>Copyright © 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
|
||||
copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
|
||||
</body>
|
||||
|
135
include/boost/detail/lightweight_thread.hpp
Normal file
135
include/boost/detail/lightweight_thread.hpp
Normal file
@@ -0,0 +1,135 @@
|
||||
#ifndef BOOST_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// boost/detail/lightweight_thread.hpp
|
||||
//
|
||||
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
|
||||
// Copyright (c) 2008 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <memory>
|
||||
#include <cerrno>
|
||||
|
||||
// pthread_create, pthread_join
|
||||
|
||||
#if defined( BOOST_HAS_PTHREADS )
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#else
|
||||
|
||||
#include <windows.h>
|
||||
#include <process.h>
|
||||
|
||||
typedef HANDLE pthread_t;
|
||||
|
||||
int pthread_create( pthread_t * thread, void const *, unsigned (__stdcall * start_routine) (void*), void* arg )
|
||||
{
|
||||
HANDLE h = (HANDLE)_beginthreadex( 0, 0, start_routine, arg, 0, 0 );
|
||||
|
||||
if( h != 0 )
|
||||
{
|
||||
*thread = h;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return EAGAIN;
|
||||
}
|
||||
}
|
||||
|
||||
int pthread_join( pthread_t thread, void ** /*value_ptr*/ )
|
||||
{
|
||||
::WaitForSingleObject( thread, INFINITE );
|
||||
::CloseHandle( thread );
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// template<class F> int lw_thread_create( pthread_t & pt, F f );
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class lw_abstract_thread
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~lw_abstract_thread() {}
|
||||
virtual void run() = 0;
|
||||
};
|
||||
|
||||
#if defined( BOOST_HAS_PTHREADS )
|
||||
|
||||
extern "C" void * lw_thread_routine( void * pv )
|
||||
{
|
||||
std::auto_ptr<lw_abstract_thread> pt( static_cast<lw_abstract_thread *>( pv ) );
|
||||
|
||||
pt->run();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
unsigned __stdcall lw_thread_routine( void * pv )
|
||||
{
|
||||
std::auto_ptr<lw_abstract_thread> pt( static_cast<lw_abstract_thread *>( pv ) );
|
||||
|
||||
pt->run();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template<class F> class lw_thread_impl: public lw_abstract_thread
|
||||
{
|
||||
public:
|
||||
|
||||
explicit lw_thread_impl( F f ): f_( f )
|
||||
{
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
f_();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
F f_;
|
||||
};
|
||||
|
||||
template<class F> int lw_thread_create( pthread_t & pt, F f )
|
||||
{
|
||||
std::auto_ptr<lw_abstract_thread> p( new lw_thread_impl<F>( f ) );
|
||||
|
||||
int r = pthread_create( &pt, 0, lw_thread_routine, p.get() );
|
||||
|
||||
if( r == 0 )
|
||||
{
|
||||
p.release();
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED
|
23
include/boost/detail/quick_allocator.hpp
Normal file
23
include/boost/detail/quick_allocator.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef BOOST_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// detail/quick_allocator.hpp
|
||||
//
|
||||
// Copyright (c) 2003 David Abrahams
|
||||
// Copyright (c) 2003 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/quick_allocator.hpp>
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED
|
@@ -1,135 +0,0 @@
|
||||
#ifndef BOOST_DETAIL_SP_TYPEINFO_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_SP_TYPEINFO_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// detail/sp_typeinfo.hpp
|
||||
//
|
||||
// Copyright 2007 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#if defined( BOOST_NO_TYPEID )
|
||||
|
||||
#include <boost/current_function.hpp>
|
||||
#include <functional>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class sp_typeinfo
|
||||
{
|
||||
private:
|
||||
|
||||
sp_typeinfo( sp_typeinfo const& );
|
||||
sp_typeinfo& operator=( sp_typeinfo const& );
|
||||
|
||||
char const * name_;
|
||||
|
||||
public:
|
||||
|
||||
explicit sp_typeinfo( char const * name ): name_( name )
|
||||
{
|
||||
}
|
||||
|
||||
bool operator==( sp_typeinfo const& rhs ) const
|
||||
{
|
||||
return this == &rhs;
|
||||
}
|
||||
|
||||
bool operator!=( sp_typeinfo const& rhs ) const
|
||||
{
|
||||
return this != &rhs;
|
||||
}
|
||||
|
||||
bool before( sp_typeinfo const& rhs ) const
|
||||
{
|
||||
return std::less< sp_typeinfo const* >()( this, &rhs );
|
||||
}
|
||||
|
||||
char const* name() const
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
};
|
||||
|
||||
template<class T> struct sp_typeid_
|
||||
{
|
||||
static sp_typeinfo ti_;
|
||||
|
||||
static char const * name()
|
||||
{
|
||||
return BOOST_CURRENT_FUNCTION;
|
||||
}
|
||||
};
|
||||
|
||||
#if defined(__SUNPRO_CC)
|
||||
// see #4199, the Sun Studio compiler gets confused about static initialization
|
||||
// constructor arguments. But an assignment works just fine.
|
||||
template<class T> sp_typeinfo sp_typeid_< T >::ti_ = sp_typeid_< T >::name();
|
||||
#else
|
||||
template<class T> sp_typeinfo sp_typeid_< T >::ti_(sp_typeid_< T >::name());
|
||||
#endif
|
||||
|
||||
template<class T> struct sp_typeid_< T & >: sp_typeid_< T >
|
||||
{
|
||||
};
|
||||
|
||||
template<class T> struct sp_typeid_< T const >: sp_typeid_< T >
|
||||
{
|
||||
};
|
||||
|
||||
template<class T> struct sp_typeid_< T volatile >: sp_typeid_< T >
|
||||
{
|
||||
};
|
||||
|
||||
template<class T> struct sp_typeid_< T const volatile >: sp_typeid_< T >
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#define BOOST_SP_TYPEID(T) (boost::detail::sp_typeid_<T>::ti_)
|
||||
|
||||
#else
|
||||
|
||||
#include <typeinfo>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
#if defined( BOOST_NO_STD_TYPEINFO )
|
||||
|
||||
typedef ::type_info sp_typeinfo;
|
||||
|
||||
#else
|
||||
|
||||
typedef std::type_info sp_typeinfo;
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#define BOOST_SP_TYPEID(T) typeid(T)
|
||||
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_SP_TYPEINFO_HPP_INCLUDED
|
@@ -1,33 +0,0 @@
|
||||
// Copyright Peter Dimov and David Abrahams 2002.
|
||||
// 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)
|
||||
#ifndef GET_POINTER_DWA20021219_HPP
|
||||
# define GET_POINTER_DWA20021219_HPP
|
||||
|
||||
// In order to avoid circular dependencies with Boost.TR1
|
||||
// we make sure that our include of <memory> doesn't try to
|
||||
// pull in the TR1 headers: that's why we use this header
|
||||
// rather than including <memory> directly:
|
||||
# include <boost/config/no_tr1/memory.hpp> // std::auto_ptr
|
||||
|
||||
namespace boost {
|
||||
|
||||
// get_pointer(p) extracts a ->* capable pointer from p
|
||||
|
||||
template<class T> T * get_pointer(T * p)
|
||||
{
|
||||
return p;
|
||||
}
|
||||
|
||||
// get_pointer(shared_ptr<T> const & p) has been moved to shared_ptr.hpp
|
||||
|
||||
template<class T> T * get_pointer(std::auto_ptr<T> const& p)
|
||||
{
|
||||
return p.get();
|
||||
}
|
||||
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // GET_POINTER_DWA20021219_HPP
|
14
include/boost/make_unique.hpp
Normal file
14
include/boost/make_unique.hpp
Normal 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
|
@@ -1,53 +0,0 @@
|
||||
#ifndef BOOST_MEMORY_ORDER_HPP_INCLUDED
|
||||
#define BOOST_MEMORY_ORDER_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// boost/memory_order.hpp
|
||||
//
|
||||
// Defines enum boost::memory_order per the C++0x working draft
|
||||
//
|
||||
// Copyright (c) 2008, 2009 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
|
||||
{
|
||||
|
||||
//
|
||||
// Enum values are chosen so that code that needs to insert
|
||||
// a trailing fence for acquire semantics can use a single
|
||||
// test such as:
|
||||
//
|
||||
// if( mo & memory_order_acquire ) { ...fence... }
|
||||
//
|
||||
// For leading fences one can use:
|
||||
//
|
||||
// if( mo & memory_order_release ) { ...fence... }
|
||||
//
|
||||
// Architectures such as Alpha that need a fence on consume
|
||||
// can use:
|
||||
//
|
||||
// if( mo & ( memory_order_acquire | memory_order_consume ) ) { ...fence... }
|
||||
//
|
||||
|
||||
enum memory_order
|
||||
{
|
||||
memory_order_relaxed = 0,
|
||||
memory_order_acquire = 1,
|
||||
memory_order_release = 2,
|
||||
memory_order_acq_rel = 3, // acquire | release
|
||||
memory_order_seq_cst = 7, // acq_rel | 4
|
||||
memory_order_consume = 8
|
||||
};
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MEMORY_ORDER_HPP_INCLUDED
|
181
include/boost/smart_ptr/allocate_shared_array.hpp
Normal file
181
include/boost/smart_ptr/allocate_shared_array.hpp
Normal 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)
|
||||
*/
|
||||
#ifndef BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP
|
||||
#define BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP
|
||||
|
||||
#include <boost/smart_ptr/detail/array_count_impl.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_if_array.hpp>
|
||||
|
||||
namespace boost {
|
||||
template<class T, class A>
|
||||
inline typename boost::detail::sp_if_array<T>::type
|
||||
allocate_shared(const A& allocator, std::size_t size) {
|
||||
typedef typename boost::detail::array_inner<T>::type T1;
|
||||
typedef typename boost::detail::array_base<T1>::type T2;
|
||||
typedef boost::detail::ms_init_tag R1;
|
||||
typedef boost::detail::as_allocator<A, T, R1> A1;
|
||||
typedef boost::detail::ms_in_allocator_tag D1;
|
||||
std::size_t n1 = size * boost::detail::array_total<T1>::size;
|
||||
T1* p1 = 0;
|
||||
T2* p2 = 0;
|
||||
D1 d1;
|
||||
A1 a1(allocator, size, &p2);
|
||||
shared_ptr<T> s1(p1, d1, a1);
|
||||
A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter());
|
||||
a2->set(0);
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
boost::detail::as_init(allocator, p2, n1);
|
||||
#else
|
||||
boost::detail::ms_init(p2, n1);
|
||||
#endif
|
||||
a2->set(p2);
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
return shared_ptr<T>(s1, p1);
|
||||
}
|
||||
|
||||
template<class T, class A>
|
||||
inline typename boost::detail::sp_if_size_array<T>::type
|
||||
allocate_shared(const A& allocator) {
|
||||
typedef typename boost::detail::array_inner<T>::type T1;
|
||||
typedef typename boost::detail::array_base<T1>::type T2;
|
||||
typedef boost::detail::ms_init_tag R1;
|
||||
typedef boost::detail::as_allocator<A, T, R1> A1;
|
||||
typedef boost::detail::ms_in_allocator_tag D1;
|
||||
enum {
|
||||
N = boost::detail::array_total<T>::size
|
||||
};
|
||||
T1* p1 = 0;
|
||||
T2* p2 = 0;
|
||||
D1 d1;
|
||||
A1 a1(allocator, &p2);
|
||||
shared_ptr<T> s1(p1, d1, a1);
|
||||
A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter());
|
||||
a2->set(0);
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
boost::detail::as_init(allocator, p2, N);
|
||||
#else
|
||||
boost::detail::ms_init(p2, N);
|
||||
#endif
|
||||
a2->set(p2);
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
return shared_ptr<T>(s1, p1);
|
||||
}
|
||||
|
||||
template<class T, class A>
|
||||
inline typename boost::detail::sp_if_array<T>::type
|
||||
allocate_shared(const A& allocator, std::size_t size,
|
||||
const typename boost::detail::array_inner<T>::type& value) {
|
||||
typedef typename boost::detail::array_inner<T>::type T1;
|
||||
typedef typename boost::detail::array_base<T1>::type T2;
|
||||
typedef const T2 T3;
|
||||
typedef boost::detail::ms_init_tag R1;
|
||||
typedef boost::detail::as_allocator<A, T, R1> A1;
|
||||
typedef boost::detail::ms_in_allocator_tag D1;
|
||||
enum {
|
||||
M = boost::detail::array_total<T1>::size
|
||||
};
|
||||
std::size_t n1 = M * size;
|
||||
T1* p1 = 0;
|
||||
T2* p2 = 0;
|
||||
T3* p3 = reinterpret_cast<T3*>(&value);
|
||||
D1 d1;
|
||||
A1 a1(allocator, size, &p2);
|
||||
shared_ptr<T> s1(p1, d1, a1);
|
||||
A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter());
|
||||
a2->set(0);
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
boost::detail::as_init<T2, A, M>(allocator, p2, n1, p3);
|
||||
#else
|
||||
boost::detail::ms_init<T2, M>(p2, n1, p3);
|
||||
#endif
|
||||
a2->set(p2);
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
return shared_ptr<T>(s1, p1);
|
||||
}
|
||||
|
||||
template<class T, class A>
|
||||
inline typename boost::detail::sp_if_size_array<T>::type
|
||||
allocate_shared(const A& allocator,
|
||||
const typename boost::detail::array_inner<T>::type& value) {
|
||||
typedef typename boost::detail::array_inner<T>::type T1;
|
||||
typedef typename boost::detail::array_base<T1>::type T2;
|
||||
typedef const T2 T3;
|
||||
typedef boost::detail::ms_init_tag R1;
|
||||
typedef boost::detail::as_allocator<A, T, R1> A1;
|
||||
typedef boost::detail::ms_in_allocator_tag D1;
|
||||
enum {
|
||||
N = boost::detail::array_total<T>::size,
|
||||
M = boost::detail::array_total<T1>::size
|
||||
};
|
||||
T1* p1 = 0;
|
||||
T2* p2 = 0;
|
||||
T3* p3 = reinterpret_cast<T3*>(&value);
|
||||
D1 d1;
|
||||
A1 a1(allocator, &p2);
|
||||
shared_ptr<T> s1(p1, d1, a1);
|
||||
A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter());
|
||||
a2->set(0);
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
boost::detail::as_init<T2, A, M>(allocator, p2, N, p3);
|
||||
#else
|
||||
boost::detail::ms_init<T2, M>(p2, N, p3);
|
||||
#endif
|
||||
a2->set(p2);
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
return shared_ptr<T>(s1, p1);
|
||||
}
|
||||
|
||||
template<class T, class A>
|
||||
inline typename boost::detail::sp_if_array<T>::type
|
||||
allocate_shared_noinit(const A& allocator, std::size_t size) {
|
||||
typedef typename boost::detail::array_inner<T>::type T1;
|
||||
typedef typename boost::detail::array_base<T1>::type T2;
|
||||
typedef boost::detail::ms_noinit_tag R1;
|
||||
typedef boost::detail::as_allocator<A, T, R1> A1;
|
||||
typedef boost::detail::ms_in_allocator_tag D1;
|
||||
std::size_t n1 = size * boost::detail::array_total<T1>::size;
|
||||
T1* p1 = 0;
|
||||
T2* p2 = 0;
|
||||
D1 d1;
|
||||
A1 a1(allocator, size, &p2);
|
||||
shared_ptr<T> s1(p1, d1, a1);
|
||||
A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter());
|
||||
a2->set(0);
|
||||
boost::detail::ms_noinit(p2, n1);
|
||||
a2->set(p2);
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
return shared_ptr<T>(s1, p1);
|
||||
}
|
||||
|
||||
template<class T, class A>
|
||||
inline typename boost::detail::sp_if_size_array<T>::type
|
||||
allocate_shared_noinit(const A& allocator) {
|
||||
typedef typename boost::detail::array_inner<T>::type T1;
|
||||
typedef typename boost::detail::array_base<T1>::type T2;
|
||||
typedef boost::detail::ms_noinit_tag R1;
|
||||
typedef boost::detail::as_allocator<A, T, R1> A1;
|
||||
typedef boost::detail::ms_in_allocator_tag D1;
|
||||
enum {
|
||||
N = boost::detail::array_total<T>::size
|
||||
};
|
||||
T1* p1 = 0;
|
||||
T2* p2 = 0;
|
||||
D1 d1;
|
||||
A1 a1(allocator, &p2);
|
||||
shared_ptr<T> s1(p1, d1, a1);
|
||||
A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter());
|
||||
a2->set(0);
|
||||
boost::detail::ms_noinit(p2, N);
|
||||
a2->set(p2);
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
return shared_ptr<T>(s1, p1);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
318
include/boost/smart_ptr/detail/array_allocator.hpp
Normal file
318
include/boost/smart_ptr/detail/array_allocator.hpp
Normal file
@@ -0,0 +1,318 @@
|
||||
/*
|
||||
* 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/align/align.hpp>
|
||||
#include <boost/smart_ptr/detail/array_traits.hpp>
|
||||
#include <boost/smart_ptr/detail/array_utility.hpp>
|
||||
#include <boost/type_traits/alignment_of.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace detail {
|
||||
struct ms_init_tag { };
|
||||
struct ms_noinit_tag { };
|
||||
|
||||
template<class T>
|
||||
struct ms_allocator_state;
|
||||
|
||||
template<class T>
|
||||
struct ms_allocator_state<T[]> {
|
||||
typedef typename array_base<T>::type type;
|
||||
|
||||
ms_allocator_state(std::size_t size_,
|
||||
type** result_)
|
||||
: size(size_ * array_total<T>::size),
|
||||
result(result_) {
|
||||
}
|
||||
|
||||
std::size_t size;
|
||||
|
||||
union {
|
||||
type** result;
|
||||
type* object;
|
||||
};
|
||||
};
|
||||
|
||||
template<class T, std::size_t N>
|
||||
struct ms_allocator_state<T[N]> {
|
||||
typedef typename array_base<T>::type type;
|
||||
|
||||
ms_allocator_state(type** result_)
|
||||
: result(result_) {
|
||||
}
|
||||
|
||||
enum {
|
||||
size = array_total<T[N]>::size
|
||||
};
|
||||
|
||||
union {
|
||||
type** result;
|
||||
type* object;
|
||||
};
|
||||
};
|
||||
|
||||
template<class A, class T, class R>
|
||||
class as_allocator
|
||||
: public A {
|
||||
template<class A_, class T_, class R_>
|
||||
friend class as_allocator;
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
typedef std::allocator_traits<A> AT;
|
||||
typedef typename AT::template rebind_alloc<char> CA;
|
||||
typedef typename AT::template rebind_traits<char> CT;
|
||||
#else
|
||||
typedef typename A::template rebind<char>::other CA;
|
||||
#endif
|
||||
|
||||
public:
|
||||
typedef A allocator_type;
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
typedef typename AT::value_type value_type;
|
||||
typedef typename AT::pointer pointer;
|
||||
typedef typename AT::const_pointer const_pointer;
|
||||
typedef typename AT::void_pointer void_pointer;
|
||||
typedef typename AT::const_void_pointer const_void_pointer;
|
||||
typedef typename AT::size_type size_type;
|
||||
typedef typename AT::difference_type difference_type;
|
||||
#else
|
||||
typedef typename A::value_type value_type;
|
||||
typedef typename A::pointer pointer;
|
||||
typedef typename A::const_pointer const_pointer;
|
||||
typedef typename A::size_type size_type;
|
||||
typedef typename A::difference_type difference_type;
|
||||
typedef typename A::reference reference;
|
||||
typedef typename A::const_reference const_reference;
|
||||
typedef void* void_pointer;
|
||||
typedef const void* const_void_pointer;
|
||||
#endif
|
||||
|
||||
template<class U>
|
||||
struct rebind {
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
typedef as_allocator<typename AT::
|
||||
template rebind_alloc<U>, T, R> other;
|
||||
#else
|
||||
typedef as_allocator<typename A::
|
||||
template rebind<U>::other, T, R> other;
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef typename array_base<T>::type type;
|
||||
|
||||
as_allocator(const A& allocator_, type** result)
|
||||
: A(allocator_),
|
||||
data(result) {
|
||||
}
|
||||
|
||||
as_allocator(const A& allocator_, std::size_t size,
|
||||
type** result)
|
||||
: A(allocator_),
|
||||
data(size, result) {
|
||||
}
|
||||
|
||||
template<class U>
|
||||
as_allocator(const as_allocator<U, T, R>& other)
|
||||
: A(other.allocator()),
|
||||
data(other.data) {
|
||||
}
|
||||
|
||||
pointer allocate(size_type count, const_void_pointer = 0) {
|
||||
enum {
|
||||
M = boost::alignment_of<type>::value
|
||||
};
|
||||
std::size_t n1 = count * sizeof(value_type);
|
||||
std::size_t n2 = data.size * sizeof(type);
|
||||
std::size_t n3 = n2 + M;
|
||||
CA ca(allocator());
|
||||
void* p1 = ca.allocate(n1 + n3);
|
||||
void* p2 = static_cast<char*>(p1) + n1;
|
||||
(void)boost::alignment::align(M, n2, p2, n3);
|
||||
*data.result = static_cast<type*>(p2);
|
||||
return static_cast<value_type*>(p1);
|
||||
}
|
||||
|
||||
void deallocate(pointer memory, size_type count) {
|
||||
enum {
|
||||
M = boost::alignment_of<type>::value
|
||||
};
|
||||
std::size_t n1 = count * sizeof(value_type);
|
||||
std::size_t n2 = data.size * sizeof(type) + M;
|
||||
char* p1 = reinterpret_cast<char*>(memory);
|
||||
CA ca(allocator());
|
||||
ca.deallocate(p1, n1 + n2);
|
||||
}
|
||||
|
||||
const A& allocator() const {
|
||||
return static_cast<const A&>(*this);
|
||||
}
|
||||
|
||||
A& allocator() {
|
||||
return static_cast<A&>(*this);
|
||||
}
|
||||
|
||||
void set(type* memory) {
|
||||
data.object = memory;
|
||||
}
|
||||
|
||||
void operator()() {
|
||||
if (data.object) {
|
||||
R tag;
|
||||
release(tag);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void release(ms_init_tag) {
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
as_destroy(allocator(), data.object, data.size);
|
||||
#else
|
||||
ms_destroy(data.object, data.size);
|
||||
#endif
|
||||
}
|
||||
|
||||
void release(ms_noinit_tag) {
|
||||
ms_destroy(data.object, data.size);
|
||||
}
|
||||
|
||||
ms_allocator_state<T> data;
|
||||
};
|
||||
|
||||
template<class A1, class A2, class T, class R>
|
||||
bool operator==(const as_allocator<A1, T, R>& a1,
|
||||
const as_allocator<A2, T, R>& a2) {
|
||||
return a1.allocator() == a2.allocator();
|
||||
}
|
||||
|
||||
template<class A1, class A2, class T, class R>
|
||||
bool operator!=(const as_allocator<A1, T, R>& a1,
|
||||
const as_allocator<A2, T, R>& a2) {
|
||||
return a1.allocator() != a2.allocator();
|
||||
}
|
||||
|
||||
template<class T, class Y = char>
|
||||
class ms_allocator;
|
||||
|
||||
template<class T, class Y>
|
||||
class ms_allocator {
|
||||
template<class T_, class Y_>
|
||||
friend class ms_allocator;
|
||||
|
||||
public:
|
||||
typedef typename array_base<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<class U>
|
||||
struct rebind {
|
||||
typedef ms_allocator<T, U> other;
|
||||
};
|
||||
|
||||
ms_allocator(type** result)
|
||||
: data(result) {
|
||||
}
|
||||
|
||||
ms_allocator(std::size_t size, type** result)
|
||||
: data(size, result) {
|
||||
}
|
||||
|
||||
template<class U>
|
||||
ms_allocator(const ms_allocator<T, U>& other)
|
||||
: data(other.data) {
|
||||
}
|
||||
|
||||
pointer allocate(size_type count, const void* = 0) {
|
||||
enum {
|
||||
M = boost::alignment_of<type>::value
|
||||
};
|
||||
std::size_t n1 = count * sizeof(Y);
|
||||
std::size_t n2 = data.size * sizeof(type);
|
||||
std::size_t n3 = n2 + M;
|
||||
void* p1 = ::operator new(n1 + n3);
|
||||
void* p2 = static_cast<char*>(p1) + n1;
|
||||
(void)boost::alignment::align(M, n2, p2, n3);
|
||||
*data.result = static_cast<type*>(p2);
|
||||
return static_cast<Y*>(p1);
|
||||
}
|
||||
|
||||
void deallocate(pointer memory, size_type) {
|
||||
void* p1 = memory;
|
||||
::operator delete(p1);
|
||||
}
|
||||
|
||||
#if defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
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(Y)
|
||||
};
|
||||
return N;
|
||||
}
|
||||
|
||||
void construct(pointer memory, const_reference value) {
|
||||
void* p1 = memory;
|
||||
::new(p1) Y(value);
|
||||
}
|
||||
|
||||
void destroy(pointer memory) {
|
||||
(void)memory;
|
||||
memory->~Y();
|
||||
}
|
||||
#endif
|
||||
|
||||
void set(type* memory) {
|
||||
data.object = memory;
|
||||
}
|
||||
|
||||
void operator()() {
|
||||
if (data.object) {
|
||||
ms_destroy(data.object, data.size);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
ms_allocator_state<T> data;
|
||||
};
|
||||
|
||||
template<class T, class Y1, class Y2>
|
||||
bool operator==(const ms_allocator<T, Y1>&,
|
||||
const ms_allocator<T, Y2>&) {
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class T, class Y1, class Y2>
|
||||
bool operator!=(const ms_allocator<T, Y1>&,
|
||||
const ms_allocator<T, Y2>&) {
|
||||
return false;
|
||||
}
|
||||
|
||||
class ms_in_allocator_tag {
|
||||
public:
|
||||
void operator()(const void*) {
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
67
include/boost/smart_ptr/detail/array_count_impl.hpp
Normal file
67
include/boost/smart_ptr/detail/array_count_impl.hpp
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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_ARRAY_COUNT_IMPL_HPP
|
||||
#define BOOST_SMART_PTR_DETAIL_ARRAY_COUNT_IMPL_HPP
|
||||
|
||||
#include <boost/smart_ptr/detail/array_allocator.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_counted_impl.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace detail {
|
||||
template<class P, class A>
|
||||
class sp_counted_impl_pda<P, ms_in_allocator_tag, A>
|
||||
: public sp_counted_base {
|
||||
typedef ms_in_allocator_tag D;
|
||||
typedef sp_counted_impl_pda<P, D, A> Y;
|
||||
public:
|
||||
sp_counted_impl_pda(P, D, const A& allocator_)
|
||||
: allocator(allocator_) {
|
||||
}
|
||||
|
||||
virtual void dispose() {
|
||||
allocator();
|
||||
}
|
||||
|
||||
virtual void destroy() {
|
||||
#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_traits<Y> YT;
|
||||
#else
|
||||
typedef typename A::template rebind<Y>::other YA;
|
||||
#endif
|
||||
YA a1(allocator);
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
YT::destroy(a1, this);
|
||||
YT::deallocate(a1, this, 1);
|
||||
#else
|
||||
this->~Y();
|
||||
a1.deallocate(this, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual void* get_deleter(const sp_typeinfo&) {
|
||||
return &reinterpret_cast<char&>(allocator);
|
||||
}
|
||||
|
||||
virtual void* get_untyped_deleter() {
|
||||
return &reinterpret_cast<char&>(allocator);
|
||||
}
|
||||
|
||||
private:
|
||||
sp_counted_impl_pda(const sp_counted_impl_pda&);
|
||||
sp_counted_impl_pda& operator=(const sp_counted_impl_pda&);
|
||||
|
||||
A allocator;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
60
include/boost/smart_ptr/detail/array_traits.hpp
Normal file
60
include/boost/smart_ptr/detail/array_traits.hpp
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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_TRAITS_HPP
|
||||
#define BOOST_SMART_PTR_DETAIL_ARRAY_TRAITS_HPP
|
||||
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace detail {
|
||||
template<class T>
|
||||
struct array_base {
|
||||
typedef typename boost::remove_cv<T>::type type;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct array_base<T[]> {
|
||||
typedef typename array_base<T>::type type;
|
||||
};
|
||||
|
||||
template<class T, std::size_t N>
|
||||
struct array_base<T[N]> {
|
||||
typedef typename array_base<T>::type type;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct array_total {
|
||||
enum {
|
||||
size = 1
|
||||
};
|
||||
};
|
||||
|
||||
template<class T, std::size_t N>
|
||||
struct array_total<T[N]> {
|
||||
enum {
|
||||
size = N * array_total<T>::size
|
||||
};
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct array_inner;
|
||||
|
||||
template<class T>
|
||||
struct array_inner<T[]> {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<class T, std::size_t N>
|
||||
struct array_inner<T[N]> {
|
||||
typedef T type;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
214
include/boost/smart_ptr/detail/array_utility.hpp
Normal file
214
include/boost/smart_ptr/detail/array_utility.hpp
Normal file
@@ -0,0 +1,214 @@
|
||||
/*
|
||||
* 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_UTILITY_HPP
|
||||
#define BOOST_SMART_PTR_DETAIL_ARRAY_UTILITY_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/type_traits/has_trivial_constructor.hpp>
|
||||
#include <boost/type_traits/has_trivial_destructor.hpp>
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
#include <memory>
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace detail {
|
||||
typedef boost::true_type ms_is_trivial;
|
||||
typedef boost::false_type ms_no_trivial;
|
||||
|
||||
template<class T>
|
||||
inline void ms_destroy(T*, std::size_t, ms_is_trivial) {
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline void ms_destroy(T* memory, std::size_t size, ms_no_trivial) {
|
||||
for (std::size_t i = size; i > 0;) {
|
||||
memory[--i].~T();
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline void ms_destroy(T* memory, std::size_t size) {
|
||||
boost::has_trivial_destructor<T> trivial;
|
||||
ms_destroy(memory, size, trivial);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline void ms_init(T* memory, std::size_t size, ms_is_trivial) {
|
||||
for (std::size_t i = 0; i < size; i++) {
|
||||
void* p1 = memory + i;
|
||||
::new(p1) T();
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline void ms_init(T* memory, std::size_t size, ms_no_trivial) {
|
||||
#if !defined(BOOST_NO_EXCEPTIONS)
|
||||
std::size_t i = 0;
|
||||
try {
|
||||
for (; i < size; i++) {
|
||||
void* p1 = memory + i;
|
||||
::new(p1) T();
|
||||
}
|
||||
} catch (...) {
|
||||
ms_destroy(memory, i);
|
||||
throw;
|
||||
}
|
||||
#else
|
||||
for (std::size_t i = 0; i < size; i++) {
|
||||
void* p1 = memory + i;
|
||||
::new(p1) T();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline void ms_init(T* memory, std::size_t size) {
|
||||
boost::has_trivial_default_constructor<T> trivial;
|
||||
ms_init(memory, size, trivial);
|
||||
}
|
||||
|
||||
template<class T, std::size_t N>
|
||||
inline void ms_init(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
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
template<class T, class A>
|
||||
inline void as_destroy(const A& allocator, T* memory,
|
||||
std::size_t size) {
|
||||
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 = size; i > 0;) {
|
||||
TT::destroy(a2, &memory[--i]);
|
||||
}
|
||||
}
|
||||
|
||||
template<class T, class 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<class T, class 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)
|
||||
std::size_t i = 0;
|
||||
try {
|
||||
for (; i < size; i++) {
|
||||
TT::construct(a2, memory + i);
|
||||
}
|
||||
} catch (...) {
|
||||
as_destroy(a2, memory, i);
|
||||
throw;
|
||||
}
|
||||
#else
|
||||
for (std::size_t i = 0; i < size; i++) {
|
||||
TT::construct(a2, memory + i);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
template<class T, class A>
|
||||
inline void as_init(const A& allocator, T* memory, std::size_t size) {
|
||||
boost::has_trivial_default_constructor<T> trivial;
|
||||
as_init(allocator, memory, size, trivial);
|
||||
}
|
||||
|
||||
template<class T, class 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
|
||||
}
|
||||
#endif
|
||||
|
||||
template<class T>
|
||||
inline void ms_noinit(T*, std::size_t, ms_is_trivial) {
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline void ms_noinit(T* memory, std::size_t size, ms_no_trivial) {
|
||||
#if !defined(BOOST_NO_EXCEPTIONS)
|
||||
std::size_t i = 0;
|
||||
try {
|
||||
for (; i < size; i++) {
|
||||
void* p1 = memory + i;
|
||||
::new(p1) T;
|
||||
}
|
||||
} catch (...) {
|
||||
ms_destroy(memory, i);
|
||||
throw;
|
||||
}
|
||||
#else
|
||||
for (std::size_t i = 0; i < size; i++) {
|
||||
void* p1 = memory + i;
|
||||
::new(p1) T;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline void ms_noinit(T* memory, std::size_t size) {
|
||||
boost::has_trivial_default_constructor<T> trivial;
|
||||
ms_noinit(memory, size, trivial);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@@ -11,10 +11,11 @@
|
||||
// boost/detail/atomic_count.hpp - thread/SMP safe reference counter
|
||||
//
|
||||
// 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
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// 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
|
||||
//
|
||||
// typedef <implementation-defined> boost::detail::atomic_count;
|
||||
//
|
||||
@@ -27,92 +28,68 @@
|
||||
// a;
|
||||
//
|
||||
// Returns: (long) the current value of a
|
||||
// Memory Ordering: acquire
|
||||
//
|
||||
// ++a;
|
||||
//
|
||||
// Effects: Atomically increments the value of a
|
||||
// Returns: (long) the new value of a
|
||||
// Memory Ordering: acquire/release
|
||||
//
|
||||
// --a;
|
||||
//
|
||||
// Effects: Atomically decrements the value of a
|
||||
// Returns: (long) the new value of a
|
||||
//
|
||||
// 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...
|
||||
// Memory Ordering: acquire/release
|
||||
//
|
||||
|
||||
#include <boost/config.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
|
||||
{
|
||||
|
||||
typedef long atomic_count;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
#elif defined( BOOST_AC_USE_SPINLOCK )
|
||||
# include <boost/smart_ptr/detail/atomic_count_spin.hpp>
|
||||
|
||||
#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>
|
||||
|
||||
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
|
||||
# include <boost/smart_ptr/detail/atomic_count_win32.hpp>
|
||||
|
||||
#elif defined( BOOST_SP_HAS_SYNC )
|
||||
# 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__)
|
||||
# include <boost/smart_ptr/detail/atomic_count_gcc.hpp>
|
||||
|
||||
#elif defined(BOOST_HAS_PTHREADS)
|
||||
|
||||
# define BOOST_AC_USE_PTHREADS
|
||||
# include <boost/smart_ptr/detail/atomic_count_pthreads.hpp>
|
||||
#elif !defined( BOOST_HAS_THREADS )
|
||||
# include <boost/smart_ptr/detail/atomic_count_nt.hpp>
|
||||
|
||||
#else
|
||||
|
||||
// Use #define BOOST_DISABLE_THREADS to avoid the error
|
||||
#error Unrecognized threading platform
|
||||
# include <boost/smart_ptr/detail/atomic_count_spin.hpp>
|
||||
|
||||
#endif
|
||||
|
||||
|
59
include/boost/smart_ptr/detail/atomic_count_nt.hpp
Normal file
59
include/boost/smart_ptr/detail/atomic_count_nt.hpp
Normal 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
|
@@ -11,6 +11,7 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <pthread.h>
|
||||
|
||||
//
|
||||
@@ -37,12 +38,12 @@ private:
|
||||
|
||||
scoped_lock(pthread_mutex_t & m): m_(m)
|
||||
{
|
||||
pthread_mutex_lock(&m_);
|
||||
BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
|
||||
}
|
||||
|
||||
~scoped_lock()
|
||||
{
|
||||
pthread_mutex_unlock(&m_);
|
||||
BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -54,12 +55,12 @@ public:
|
||||
|
||||
explicit atomic_count(long v): value_(v)
|
||||
{
|
||||
pthread_mutex_init(&mutex_, 0);
|
||||
BOOST_VERIFY( pthread_mutex_init( &mutex_, 0 ) == 0 );
|
||||
}
|
||||
|
||||
~atomic_count()
|
||||
{
|
||||
pthread_mutex_destroy(&mutex_);
|
||||
BOOST_VERIFY( pthread_mutex_destroy( &mutex_ ) == 0 );
|
||||
}
|
||||
|
||||
long operator++()
|
62
include/boost/smart_ptr/detail/atomic_count_spin.hpp
Normal file
62
include/boost/smart_ptr/detail/atomic_count_spin.hpp
Normal 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
|
60
include/boost/smart_ptr/detail/atomic_count_std_atomic.hpp
Normal file
60
include/boost/smart_ptr/detail/atomic_count_std_atomic.hpp
Normal 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
|
@@ -17,7 +17,7 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <boost/detail/interlocked.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_interlocked.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
@@ -35,12 +35,12 @@ public:
|
||||
|
||||
long operator++()
|
||||
{
|
||||
return BOOST_INTERLOCKED_INCREMENT( &value_ );
|
||||
return BOOST_SP_INTERLOCKED_INCREMENT( &value_ );
|
||||
}
|
||||
|
||||
long operator--()
|
||||
{
|
||||
return BOOST_INTERLOCKED_DECREMENT( &value_ );
|
||||
return BOOST_SP_INTERLOCKED_DECREMENT( &value_ );
|
||||
}
|
||||
|
||||
operator long() const
|
||||
|
@@ -11,12 +11,15 @@
|
||||
// boost/detail/lwm_win32_cs.hpp
|
||||
//
|
||||
// Copyright (c) 2002, 2003 Peter Dimov
|
||||
// Copyright (c) Microsoft Corporation 2014
|
||||
//
|
||||
// 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/predef.h>
|
||||
|
||||
#ifdef BOOST_USE_WINDOWS_H
|
||||
# include <windows.h>
|
||||
#endif
|
||||
@@ -43,7 +46,11 @@ struct critical_section
|
||||
#endif
|
||||
};
|
||||
|
||||
#if BOOST_PLAT_WINDOWS_RUNTIME
|
||||
extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSectionEx(critical_section *, unsigned long, unsigned long);
|
||||
#else
|
||||
extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSection(critical_section *);
|
||||
#endif
|
||||
extern "C" __declspec(dllimport) void __stdcall EnterCriticalSection(critical_section *);
|
||||
extern "C" __declspec(dllimport) void __stdcall LeaveCriticalSection(critical_section *);
|
||||
extern "C" __declspec(dllimport) void __stdcall DeleteCriticalSection(critical_section *);
|
||||
@@ -67,7 +74,11 @@ public:
|
||||
|
||||
lightweight_mutex()
|
||||
{
|
||||
#if BOOST_PLAT_WINDOWS_RUNTIME
|
||||
InitializeCriticalSectionEx(&cs_, 4000, 0);
|
||||
#else
|
||||
InitializeCriticalSection(&cs_);
|
||||
#endif
|
||||
}
|
||||
|
||||
~lightweight_mutex()
|
||||
|
@@ -1,14 +1,21 @@
|
||||
// This header intentionally has no include guards.
|
||||
//
|
||||
// Copyright (c) 2001-2009 Peter Dimov
|
||||
// Copyright (c) 2001-2009, 2012 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#if ( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, < 0x570) ) || defined(__CINT__)
|
||||
#if !defined( BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS ) && !defined( BOOST_NO_CXX11_NULLPTR )
|
||||
|
||||
operator bool () const
|
||||
explicit operator bool () const BOOST_NOEXCEPT
|
||||
{
|
||||
return px != 0;
|
||||
}
|
||||
|
||||
#elif ( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, < 0x570) ) || defined(__CINT__)
|
||||
|
||||
operator bool () const BOOST_NOEXCEPT
|
||||
{
|
||||
return px != 0;
|
||||
}
|
||||
@@ -21,7 +28,7 @@
|
||||
|
||||
typedef void (*unspecified_bool_type)( this_type*** );
|
||||
|
||||
operator unspecified_bool_type() const // never throws
|
||||
operator unspecified_bool_type() const BOOST_NOEXCEPT
|
||||
{
|
||||
return px == 0? 0: unspecified_bool;
|
||||
}
|
||||
@@ -31,18 +38,18 @@
|
||||
( defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 304) ) || \
|
||||
( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x590) )
|
||||
|
||||
typedef T * (this_type::*unspecified_bool_type)() const;
|
||||
typedef element_type * (this_type::*unspecified_bool_type)() const;
|
||||
|
||||
operator unspecified_bool_type() const // never throws
|
||||
operator unspecified_bool_type() const BOOST_NOEXCEPT
|
||||
{
|
||||
return px == 0? 0: &this_type::get;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
typedef T * this_type::*unspecified_bool_type;
|
||||
typedef element_type * this_type::*unspecified_bool_type;
|
||||
|
||||
operator unspecified_bool_type() const // never throws
|
||||
operator unspecified_bool_type() const BOOST_NOEXCEPT
|
||||
{
|
||||
return px == 0? 0: &this_type::px;
|
||||
}
|
||||
@@ -50,7 +57,7 @@
|
||||
#endif
|
||||
|
||||
// operator! is redundant, but some compilers need it
|
||||
bool operator! () const // never throws
|
||||
bool operator! () const BOOST_NOEXCEPT
|
||||
{
|
||||
return px == 0;
|
||||
}
|
||||
|
@@ -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
|
@@ -35,7 +35,14 @@
|
||||
// rather than including <memory> directly:
|
||||
#include <boost/config/no_tr1/memory.hpp> // std::auto_ptr
|
||||
#include <functional> // std::less
|
||||
|
||||
#ifdef BOOST_NO_EXCEPTIONS
|
||||
# include <new> // std::bad_alloc
|
||||
#endif
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_SMART_PTR )
|
||||
# include <boost/utility/addressof.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
@@ -56,6 +63,38 @@ template< class D > struct sp_inplace_tag
|
||||
{
|
||||
};
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_SMART_PTR )
|
||||
|
||||
template< class T > class sp_reference_wrapper
|
||||
{
|
||||
public:
|
||||
|
||||
explicit sp_reference_wrapper( T & t): t_( boost::addressof( t ) )
|
||||
{
|
||||
}
|
||||
|
||||
template< class Y > void operator()( Y * p ) const
|
||||
{
|
||||
(*t_)( p );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
T * t_;
|
||||
};
|
||||
|
||||
template< class D > struct sp_convert_reference
|
||||
{
|
||||
typedef D type;
|
||||
};
|
||||
|
||||
template< class D > struct sp_convert_reference< D& >
|
||||
{
|
||||
typedef sp_reference_wrapper< D > type;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
class weak_count;
|
||||
|
||||
class shared_count
|
||||
@@ -161,7 +200,7 @@ public:
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
D()( p ); // delete p
|
||||
D::operator_fn( p ); // delete p
|
||||
throw;
|
||||
}
|
||||
|
||||
@@ -171,7 +210,7 @@ public:
|
||||
|
||||
if( pi_ == 0 )
|
||||
{
|
||||
D()( p ); // delete p
|
||||
D::operator_fn( p ); // delete p
|
||||
boost::throw_exception( std::bad_alloc() );
|
||||
}
|
||||
|
||||
@@ -186,16 +225,35 @@ public:
|
||||
#endif
|
||||
{
|
||||
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;
|
||||
|
||||
#endif
|
||||
|
||||
A2 a2( a );
|
||||
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
|
||||
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 ) );
|
||||
new( static_cast< void* >( pi_ ) ) impl_type( p, d, a );
|
||||
::new( static_cast< void* >( pi_ ) ) impl_type( p, d, a );
|
||||
|
||||
#endif
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
@@ -209,13 +267,30 @@ public:
|
||||
throw;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
|
||||
|
||||
impl_type * pi = std::allocator_traits<A2>::allocate( a2, 1 );
|
||||
pi_ = pi;
|
||||
|
||||
#else
|
||||
|
||||
pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
|
||||
|
||||
#endif
|
||||
|
||||
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
|
||||
{
|
||||
@@ -234,20 +309,39 @@ public:
|
||||
#endif
|
||||
{
|
||||
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;
|
||||
|
||||
#endif
|
||||
|
||||
A2 a2( a );
|
||||
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
|
||||
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 ) );
|
||||
new( static_cast< void* >( pi_ ) ) impl_type( p, a );
|
||||
::new( static_cast< void* >( pi_ ) ) impl_type( p, a );
|
||||
|
||||
#endif
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
D()( p );
|
||||
D::operator_fn( p );
|
||||
|
||||
if( pi_ != 0 )
|
||||
{
|
||||
@@ -257,17 +351,34 @@ public:
|
||||
throw;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
|
||||
|
||||
impl_type * pi = std::allocator_traits<A2>::allocate( a2, 1 );
|
||||
pi_ = pi;
|
||||
|
||||
#else
|
||||
|
||||
pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
|
||||
|
||||
#endif
|
||||
|
||||
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
|
||||
{
|
||||
D()( p );
|
||||
D::operator_fn( p );
|
||||
boost::throw_exception( std::bad_alloc() );
|
||||
}
|
||||
|
||||
@@ -298,6 +409,33 @@ public:
|
||||
r.release();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_SMART_PTR )
|
||||
|
||||
template<class Y, class D>
|
||||
explicit shared_count( std::unique_ptr<Y, D> & r ): pi_( 0 )
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
, id_(shared_count_id)
|
||||
#endif
|
||||
{
|
||||
typedef typename sp_convert_reference<D>::type D2;
|
||||
|
||||
D2 d2( r.get_deleter() );
|
||||
pi_ = new sp_counted_impl_pd< typename std::unique_ptr<Y, D>::pointer, D2 >( r.get(), d2 );
|
||||
|
||||
#ifdef BOOST_NO_EXCEPTIONS
|
||||
|
||||
if( pi_ == 0 )
|
||||
{
|
||||
boost::throw_exception( std::bad_alloc() );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
r.release();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
~shared_count() // nothrow
|
||||
@@ -316,7 +454,7 @@ public:
|
||||
if( pi_ != 0 ) pi_->add_ref_copy();
|
||||
}
|
||||
|
||||
#if defined( BOOST_HAS_RVALUE_REFS )
|
||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||
|
||||
shared_count(shared_count && r): pi_(r.pi_) // nothrow
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
@@ -381,6 +519,11 @@ public:
|
||||
{
|
||||
return pi_? pi_->get_deleter( ti ): 0;
|
||||
}
|
||||
|
||||
void * get_untyped_deleter() const
|
||||
{
|
||||
return pi_? pi_->get_untyped_deleter(): 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -423,7 +566,7 @@ public:
|
||||
|
||||
// Move support
|
||||
|
||||
#if defined( BOOST_HAS_RVALUE_REFS )
|
||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||
|
||||
weak_count(weak_count && r): pi_(r.pi_) // nothrow
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
|
@@ -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
|
@@ -48,6 +48,21 @@ template< class Y, class T > struct sp_convertible
|
||||
enum _vt { value = sizeof( (f)( static_cast<Y*>(0) ) ) == sizeof(yes) };
|
||||
};
|
||||
|
||||
template< class Y, class T > struct sp_convertible< Y, T[] >
|
||||
{
|
||||
enum _vt { value = false };
|
||||
};
|
||||
|
||||
template< class Y, class T > struct sp_convertible< Y[], T[] >
|
||||
{
|
||||
enum _vt { value = sp_convertible< Y[1], T[1] >::value };
|
||||
};
|
||||
|
||||
template< class Y, std::size_t N, class T > struct sp_convertible< Y[N], T[] >
|
||||
{
|
||||
enum _vt { value = sp_convertible< Y[1], T[1] >::value };
|
||||
};
|
||||
|
||||
struct sp_empty
|
||||
{
|
||||
};
|
||||
|
@@ -10,7 +10,7 @@
|
||||
//
|
||||
// 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
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -23,6 +23,9 @@
|
||||
#if defined( BOOST_SP_DISABLE_THREADS )
|
||||
# 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 )
|
||||
# include <boost/smart_ptr/detail/sp_counted_base_spin.hpp>
|
||||
|
||||
@@ -32,22 +35,28 @@
|
||||
#elif defined( BOOST_DISABLE_THREADS ) && !defined( BOOST_SP_ENABLE_THREADS ) && !defined( BOOST_DISABLE_WIN32 )
|
||||
# include <boost/smart_ptr/detail/sp_counted_base_nt.hpp>
|
||||
|
||||
#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) )
|
||||
# include <boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp>
|
||||
#elif defined( __SNC__ )
|
||||
# include <boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp>
|
||||
|
||||
#elif defined( __GNUC__ ) && defined( __ia64__ ) && !defined( __INTEL_COMPILER )
|
||||
# include <boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp>
|
||||
#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) && !defined(__PATHSCALE__)
|
||||
# include <boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp>
|
||||
|
||||
#elif defined(__HP_aCC) && defined(__ia64)
|
||||
# include <boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp>
|
||||
|
||||
#elif defined( __GNUC__ ) && defined( __ia64__ ) && !defined( __INTEL_COMPILER ) && !defined(__PATHSCALE__)
|
||||
# include <boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp>
|
||||
|
||||
#elif defined( __IBMCPP__ ) && defined( __powerpc )
|
||||
# include <boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp>
|
||||
|
||||
#elif defined( __MWERKS__ ) && defined( __POWERPC__ )
|
||||
# include <boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp>
|
||||
|
||||
#elif defined( __GNUC__ ) && ( defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc ) )
|
||||
#elif defined( __GNUC__ ) && ( defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc ) ) && !defined(__PATHSCALE__) && !defined( _AIX )
|
||||
# include <boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp>
|
||||
|
||||
#elif defined( __GNUC__ ) && ( defined( __mips__ ) || defined( _mips ) )
|
||||
#elif defined( __GNUC__ ) && ( defined( __mips__ ) || defined( _mips ) ) && !defined(__PATHSCALE__)
|
||||
# include <boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp>
|
||||
|
||||
#elif defined( BOOST_SP_HAS_SYNC )
|
||||
|
@@ -104,6 +104,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
|
@@ -96,6 +96,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
|
@@ -124,6 +124,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
|
@@ -112,6 +112,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
|
@@ -111,6 +111,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
|
@@ -135,6 +135,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
|
@@ -135,6 +135,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
|
@@ -120,6 +120,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
|
@@ -127,6 +127,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
|
@@ -59,6 +59,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
|
@@ -19,6 +19,7 @@
|
||||
//
|
||||
|
||||
#include <boost/detail/sp_typeinfo.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <pthread.h>
|
||||
|
||||
namespace boost
|
||||
@@ -46,15 +47,15 @@ public:
|
||||
// HPUX 10.20 / DCE has a nonstandard pthread_mutex_init
|
||||
|
||||
#if defined(__hpux) && defined(_DECTHREADS_)
|
||||
pthread_mutex_init( &m_, pthread_mutexattr_default );
|
||||
BOOST_VERIFY( pthread_mutex_init( &m_, pthread_mutexattr_default ) == 0 );
|
||||
#else
|
||||
pthread_mutex_init( &m_, 0 );
|
||||
BOOST_VERIFY( pthread_mutex_init( &m_, 0 ) == 0 );
|
||||
#endif
|
||||
}
|
||||
|
||||
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
|
||||
@@ -70,27 +71,28 @@ public:
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
pthread_mutex_lock( &m_ );
|
||||
BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
|
||||
++use_count_;
|
||||
pthread_mutex_unlock( &m_ );
|
||||
BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
|
||||
}
|
||||
|
||||
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 );
|
||||
pthread_mutex_unlock( &m_ );
|
||||
BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
|
||||
return r;
|
||||
}
|
||||
|
||||
void release() // nothrow
|
||||
{
|
||||
pthread_mutex_lock( &m_ );
|
||||
BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
|
||||
long new_use_count = --use_count_;
|
||||
pthread_mutex_unlock( &m_ );
|
||||
BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
|
||||
|
||||
if( new_use_count == 0 )
|
||||
{
|
||||
@@ -101,16 +103,16 @@ public:
|
||||
|
||||
void weak_add_ref() // nothrow
|
||||
{
|
||||
pthread_mutex_lock( &m_ );
|
||||
BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
|
||||
++weak_count_;
|
||||
pthread_mutex_unlock( &m_ );
|
||||
BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
|
||||
}
|
||||
|
||||
void weak_release() // nothrow
|
||||
{
|
||||
pthread_mutex_lock( &m_ );
|
||||
BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
|
||||
long new_weak_count = --weak_count_;
|
||||
pthread_mutex_unlock( &m_ );
|
||||
BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
|
||||
|
||||
if( new_weak_count == 0 )
|
||||
{
|
||||
@@ -120,9 +122,9 @@ public:
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
pthread_mutex_lock( &m_ );
|
||||
BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
|
||||
long r = use_count_;
|
||||
pthread_mutex_unlock( &m_ );
|
||||
BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
|
||||
|
||||
return r;
|
||||
}
|
||||
|
162
include/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp
Normal file
162
include/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp
Normal file
@@ -0,0 +1,162 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SNC_PS3_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SNC_PS3_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// detail/sp_counted_base_gcc_sparc.hpp - g++ on Sparc V8+
|
||||
//
|
||||
// Copyright (c) 2006 Piotr Wyderski
|
||||
// Copyright (c) 2006 Tomas Puverle
|
||||
// Copyright (c) 2006 Peter Dimov
|
||||
// Copyright (c) 2011 Emil Dotchevski
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
// Thanks to Michael van der Westhuizen
|
||||
|
||||
#include <boost/detail/sp_typeinfo.hpp>
|
||||
#include <inttypes.h> // uint32_t
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
inline uint32_t compare_and_swap( uint32_t * dest_, uint32_t compare_, uint32_t swap_ )
|
||||
{
|
||||
return __builtin_cellAtomicCompareAndSwap32(dest_,compare_,swap_);
|
||||
}
|
||||
|
||||
inline uint32_t atomic_fetch_and_add( uint32_t * pw, uint32_t dv )
|
||||
{
|
||||
// long r = *pw;
|
||||
// *pw += dv;
|
||||
// return r;
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
uint32_t r = *pw;
|
||||
|
||||
if( __builtin_expect((compare_and_swap(pw, r, r + dv) == r), 1) )
|
||||
{
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void atomic_increment( uint32_t * pw )
|
||||
{
|
||||
(void) __builtin_cellAtomicIncr32( pw );
|
||||
}
|
||||
|
||||
inline uint32_t atomic_decrement( uint32_t * pw )
|
||||
{
|
||||
return __builtin_cellAtomicDecr32( pw );
|
||||
}
|
||||
|
||||
inline uint32_t atomic_conditional_increment( uint32_t * pw )
|
||||
{
|
||||
// long r = *pw;
|
||||
// if( r != 0 ) ++*pw;
|
||||
// return r;
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
uint32_t r = *pw;
|
||||
|
||||
if( r == 0 )
|
||||
{
|
||||
return r;
|
||||
}
|
||||
|
||||
if( __builtin_expect( ( compare_and_swap( pw, r, r + 1 ) == r ), 1 ) )
|
||||
{
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
uint32_t use_count_; // #shared
|
||||
uint32_t weak_count_; // #weak + (#shared != 0)
|
||||
|
||||
public:
|
||||
|
||||
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~sp_counted_base() // nothrow
|
||||
{
|
||||
}
|
||||
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
|
||||
virtual void dispose() = 0; // nothrow
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
atomic_increment( &use_count_ );
|
||||
}
|
||||
|
||||
bool add_ref_lock() // true on success
|
||||
{
|
||||
return atomic_conditional_increment( &use_count_ ) != 0;
|
||||
}
|
||||
|
||||
void release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &use_count_ ) == 1 )
|
||||
{
|
||||
dispose();
|
||||
weak_release();
|
||||
}
|
||||
}
|
||||
|
||||
void weak_add_ref() // nothrow
|
||||
{
|
||||
atomic_increment( &weak_count_ );
|
||||
}
|
||||
|
||||
void weak_release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &weak_count_ ) == 1 )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
return const_cast< uint32_t const volatile & >( use_count_ );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SNC_PS3_HPP_INCLUDED
|
@@ -62,6 +62,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
|
@@ -84,6 +84,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
|
137
include/boost/smart_ptr/detail/sp_counted_base_std_atomic.hpp
Normal file
137
include/boost/smart_ptr/detail/sp_counted_base_std_atomic.hpp
Normal 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
|
@@ -109,6 +109,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
|
151
include/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp
Normal file
151
include/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp
Normal file
@@ -0,0 +1,151 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_VACPP_PPC_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_VACPP_PPC_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// detail/sp_counted_base_vacpp_ppc.hpp - xlC(vacpp) on POWER
|
||||
// based on: detail/sp_counted_base_w32.hpp
|
||||
//
|
||||
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
|
||||
// Copyright 2004-2005 Peter Dimov
|
||||
// Copyright 2006 Michael van der Westhuizen
|
||||
// Copyright 2012 IBM Corp.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
//
|
||||
// Lock-free algorithm by Alexander Terekhov
|
||||
//
|
||||
// Thanks to Ben Hitchings for the #weak + (#shared != 0)
|
||||
// formulation
|
||||
//
|
||||
|
||||
#include <boost/detail/sp_typeinfo.hpp>
|
||||
|
||||
extern "builtin" void __lwsync(void);
|
||||
extern "builtin" void __isync(void);
|
||||
extern "builtin" int __fetch_and_add(volatile int* addr, int val);
|
||||
extern "builtin" int __compare_and_swap(volatile int*, int*, int);
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
inline void atomic_increment( int *pw )
|
||||
{
|
||||
// ++*pw;
|
||||
__lwsync();
|
||||
__fetch_and_add(pw, 1);
|
||||
__isync();
|
||||
}
|
||||
|
||||
inline int atomic_decrement( int *pw )
|
||||
{
|
||||
// return --*pw;
|
||||
__lwsync();
|
||||
int originalValue = __fetch_and_add(pw, -1);
|
||||
__isync();
|
||||
|
||||
return (originalValue - 1);
|
||||
}
|
||||
|
||||
inline int atomic_conditional_increment( int *pw )
|
||||
{
|
||||
// if( *pw != 0 ) ++*pw;
|
||||
// return *pw;
|
||||
|
||||
__lwsync();
|
||||
int v = *const_cast<volatile int*>(pw);
|
||||
for (;;)
|
||||
// loop until state is known
|
||||
{
|
||||
if (v == 0) return 0;
|
||||
if (__compare_and_swap(pw, &v, v + 1))
|
||||
{
|
||||
__isync(); return (v + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class sp_counted_base
|
||||
{
|
||||
private:
|
||||
|
||||
sp_counted_base( sp_counted_base const & );
|
||||
sp_counted_base & operator= ( sp_counted_base const & );
|
||||
|
||||
int use_count_; // #shared
|
||||
int weak_count_; // #weak + (#shared != 0)
|
||||
char pad[64] __attribute__((__aligned__(64)));
|
||||
// pad to prevent false sharing
|
||||
public:
|
||||
|
||||
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~sp_counted_base() // nothrow
|
||||
{
|
||||
}
|
||||
|
||||
// dispose() is called when use_count_ drops to zero, to release
|
||||
// the resources managed by *this.
|
||||
|
||||
virtual void dispose() = 0; // nothrow
|
||||
|
||||
// destroy() is called when weak_count_ drops to zero.
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
atomic_increment( &use_count_ );
|
||||
}
|
||||
|
||||
bool add_ref_lock() // true on success
|
||||
{
|
||||
return atomic_conditional_increment( &use_count_ ) != 0;
|
||||
}
|
||||
|
||||
void release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &use_count_ ) == 0 )
|
||||
{
|
||||
dispose();
|
||||
weak_release();
|
||||
}
|
||||
}
|
||||
|
||||
void weak_add_ref() // nothrow
|
||||
{
|
||||
atomic_increment( &weak_count_ );
|
||||
}
|
||||
|
||||
void weak_release() // nothrow
|
||||
{
|
||||
if( atomic_decrement( &weak_count_ ) == 0 )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
long use_count() const // nothrow
|
||||
{
|
||||
return *const_cast<volatile int*>(&use_count_);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_VACPP_PPC_HPP_INCLUDED
|
@@ -24,7 +24,7 @@
|
||||
// formulation
|
||||
//
|
||||
|
||||
#include <boost/detail/interlocked.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_interlocked.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/detail/sp_typeinfo.hpp>
|
||||
|
||||
@@ -67,10 +67,11 @@ public:
|
||||
}
|
||||
|
||||
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
|
||||
virtual void * get_untyped_deleter() = 0;
|
||||
|
||||
void add_ref_copy()
|
||||
{
|
||||
BOOST_INTERLOCKED_INCREMENT( &use_count_ );
|
||||
BOOST_SP_INTERLOCKED_INCREMENT( &use_count_ );
|
||||
}
|
||||
|
||||
bool add_ref_lock() // true on success
|
||||
@@ -85,11 +86,11 @@ public:
|
||||
// work around a code generation bug
|
||||
|
||||
long tmp2 = tmp + 1;
|
||||
if( BOOST_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp2, tmp ) == tmp2 - 1 ) return true;
|
||||
if( BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp2, tmp ) == tmp2 - 1 ) return true;
|
||||
|
||||
#else
|
||||
|
||||
if( BOOST_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp + 1, tmp ) == tmp ) return true;
|
||||
if( BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp + 1, tmp ) == tmp ) return true;
|
||||
|
||||
#endif
|
||||
}
|
||||
@@ -97,7 +98,7 @@ public:
|
||||
|
||||
void release() // nothrow
|
||||
{
|
||||
if( BOOST_INTERLOCKED_DECREMENT( &use_count_ ) == 0 )
|
||||
if( BOOST_SP_INTERLOCKED_DECREMENT( &use_count_ ) == 0 )
|
||||
{
|
||||
dispose();
|
||||
weak_release();
|
||||
@@ -106,12 +107,12 @@ public:
|
||||
|
||||
void weak_add_ref() // nothrow
|
||||
{
|
||||
BOOST_INTERLOCKED_INCREMENT( &weak_count_ );
|
||||
BOOST_SP_INTERLOCKED_INCREMENT( &weak_count_ );
|
||||
}
|
||||
|
||||
void weak_release() // nothrow
|
||||
{
|
||||
if( BOOST_INTERLOCKED_DECREMENT( &weak_count_ ) == 0 )
|
||||
if( BOOST_SP_INTERLOCKED_DECREMENT( &weak_count_ ) == 0 )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
@@ -83,6 +83,11 @@ public:
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void * get_untyped_deleter()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(BOOST_SP_USE_STD_ALLOCATOR)
|
||||
|
||||
void * operator new( std::size_t )
|
||||
@@ -153,6 +158,11 @@ public:
|
||||
return ti == BOOST_SP_TYPEID(D)? &reinterpret_cast<char&>( del ): 0;
|
||||
}
|
||||
|
||||
virtual void * get_untyped_deleter()
|
||||
{
|
||||
return &reinterpret_cast<char&>( del );
|
||||
}
|
||||
|
||||
#if defined(BOOST_SP_USE_STD_ALLOCATOR)
|
||||
|
||||
void * operator new( std::size_t )
|
||||
@@ -203,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 )
|
||||
{
|
||||
}
|
||||
|
||||
@@ -214,11 +224,28 @@ public:
|
||||
|
||||
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;
|
||||
|
||||
#endif
|
||||
|
||||
A2 a2( a_ );
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
|
||||
|
||||
std::allocator_traits<A2>::destroy( a2, this );
|
||||
|
||||
#else
|
||||
|
||||
this->~this_type();
|
||||
|
||||
#endif
|
||||
|
||||
a2.deallocate( this, 1 );
|
||||
}
|
||||
|
||||
@@ -226,6 +253,11 @@ public:
|
||||
{
|
||||
return ti == BOOST_SP_TYPEID( D )? &reinterpret_cast<char&>( d_ ): 0;
|
||||
}
|
||||
|
||||
virtual void * get_untyped_deleter()
|
||||
{
|
||||
return &reinterpret_cast<char&>( d_ );
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef __CODEGUARD__
|
||||
|
39
include/boost/smart_ptr/detail/sp_forward.hpp
Normal file
39
include/boost/smart_ptr/detail/sp_forward.hpp
Normal file
@@ -0,0 +1,39 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_FORWARD_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_FORWARD_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// detail/sp_forward.hpp
|
||||
//
|
||||
// Copyright 2008,2012 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||
|
||||
template< class T > T&& sp_forward( T & t ) BOOST_NOEXCEPT
|
||||
{
|
||||
return static_cast< T&& >( t );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_FORWARD_HPP_INCLUDED
|
@@ -20,7 +20,17 @@
|
||||
// are available.
|
||||
//
|
||||
|
||||
#if defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 ) && !defined( BOOST_SP_NO_SYNC )
|
||||
#ifndef BOOST_SP_NO_SYNC
|
||||
|
||||
#if defined( __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 )
|
||||
|
||||
# define BOOST_SP_HAS_SYNC
|
||||
|
||||
#elif defined( __IBMCPP__ ) && ( __IBMCPP__ >= 1210 )
|
||||
|
||||
# define BOOST_SP_HAS_SYNC
|
||||
|
||||
#elif defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 )
|
||||
|
||||
#define BOOST_SP_HAS_SYNC
|
||||
|
||||
@@ -44,10 +54,16 @@
|
||||
#undef BOOST_SP_HAS_SYNC
|
||||
#endif
|
||||
|
||||
#if defined( __INTEL_COMPILER ) && !defined( __ia64__ ) && ( __INTEL_COMPILER < 1100 )
|
||||
#if defined( __INTEL_COMPILER ) && !defined( __ia64__ ) && ( __INTEL_COMPILER < 1110 )
|
||||
#undef BOOST_SP_HAS_SYNC
|
||||
#endif
|
||||
|
||||
#endif // __GNUC__ * 100 + __GNUC_MINOR__ >= 401
|
||||
#if defined(__PATHSCALE__) && ((__PATHCC__ == 4) && (__PATHCC_MINOR__ < 9))
|
||||
#undef BOOST_SP_HAS_SYNC
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_SP_NO_SYNC
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_HPP_INCLUDED
|
||||
|
34
include/boost/smart_ptr/detail/sp_if_array.hpp
Normal file
34
include/boost/smart_ptr/detail/sp_if_array.hpp
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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_SP_IF_ARRAY_HPP
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_IF_ARRAY_HPP
|
||||
|
||||
#include <boost/smart_ptr/shared_ptr.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace detail {
|
||||
template<class T>
|
||||
struct sp_if_array;
|
||||
|
||||
template<class T>
|
||||
struct sp_if_array<T[]> {
|
||||
typedef boost::shared_ptr<T[]> type;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct sp_if_size_array;
|
||||
|
||||
template<class T, std::size_t N>
|
||||
struct sp_if_size_array<T[N]> {
|
||||
typedef boost::shared_ptr<T[N]> type;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
152
include/boost/smart_ptr/detail/sp_interlocked.hpp
Normal file
152
include/boost/smart_ptr/detail/sp_interlocked.hpp
Normal file
@@ -0,0 +1,152 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_INTERLOCKED_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_INTERLOCKED_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// boost/detail/sp_interlocked.hpp
|
||||
//
|
||||
// Copyright 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/config.hpp>
|
||||
|
||||
// BOOST_SP_HAS_INTRIN_H
|
||||
|
||||
// VC9 has intrin.h, but it collides with <utility>
|
||||
#if defined( BOOST_MSVC ) && BOOST_MSVC >= 1600
|
||||
|
||||
# define BOOST_SP_HAS_INTRIN_H
|
||||
|
||||
// Unlike __MINGW64__, __MINGW64_VERSION_MAJOR is defined by MinGW-w64 for both 32 and 64-bit targets.
|
||||
#elif defined( __MINGW64_VERSION_MAJOR )
|
||||
|
||||
// MinGW-w64 provides intrin.h for both 32 and 64-bit targets.
|
||||
# define BOOST_SP_HAS_INTRIN_H
|
||||
|
||||
// Intel C++ on Windows on VC10+ stdlib
|
||||
#elif defined( BOOST_INTEL_WIN ) && defined( _CPPLIB_VER ) && _CPPLIB_VER >= 520
|
||||
|
||||
# define BOOST_SP_HAS_INTRIN_H
|
||||
|
||||
#endif
|
||||
|
||||
#if defined( BOOST_USE_WINDOWS_H )
|
||||
|
||||
# include <windows.h>
|
||||
|
||||
# define BOOST_SP_INTERLOCKED_INCREMENT InterlockedIncrement
|
||||
# define BOOST_SP_INTERLOCKED_DECREMENT InterlockedDecrement
|
||||
# define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE InterlockedCompareExchange
|
||||
# define BOOST_SP_INTERLOCKED_EXCHANGE InterlockedExchange
|
||||
# define BOOST_SP_INTERLOCKED_EXCHANGE_ADD InterlockedExchangeAdd
|
||||
|
||||
#elif defined( BOOST_USE_INTRIN_H ) || defined( BOOST_SP_HAS_INTRIN_H )
|
||||
|
||||
#include <intrin.h>
|
||||
|
||||
# define BOOST_SP_INTERLOCKED_INCREMENT _InterlockedIncrement
|
||||
# define BOOST_SP_INTERLOCKED_DECREMENT _InterlockedDecrement
|
||||
# define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange
|
||||
# define BOOST_SP_INTERLOCKED_EXCHANGE _InterlockedExchange
|
||||
# define BOOST_SP_INTERLOCKED_EXCHANGE_ADD _InterlockedExchangeAdd
|
||||
|
||||
#elif defined( _WIN32_WCE )
|
||||
|
||||
#if _WIN32_WCE >= 0x600
|
||||
|
||||
extern "C" long __cdecl _InterlockedIncrement( long volatile * );
|
||||
extern "C" long __cdecl _InterlockedDecrement( long volatile * );
|
||||
extern "C" long __cdecl _InterlockedCompareExchange( long volatile *, long, long );
|
||||
extern "C" long __cdecl _InterlockedExchange( long volatile *, long );
|
||||
extern "C" long __cdecl _InterlockedExchangeAdd( long volatile *, long );
|
||||
|
||||
# define BOOST_SP_INTERLOCKED_INCREMENT _InterlockedIncrement
|
||||
# define BOOST_SP_INTERLOCKED_DECREMENT _InterlockedDecrement
|
||||
# define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange
|
||||
# define BOOST_SP_INTERLOCKED_EXCHANGE _InterlockedExchange
|
||||
# define BOOST_SP_INTERLOCKED_EXCHANGE_ADD _InterlockedExchangeAdd
|
||||
|
||||
#else
|
||||
|
||||
// under Windows CE we still have old-style Interlocked* functions
|
||||
|
||||
extern "C" long __cdecl InterlockedIncrement( long* );
|
||||
extern "C" long __cdecl InterlockedDecrement( long* );
|
||||
extern "C" long __cdecl InterlockedCompareExchange( long*, long, long );
|
||||
extern "C" long __cdecl InterlockedExchange( long*, long );
|
||||
extern "C" long __cdecl InterlockedExchangeAdd( long*, long );
|
||||
|
||||
# define BOOST_SP_INTERLOCKED_INCREMENT InterlockedIncrement
|
||||
# define BOOST_SP_INTERLOCKED_DECREMENT InterlockedDecrement
|
||||
# define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE InterlockedCompareExchange
|
||||
# define BOOST_SP_INTERLOCKED_EXCHANGE InterlockedExchange
|
||||
# define BOOST_SP_INTERLOCKED_EXCHANGE_ADD InterlockedExchangeAdd
|
||||
|
||||
#endif
|
||||
|
||||
#elif defined( BOOST_MSVC ) || defined( BOOST_INTEL_WIN )
|
||||
|
||||
#if defined( __CLRCALL_PURE_OR_CDECL )
|
||||
|
||||
extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedIncrement( long volatile * );
|
||||
extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedDecrement( long volatile * );
|
||||
extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedCompareExchange( long volatile *, long, long );
|
||||
extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedExchange( long volatile *, long );
|
||||
extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedExchangeAdd( long volatile *, long );
|
||||
|
||||
#else
|
||||
|
||||
extern "C" long __cdecl _InterlockedIncrement( long volatile * );
|
||||
extern "C" long __cdecl _InterlockedDecrement( long volatile * );
|
||||
extern "C" long __cdecl _InterlockedCompareExchange( long volatile *, long, long );
|
||||
extern "C" long __cdecl _InterlockedExchange( long volatile *, long );
|
||||
extern "C" long __cdecl _InterlockedExchangeAdd( long volatile *, long );
|
||||
|
||||
#endif
|
||||
|
||||
# define BOOST_SP_INTERLOCKED_INCREMENT _InterlockedIncrement
|
||||
# define BOOST_SP_INTERLOCKED_DECREMENT _InterlockedDecrement
|
||||
# define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange
|
||||
# define BOOST_SP_INTERLOCKED_EXCHANGE _InterlockedExchange
|
||||
# define BOOST_SP_INTERLOCKED_EXCHANGE_ADD _InterlockedExchangeAdd
|
||||
|
||||
#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined( __CYGWIN__ )
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
extern "C" __declspec(dllimport) long __stdcall InterlockedIncrement( long volatile * );
|
||||
extern "C" __declspec(dllimport) long __stdcall InterlockedDecrement( long volatile * );
|
||||
extern "C" __declspec(dllimport) long __stdcall InterlockedCompareExchange( long volatile *, long, long );
|
||||
extern "C" __declspec(dllimport) long __stdcall InterlockedExchange( long volatile *, long );
|
||||
extern "C" __declspec(dllimport) long __stdcall InterlockedExchangeAdd( long volatile *, long );
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
# define BOOST_SP_INTERLOCKED_INCREMENT ::boost::detail::InterlockedIncrement
|
||||
# define BOOST_SP_INTERLOCKED_DECREMENT ::boost::detail::InterlockedDecrement
|
||||
# define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE ::boost::detail::InterlockedCompareExchange
|
||||
# define BOOST_SP_INTERLOCKED_EXCHANGE ::boost::detail::InterlockedExchange
|
||||
# define BOOST_SP_INTERLOCKED_EXCHANGE_ADD ::boost::detail::InterlockedExchangeAdd
|
||||
|
||||
#else
|
||||
|
||||
# error "Interlocked intrinsics not available"
|
||||
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_INTERLOCKED_HPP_INCLUDED
|
45
include/boost/smart_ptr/detail/sp_nullptr_t.hpp
Normal file
45
include/boost/smart_ptr/detail/sp_nullptr_t.hpp
Normal file
@@ -0,0 +1,45 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SP_NULLPTR_T_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SP_NULLPTR_T_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// detail/sp_nullptr_t.hpp
|
||||
//
|
||||
// Copyright 2013 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_NULLPTR )
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
#if defined( __clang__ ) && !defined( _LIBCPP_VERSION ) && !defined( BOOST_NO_CXX11_DECLTYPE )
|
||||
|
||||
typedef decltype(nullptr) sp_nullptr_t;
|
||||
|
||||
#else
|
||||
|
||||
typedef std::nullptr_t sp_nullptr_t;
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined( BOOST_NO_CXX11_NULLPTR )
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_NULLPTR_T_HPP_INCLUDED
|
@@ -31,7 +31,16 @@
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_has_sync.hpp>
|
||||
|
||||
#if defined( BOOST_SP_USE_PTHREADS )
|
||||
#if defined( BOOST_SP_USE_STD_ATOMIC )
|
||||
# if !defined( __clang__ )
|
||||
# include <boost/smart_ptr/detail/spinlock_std_atomic.hpp>
|
||||
# else
|
||||
// Clang (at least up to 3.4) can't compile spinlock_pool when
|
||||
// using std::atomic, so substitute the __sync implementation instead.
|
||||
# include <boost/smart_ptr/detail/spinlock_sync.hpp>
|
||||
# endif
|
||||
|
||||
#elif defined( BOOST_SP_USE_PTHREADS )
|
||||
# include <boost/smart_ptr/detail/spinlock_pt.hpp>
|
||||
|
||||
#elif defined(__GNUC__) && defined( __arm__ ) && !defined( __thumb__ )
|
||||
|
@@ -11,13 +11,15 @@
|
||||
|
||||
#include <boost/smart_ptr/detail/yield_k.hpp>
|
||||
|
||||
#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
|
||||
#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_7S__)
|
||||
|
||||
# define BOOST_SP_ARM_BARRIER "dmb"
|
||||
# define BOOST_SP_ARM_HAS_LDREX
|
||||
|
||||
#elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__)
|
||||
|
||||
# define BOOST_SP_ARM_BARRIER "mcr p15, 0, r0, c7, c10, 5"
|
||||
# define BOOST_SP_ARM_HAS_LDREX
|
||||
|
||||
#else
|
||||
|
||||
@@ -43,13 +45,28 @@ public:
|
||||
{
|
||||
int r;
|
||||
|
||||
#ifdef BOOST_SP_ARM_HAS_LDREX
|
||||
|
||||
__asm__ __volatile__(
|
||||
"swp %0, %1, [%2]\n\t"
|
||||
"ldrex %0, [%2]; \n"
|
||||
"cmp %0, %1; \n"
|
||||
"strexne %0, %1, [%2]; \n"
|
||||
BOOST_SP_ARM_BARRIER :
|
||||
"=&r"( r ): // outputs
|
||||
"r"( 1 ), "r"( &v_ ): // inputs
|
||||
"memory", "cc" );
|
||||
|
||||
#else
|
||||
|
||||
__asm__ __volatile__(
|
||||
"swp %0, %1, [%2];\n"
|
||||
BOOST_SP_ARM_BARRIER :
|
||||
"=&r"( r ): // outputs
|
||||
"r"( 1 ), "r"( &v_ ): // inputs
|
||||
"memory", "cc" );
|
||||
|
||||
#endif
|
||||
|
||||
return r == 0;
|
||||
}
|
||||
|
||||
@@ -98,5 +115,6 @@ public:
|
||||
#define BOOST_DETAIL_SPINLOCK_INIT {0}
|
||||
|
||||
#undef BOOST_SP_ARM_BARRIER
|
||||
#undef BOOST_SP_ARM_HAS_LDREX
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
|
||||
|
83
include/boost/smart_ptr/detail/spinlock_std_atomic.hpp
Normal file
83
include/boost/smart_ptr/detail/spinlock_std_atomic.hpp
Normal file
@@ -0,0 +1,83 @@
|
||||
#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_STD_ATOMIC_HPP_INCLUDED
|
||||
#define BOOST_SMART_PTR_DETAIL_SPINLOCK_STD_ATOMIC_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// Copyright (c) 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/smart_ptr/detail/yield_k.hpp>
|
||||
#include <atomic>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class spinlock
|
||||
{
|
||||
public:
|
||||
|
||||
std::atomic_flag v_;
|
||||
|
||||
public:
|
||||
|
||||
bool try_lock()
|
||||
{
|
||||
return !v_.test_and_set( std::memory_order_acquire );
|
||||
}
|
||||
|
||||
void lock()
|
||||
{
|
||||
for( unsigned k = 0; !try_lock(); ++k )
|
||||
{
|
||||
boost::detail::yield( k );
|
||||
}
|
||||
}
|
||||
|
||||
void unlock()
|
||||
{
|
||||
v_ .clear( std::memory_order_release );
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
class scoped_lock
|
||||
{
|
||||
private:
|
||||
|
||||
spinlock & sp_;
|
||||
|
||||
scoped_lock( scoped_lock const & );
|
||||
scoped_lock & operator=( scoped_lock const & );
|
||||
|
||||
public:
|
||||
|
||||
explicit scoped_lock( spinlock & sp ): sp_( sp )
|
||||
{
|
||||
sp.lock();
|
||||
}
|
||||
|
||||
~scoped_lock()
|
||||
{
|
||||
sp_.unlock();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace boost
|
||||
|
||||
#define BOOST_DETAIL_SPINLOCK_INIT { ATOMIC_FLAG_INIT }
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_STD_ATOMIC_HPP_INCLUDED
|
@@ -15,7 +15,7 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include <boost/detail/interlocked.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_interlocked.hpp>
|
||||
#include <boost/smart_ptr/detail/yield_k.hpp>
|
||||
|
||||
// BOOST_COMPILER_FENCE
|
||||
@@ -59,7 +59,7 @@ public:
|
||||
|
||||
bool try_lock()
|
||||
{
|
||||
long r = BOOST_INTERLOCKED_EXCHANGE( &v_, 1 );
|
||||
long r = BOOST_SP_INTERLOCKED_EXCHANGE( &v_, 1 );
|
||||
|
||||
BOOST_COMPILER_FENCE
|
||||
|
||||
|
26
include/boost/smart_ptr/detail/up_if_array.hpp
Normal file
26
include/boost/smart_ptr/detail/up_if_array.hpp
Normal 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<class T>
|
||||
struct up_if_array;
|
||||
|
||||
template<class T>
|
||||
struct up_if_array<T[]> {
|
||||
typedef std::unique_ptr<T[]> type;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
31
include/boost/smart_ptr/detail/up_if_not_array.hpp
Normal file
31
include/boost/smart_ptr/detail/up_if_not_array.hpp
Normal 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<class T>
|
||||
struct up_if_not_array {
|
||||
typedef std::unique_ptr<T> type;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct up_if_not_array<T[]> {
|
||||
};
|
||||
|
||||
template<class T, std::size_t N>
|
||||
struct up_if_not_array<T[N]> {
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@@ -11,6 +11,7 @@
|
||||
// yield_k.hpp
|
||||
//
|
||||
// Copyright (c) 2008 Peter Dimov
|
||||
// Copyright (c) Microsoft Corporation 2014
|
||||
//
|
||||
// void yield( unsigned k );
|
||||
//
|
||||
@@ -24,13 +25,17 @@
|
||||
//
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/predef.h>
|
||||
|
||||
#if BOOST_PLAT_WINDOWS_RUNTIME
|
||||
#include <thread>
|
||||
#endif
|
||||
|
||||
// BOOST_SMT_PAUSE
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1310 && ( defined(_M_IX86) || defined(_M_X64) )
|
||||
|
||||
extern "C" void _mm_pause();
|
||||
#pragma intrinsic( _mm_pause )
|
||||
|
||||
#define BOOST_SMT_PAUSE _mm_pause();
|
||||
|
||||
@@ -54,7 +59,7 @@ namespace boost
|
||||
namespace detail
|
||||
{
|
||||
|
||||
#if !defined( BOOST_USE_WINDOWS_H )
|
||||
#if !defined( BOOST_USE_WINDOWS_H ) && !BOOST_PLAT_WINDOWS_RUNTIME
|
||||
extern "C" void __stdcall Sleep( unsigned long ms );
|
||||
#endif
|
||||
|
||||
@@ -69,6 +74,7 @@ inline void yield( unsigned k )
|
||||
BOOST_SMT_PAUSE
|
||||
}
|
||||
#endif
|
||||
#if !BOOST_PLAT_WINDOWS_RUNTIME
|
||||
else if( k < 32 )
|
||||
{
|
||||
Sleep( 0 );
|
||||
@@ -77,6 +83,13 @@ inline void yield( unsigned k )
|
||||
{
|
||||
Sleep( 1 );
|
||||
}
|
||||
#else
|
||||
else
|
||||
{
|
||||
// Sleep isn't supported on the Windows Runtime.
|
||||
std::this_thread::yield();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
144
include/boost/smart_ptr/enable_shared_from_raw.hpp
Normal file
144
include/boost/smart_ptr/enable_shared_from_raw.hpp
Normal file
@@ -0,0 +1,144 @@
|
||||
#ifndef BOOST_ENABLE_SHARED_FROM_RAW_HPP_INCLUDED
|
||||
#define BOOST_ENABLE_SHARED_FROM_RAW_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// enable_shared_from_raw.hpp
|
||||
//
|
||||
// Copyright 2002, 2009 Peter Dimov
|
||||
// Copyright 2008-2009 Frank Mori Hess
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/weak_ptr.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
template<typename T> boost::shared_ptr<T> shared_from_raw(T *);
|
||||
template<typename T> boost::weak_ptr<T> weak_from_raw(T *);
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template< class X, class Y > inline void sp_enable_shared_from_this( boost::shared_ptr<X> * ppx, Y const * py, boost::enable_shared_from_raw const * pe );
|
||||
|
||||
} // namespace detail
|
||||
|
||||
class enable_shared_from_raw
|
||||
{
|
||||
protected:
|
||||
|
||||
enable_shared_from_raw()
|
||||
{
|
||||
}
|
||||
|
||||
enable_shared_from_raw( enable_shared_from_raw const & )
|
||||
{
|
||||
}
|
||||
|
||||
enable_shared_from_raw & operator=( enable_shared_from_raw const & )
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
~enable_shared_from_raw()
|
||||
{
|
||||
BOOST_ASSERT( shared_this_.use_count() <= 1 ); // make sure no dangling shared_ptr objects exist
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void init_weak_once() const
|
||||
{
|
||||
if( weak_this_.expired() )
|
||||
{
|
||||
shared_this_.reset( static_cast<void*>(0), detail::esft2_deleter_wrapper() );
|
||||
weak_this_ = shared_this_;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
|
||||
public:
|
||||
#else
|
||||
private:
|
||||
template<class Y> friend class shared_ptr;
|
||||
template<typename T> friend boost::shared_ptr<T> shared_from_raw(T *);
|
||||
template<typename T> friend boost::weak_ptr<T> weak_from_raw(T *);
|
||||
template< class X, class Y > friend inline void detail::sp_enable_shared_from_this( boost::shared_ptr<X> * ppx, Y const * py, boost::enable_shared_from_raw const * pe );
|
||||
#endif
|
||||
|
||||
shared_ptr<void> shared_from_this()
|
||||
{
|
||||
init_weak_once();
|
||||
return shared_ptr<void>( weak_this_ );
|
||||
}
|
||||
|
||||
shared_ptr<const void> shared_from_this() const
|
||||
{
|
||||
init_weak_once();
|
||||
return shared_ptr<const void>( weak_this_ );
|
||||
}
|
||||
|
||||
// Note: invoked automatically by shared_ptr; do not call
|
||||
template<class X, class Y> void _internal_accept_owner( shared_ptr<X> * ppx, Y * py ) const
|
||||
{
|
||||
BOOST_ASSERT( ppx != 0 );
|
||||
|
||||
if( weak_this_.expired() )
|
||||
{
|
||||
weak_this_ = *ppx;
|
||||
}
|
||||
else if( shared_this_.use_count() != 0 )
|
||||
{
|
||||
BOOST_ASSERT( ppx->unique() ); // no weak_ptrs should exist either, but there's no way to check that
|
||||
|
||||
detail::esft2_deleter_wrapper * pd = boost::get_deleter<detail::esft2_deleter_wrapper>( shared_this_ );
|
||||
BOOST_ASSERT( pd != 0 );
|
||||
|
||||
pd->set_deleter( *ppx );
|
||||
|
||||
ppx->reset( shared_this_, ppx->get() );
|
||||
shared_this_.reset();
|
||||
}
|
||||
}
|
||||
|
||||
mutable weak_ptr<void> weak_this_;
|
||||
private:
|
||||
mutable shared_ptr<void> shared_this_;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
boost::shared_ptr<T> shared_from_raw(T *p)
|
||||
{
|
||||
BOOST_ASSERT(p != 0);
|
||||
return boost::shared_ptr<T>(p->enable_shared_from_raw::shared_from_this(), p);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
boost::weak_ptr<T> weak_from_raw(T *p)
|
||||
{
|
||||
BOOST_ASSERT(p != 0);
|
||||
boost::weak_ptr<T> result;
|
||||
result._internal_aliasing_assign(p->enable_shared_from_raw::weak_this_, p);
|
||||
return result;
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template< class X, class Y > inline void sp_enable_shared_from_this( boost::shared_ptr<X> * ppx, Y const * py, boost::enable_shared_from_raw const * pe )
|
||||
{
|
||||
if( pe != 0 )
|
||||
{
|
||||
pe->_internal_accept_owner( ppx, const_cast< Y* >( py ) );
|
||||
}
|
||||
}
|
||||
} // namepsace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_ENABLE_SHARED_FROM_RAW_HPP_INCLUDED
|
@@ -25,20 +25,20 @@ template<class T> class enable_shared_from_this
|
||||
{
|
||||
protected:
|
||||
|
||||
enable_shared_from_this()
|
||||
enable_shared_from_this() BOOST_NOEXCEPT
|
||||
{
|
||||
}
|
||||
|
||||
enable_shared_from_this(enable_shared_from_this const &)
|
||||
enable_shared_from_this(enable_shared_from_this const &) BOOST_NOEXCEPT
|
||||
{
|
||||
}
|
||||
|
||||
enable_shared_from_this & operator=(enable_shared_from_this const &)
|
||||
enable_shared_from_this & operator=(enable_shared_from_this const &) BOOST_NOEXCEPT
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
~enable_shared_from_this()
|
||||
~enable_shared_from_this() BOOST_NOEXCEPT // ~weak_ptr<T> newer throws, so this call also must not throw
|
||||
{
|
||||
}
|
||||
|
||||
|
@@ -1,132 +0,0 @@
|
||||
#ifndef BOOST_ENABLE_SHARED_FROM_THIS2_HPP_INCLUDED
|
||||
#define BOOST_ENABLE_SHARED_FROM_THIS2_HPP_INCLUDED
|
||||
|
||||
//
|
||||
// enable_shared_from_this2.hpp
|
||||
//
|
||||
// Copyright 2002, 2009 Peter Dimov
|
||||
// Copyright 2008 Frank Mori Hess
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class esft2_deleter_wrapper
|
||||
{
|
||||
private:
|
||||
|
||||
shared_ptr<void> deleter_;
|
||||
|
||||
public:
|
||||
|
||||
esft2_deleter_wrapper()
|
||||
{
|
||||
}
|
||||
|
||||
template< class T > void set_deleter( shared_ptr<T> const & deleter )
|
||||
{
|
||||
deleter_ = deleter;
|
||||
}
|
||||
|
||||
template< class T> void operator()( T* )
|
||||
{
|
||||
BOOST_ASSERT( deleter_.use_count() <= 1 );
|
||||
deleter_.reset();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template< class T > class enable_shared_from_this2
|
||||
{
|
||||
protected:
|
||||
|
||||
enable_shared_from_this2()
|
||||
{
|
||||
}
|
||||
|
||||
enable_shared_from_this2( enable_shared_from_this2 const & )
|
||||
{
|
||||
}
|
||||
|
||||
enable_shared_from_this2 & operator=( enable_shared_from_this2 const & )
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
~enable_shared_from_this2()
|
||||
{
|
||||
BOOST_ASSERT( shared_this_.use_count() <= 1 ); // make sure no dangling shared_ptr objects exist
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
mutable weak_ptr<T> weak_this_;
|
||||
mutable shared_ptr<T> shared_this_;
|
||||
|
||||
public:
|
||||
|
||||
shared_ptr<T> shared_from_this()
|
||||
{
|
||||
init_weak_once();
|
||||
return shared_ptr<T>( weak_this_ );
|
||||
}
|
||||
|
||||
shared_ptr<T const> shared_from_this() const
|
||||
{
|
||||
init_weak_once();
|
||||
return shared_ptr<T>( weak_this_ );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void init_weak_once() const
|
||||
{
|
||||
if( weak_this_._empty() )
|
||||
{
|
||||
shared_this_.reset( static_cast< T* >( 0 ), detail::esft2_deleter_wrapper() );
|
||||
weak_this_ = shared_this_;
|
||||
}
|
||||
}
|
||||
|
||||
public: // actually private, but avoids compiler template friendship issues
|
||||
|
||||
// Note: invoked automatically by shared_ptr; do not call
|
||||
template<class X, class Y> void _internal_accept_owner( shared_ptr<X> * ppx, Y * py ) const
|
||||
{
|
||||
BOOST_ASSERT( ppx != 0 );
|
||||
|
||||
if( weak_this_.use_count() == 0 )
|
||||
{
|
||||
weak_this_ = shared_ptr<T>( *ppx, py );
|
||||
}
|
||||
else if( shared_this_.use_count() != 0 )
|
||||
{
|
||||
BOOST_ASSERT( ppx->unique() ); // no weak_ptrs should exist either, but there's no way to check that
|
||||
|
||||
detail::esft2_deleter_wrapper * pd = boost::get_deleter<detail::esft2_deleter_wrapper>( shared_this_ );
|
||||
BOOST_ASSERT( pd != 0 );
|
||||
|
||||
pd->set_deleter( *ppx );
|
||||
|
||||
ppx->reset( shared_this_, ppx->get() );
|
||||
shared_this_.reset();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_ENABLE_SHARED_FROM_THIS2_HPP_INCLUDED
|
@@ -18,6 +18,7 @@
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_convertible.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_nullptr_t.hpp>
|
||||
|
||||
#include <boost/config/no_tr1/functional.hpp> // for std::less
|
||||
|
||||
@@ -58,7 +59,7 @@ public:
|
||||
|
||||
typedef T element_type;
|
||||
|
||||
intrusive_ptr(): px( 0 )
|
||||
intrusive_ptr() BOOST_NOEXCEPT : px( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
@@ -108,14 +109,14 @@ public:
|
||||
|
||||
// Move support
|
||||
|
||||
#if defined( BOOST_HAS_RVALUE_REFS )
|
||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||
|
||||
intrusive_ptr(intrusive_ptr && rhs): px( rhs.px )
|
||||
intrusive_ptr(intrusive_ptr && rhs) BOOST_NOEXCEPT : px( rhs.px )
|
||||
{
|
||||
rhs.px = 0;
|
||||
}
|
||||
|
||||
intrusive_ptr & operator=(intrusive_ptr && rhs)
|
||||
intrusive_ptr & operator=(intrusive_ptr && rhs) BOOST_NOEXCEPT
|
||||
{
|
||||
this_type( static_cast< intrusive_ptr && >( rhs ) ).swap(*this);
|
||||
return *this;
|
||||
@@ -135,7 +136,7 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
void reset()
|
||||
void reset() BOOST_NOEXCEPT
|
||||
{
|
||||
this_type().swap( *this );
|
||||
}
|
||||
@@ -145,11 +146,23 @@ public:
|
||||
this_type( rhs ).swap( *this );
|
||||
}
|
||||
|
||||
T * get() const
|
||||
void reset( T * rhs, bool add_ref )
|
||||
{
|
||||
this_type( rhs, add_ref ).swap( *this );
|
||||
}
|
||||
|
||||
T * get() const BOOST_NOEXCEPT
|
||||
{
|
||||
return px;
|
||||
}
|
||||
|
||||
T * detach() BOOST_NOEXCEPT
|
||||
{
|
||||
T * ret = px;
|
||||
px = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
T & operator*() const
|
||||
{
|
||||
BOOST_ASSERT( px != 0 );
|
||||
@@ -165,7 +178,7 @@ public:
|
||||
// implicit conversion to "bool"
|
||||
#include <boost/smart_ptr/detail/operator_bool.hpp>
|
||||
|
||||
void swap(intrusive_ptr & rhs)
|
||||
void swap(intrusive_ptr & rhs) BOOST_NOEXCEPT
|
||||
{
|
||||
T * tmp = px;
|
||||
px = rhs.px;
|
||||
@@ -218,6 +231,30 @@ template<class T> inline bool operator!=(intrusive_ptr<T> const & a, intrusive_p
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_NULLPTR )
|
||||
|
||||
template<class T> inline bool operator==( intrusive_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
|
||||
{
|
||||
return p.get() == 0;
|
||||
}
|
||||
|
||||
template<class T> inline bool operator==( boost::detail::sp_nullptr_t, intrusive_ptr<T> const & p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return p.get() == 0;
|
||||
}
|
||||
|
||||
template<class T> inline bool operator!=( intrusive_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
|
||||
{
|
||||
return p.get() != 0;
|
||||
}
|
||||
|
||||
template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, intrusive_ptr<T> const & p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return p.get() != 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template<class T> inline bool operator<(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b)
|
||||
{
|
||||
return std::less<T *>()(a.get(), b.get());
|
||||
|
187
include/boost/smart_ptr/intrusive_ref_counter.hpp
Normal file
187
include/boost/smart_ptr/intrusive_ref_counter.hpp
Normal file
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
* Copyright Andrey Semashev 2007 - 2013.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
/*!
|
||||
* \file intrusive_ref_counter.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 12.03.2009
|
||||
*
|
||||
* This header contains a reference counter class for \c intrusive_ptr.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_SMART_PTR_INTRUSIVE_REF_COUNTER_HPP_INCLUDED_
|
||||
#define BOOST_SMART_PTR_INTRUSIVE_REF_COUNTER_HPP_INCLUDED_
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/smart_ptr/detail/atomic_count.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
// This is a bogus MSVC warning, which is flagged by friend declarations of intrusive_ptr_add_ref and intrusive_ptr_release in intrusive_ref_counter:
|
||||
// 'name' : the inline specifier cannot be used when a friend declaration refers to a specialization of a function template
|
||||
// Note that there is no inline specifier in the declarations.
|
||||
#pragma warning(disable: 4396)
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace sp_adl_block {
|
||||
|
||||
/*!
|
||||
* \brief Thread unsafe reference counter policy for \c intrusive_ref_counter
|
||||
*
|
||||
* The policy instructs the \c intrusive_ref_counter base class to implement
|
||||
* a reference counter suitable for single threaded use only. Pointers to the same
|
||||
* object with this kind of reference counter must not be used by different threads.
|
||||
*/
|
||||
struct thread_unsafe_counter
|
||||
{
|
||||
typedef unsigned int type;
|
||||
|
||||
static unsigned int load(unsigned int const& counter) BOOST_NOEXCEPT
|
||||
{
|
||||
return counter;
|
||||
}
|
||||
|
||||
static void increment(unsigned int& counter) BOOST_NOEXCEPT
|
||||
{
|
||||
++counter;
|
||||
}
|
||||
|
||||
static unsigned int decrement(unsigned int& counter) BOOST_NOEXCEPT
|
||||
{
|
||||
return --counter;
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Thread safe reference counter policy for \c intrusive_ref_counter
|
||||
*
|
||||
* The policy instructs the \c intrusive_ref_counter base class to implement
|
||||
* a thread-safe reference counter, if the target platform supports multithreading.
|
||||
*/
|
||||
struct thread_safe_counter
|
||||
{
|
||||
typedef boost::detail::atomic_count type;
|
||||
|
||||
static unsigned int load(boost::detail::atomic_count const& counter) BOOST_NOEXCEPT
|
||||
{
|
||||
return static_cast< unsigned int >(static_cast< long >(counter));
|
||||
}
|
||||
|
||||
static void increment(boost::detail::atomic_count& counter) BOOST_NOEXCEPT
|
||||
{
|
||||
++counter;
|
||||
}
|
||||
|
||||
static unsigned int decrement(boost::detail::atomic_count& counter) BOOST_NOEXCEPT
|
||||
{
|
||||
return --counter;
|
||||
}
|
||||
};
|
||||
|
||||
template< typename DerivedT, typename CounterPolicyT = thread_safe_counter >
|
||||
class intrusive_ref_counter;
|
||||
|
||||
template< typename DerivedT, typename CounterPolicyT >
|
||||
void intrusive_ptr_add_ref(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT;
|
||||
template< typename DerivedT, typename CounterPolicyT >
|
||||
void intrusive_ptr_release(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT;
|
||||
|
||||
/*!
|
||||
* \brief A reference counter base class
|
||||
*
|
||||
* This base class can be used with user-defined classes to add support
|
||||
* for \c intrusive_ptr. The class contains a reference counter defined by the \c CounterPolicyT.
|
||||
* Upon releasing the last \c intrusive_ptr referencing the object
|
||||
* derived from the \c intrusive_ref_counter class, operator \c delete
|
||||
* is automatically called on the pointer to the object.
|
||||
*
|
||||
* The other template parameter, \c DerivedT, is the user's class that derives from \c intrusive_ref_counter.
|
||||
*/
|
||||
template< typename DerivedT, typename CounterPolicyT >
|
||||
class intrusive_ref_counter
|
||||
{
|
||||
private:
|
||||
//! Reference counter type
|
||||
typedef typename CounterPolicyT::type counter_type;
|
||||
//! Reference counter
|
||||
mutable counter_type m_ref_counter;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Default constructor
|
||||
*
|
||||
* \post <tt>use_count() == 0</tt>
|
||||
*/
|
||||
intrusive_ref_counter() BOOST_NOEXCEPT : m_ref_counter(0)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* Copy constructor
|
||||
*
|
||||
* \post <tt>use_count() == 0</tt>
|
||||
*/
|
||||
intrusive_ref_counter(intrusive_ref_counter const&) BOOST_NOEXCEPT : m_ref_counter(0)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* Assignment
|
||||
*
|
||||
* \post The reference counter is not modified after assignment
|
||||
*/
|
||||
intrusive_ref_counter& operator= (intrusive_ref_counter const&) BOOST_NOEXCEPT { return *this; }
|
||||
|
||||
/*!
|
||||
* \return The reference counter
|
||||
*/
|
||||
unsigned int use_count() const BOOST_NOEXCEPT
|
||||
{
|
||||
return CounterPolicyT::load(m_ref_counter);
|
||||
}
|
||||
|
||||
protected:
|
||||
/*!
|
||||
* Destructor
|
||||
*/
|
||||
BOOST_DEFAULTED_FUNCTION(~intrusive_ref_counter(), {})
|
||||
|
||||
friend void intrusive_ptr_add_ref< DerivedT, CounterPolicyT >(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT;
|
||||
friend void intrusive_ptr_release< DerivedT, CounterPolicyT >(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT;
|
||||
};
|
||||
|
||||
template< typename DerivedT, typename CounterPolicyT >
|
||||
inline void intrusive_ptr_add_ref(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT
|
||||
{
|
||||
CounterPolicyT::increment(p->m_ref_counter);
|
||||
}
|
||||
|
||||
template< typename DerivedT, typename CounterPolicyT >
|
||||
inline void intrusive_ptr_release(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT
|
||||
{
|
||||
if (CounterPolicyT::decrement(p->m_ref_counter) == 0)
|
||||
delete static_cast< const DerivedT* >(p);
|
||||
}
|
||||
|
||||
} // namespace sp_adl_block
|
||||
|
||||
using sp_adl_block::intrusive_ref_counter;
|
||||
using sp_adl_block::thread_unsafe_counter;
|
||||
using sp_adl_block::thread_safe_counter;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif // BOOST_SMART_PTR_INTRUSIVE_REF_COUNTER_HPP_INCLUDED_
|
@@ -3,7 +3,7 @@
|
||||
|
||||
// make_shared.hpp
|
||||
//
|
||||
// Copyright (c) 2007, 2008 Peter Dimov
|
||||
// Copyright (c) 2007, 2008, 2012 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -12,970 +12,11 @@
|
||||
// See http://www.boost.org/libs/smart_ptr/make_shared.html
|
||||
// for documentation.
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/smart_ptr/shared_ptr.hpp>
|
||||
#include <boost/type_traits/type_with_alignment.hpp>
|
||||
#include <boost/type_traits/alignment_of.hpp>
|
||||
#include <cstddef>
|
||||
#include <new>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template< std::size_t N, std::size_t A > struct sp_aligned_storage
|
||||
{
|
||||
union type
|
||||
{
|
||||
char data_[ N ];
|
||||
typename boost::type_with_alignment< A >::type align_;
|
||||
};
|
||||
};
|
||||
|
||||
template< class T > class sp_ms_deleter
|
||||
{
|
||||
private:
|
||||
|
||||
typedef typename sp_aligned_storage< sizeof( T ), ::boost::alignment_of< T >::value >::type storage_type;
|
||||
|
||||
bool initialized_;
|
||||
storage_type storage_;
|
||||
|
||||
private:
|
||||
|
||||
void destroy()
|
||||
{
|
||||
if( initialized_ )
|
||||
{
|
||||
#if defined( __GNUC__ )
|
||||
|
||||
// fixes incorrect aliasing warning
|
||||
T * p = reinterpret_cast< T* >( storage_.data_ );
|
||||
p->~T();
|
||||
|
||||
#else
|
||||
|
||||
reinterpret_cast< T* >( storage_.data_ )->~T();
|
||||
#include <boost/smart_ptr/make_shared_object.hpp>
|
||||
|
||||
#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) && !defined( BOOST_NO_SFINAE )
|
||||
# include <boost/smart_ptr/make_shared_array.hpp>
|
||||
# include <boost/smart_ptr/allocate_shared_array.hpp>
|
||||
#endif
|
||||
|
||||
initialized_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
sp_ms_deleter(): initialized_( false )
|
||||
{
|
||||
}
|
||||
|
||||
// optimization: do not copy storage_
|
||||
sp_ms_deleter( sp_ms_deleter const & ): initialized_( false )
|
||||
{
|
||||
}
|
||||
|
||||
~sp_ms_deleter()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
void operator()( T * )
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
void * address()
|
||||
{
|
||||
return storage_.data_;
|
||||
}
|
||||
|
||||
void set_initialized()
|
||||
{
|
||||
initialized_ = true;
|
||||
}
|
||||
};
|
||||
|
||||
#if defined( BOOST_HAS_RVALUE_REFS )
|
||||
|
||||
template< class T > T&& sp_forward( T & t )
|
||||
{
|
||||
return static_cast< T&& >( t );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
#if !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
|
||||
# define BOOST_SP_MSD( T ) boost::detail::sp_inplace_tag< boost::detail::sp_ms_deleter< T > >()
|
||||
#else
|
||||
# define BOOST_SP_MSD( T ) boost::detail::sp_ms_deleter< T >()
|
||||
#endif
|
||||
|
||||
// Zero-argument versions
|
||||
//
|
||||
// Used even when variadic templates are available because of the new T() vs new T issue
|
||||
|
||||
template< class T > boost::shared_ptr< T > make_shared()
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T();
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A > boost::shared_ptr< T > allocate_shared( A const & a )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T();
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
#if defined( BOOST_HAS_VARIADIC_TMPL ) && defined( BOOST_HAS_RVALUE_REFS )
|
||||
|
||||
// Variadic templates, rvalue reference
|
||||
|
||||
template< class T, class Arg1, class... Args > boost::shared_ptr< T > make_shared( Arg1 && arg1, Args && ... args )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T( boost::detail::sp_forward<Arg1>( arg1 ), boost::detail::sp_forward<Args>( args )... );
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A, class Arg1, class... Args > boost::shared_ptr< T > allocate_shared( A const & a, Arg1 && arg1, Args && ... args )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T( boost::detail::sp_forward<Arg1>( arg1 ), boost::detail::sp_forward<Args>( args )... );
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
#elif defined( BOOST_HAS_RVALUE_REFS )
|
||||
|
||||
// For example MSVC 10.0
|
||||
|
||||
template< class T, class A1 >
|
||||
boost::shared_ptr< T > make_shared( A1 && a1 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T(
|
||||
boost::detail::sp_forward<A1>( a1 )
|
||||
);
|
||||
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A, class A1 >
|
||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 && a1 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T(
|
||||
boost::detail::sp_forward<A1>( a1 )
|
||||
);
|
||||
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A1, class A2 >
|
||||
boost::shared_ptr< T > make_shared( A1 && a1, A2 && a2 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T(
|
||||
boost::detail::sp_forward<A1>( a1 ),
|
||||
boost::detail::sp_forward<A2>( a2 )
|
||||
);
|
||||
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A, class A1, class A2 >
|
||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 && a1, A2 && a2 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T(
|
||||
boost::detail::sp_forward<A1>( a1 ),
|
||||
boost::detail::sp_forward<A2>( a2 )
|
||||
);
|
||||
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A1, class A2, class A3 >
|
||||
boost::shared_ptr< T > make_shared( A1 && a1, A2 && a2, A3 && a3 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T(
|
||||
boost::detail::sp_forward<A1>( a1 ),
|
||||
boost::detail::sp_forward<A2>( a2 ),
|
||||
boost::detail::sp_forward<A3>( a3 )
|
||||
);
|
||||
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A, class A1, class A2, class A3 >
|
||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 && a1, A2 && a2, A3 && a3 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T(
|
||||
boost::detail::sp_forward<A1>( a1 ),
|
||||
boost::detail::sp_forward<A2>( a2 ),
|
||||
boost::detail::sp_forward<A3>( a3 )
|
||||
);
|
||||
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A1, class A2, class A3, class A4 >
|
||||
boost::shared_ptr< T > make_shared( A1 && a1, A2 && a2, A3 && a3, A4 && a4 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T(
|
||||
boost::detail::sp_forward<A1>( a1 ),
|
||||
boost::detail::sp_forward<A2>( a2 ),
|
||||
boost::detail::sp_forward<A3>( a3 ),
|
||||
boost::detail::sp_forward<A4>( a4 )
|
||||
);
|
||||
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A, class A1, class A2, class A3, class A4 >
|
||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 && a1, A2 && a2, A3 && a3, A4 && a4 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T(
|
||||
boost::detail::sp_forward<A1>( a1 ),
|
||||
boost::detail::sp_forward<A2>( a2 ),
|
||||
boost::detail::sp_forward<A3>( a3 ),
|
||||
boost::detail::sp_forward<A4>( a4 )
|
||||
);
|
||||
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A1, class A2, class A3, class A4, class A5 >
|
||||
boost::shared_ptr< T > make_shared( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T(
|
||||
boost::detail::sp_forward<A1>( a1 ),
|
||||
boost::detail::sp_forward<A2>( a2 ),
|
||||
boost::detail::sp_forward<A3>( a3 ),
|
||||
boost::detail::sp_forward<A4>( a4 ),
|
||||
boost::detail::sp_forward<A5>( a5 )
|
||||
);
|
||||
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A, class A1, class A2, class A3, class A4, class A5 >
|
||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T(
|
||||
boost::detail::sp_forward<A1>( a1 ),
|
||||
boost::detail::sp_forward<A2>( a2 ),
|
||||
boost::detail::sp_forward<A3>( a3 ),
|
||||
boost::detail::sp_forward<A4>( a4 ),
|
||||
boost::detail::sp_forward<A5>( a5 )
|
||||
);
|
||||
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A1, class A2, class A3, class A4, class A5, class A6 >
|
||||
boost::shared_ptr< T > make_shared( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T(
|
||||
boost::detail::sp_forward<A1>( a1 ),
|
||||
boost::detail::sp_forward<A2>( a2 ),
|
||||
boost::detail::sp_forward<A3>( a3 ),
|
||||
boost::detail::sp_forward<A4>( a4 ),
|
||||
boost::detail::sp_forward<A5>( a5 ),
|
||||
boost::detail::sp_forward<A6>( a6 )
|
||||
);
|
||||
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6 >
|
||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T(
|
||||
boost::detail::sp_forward<A1>( a1 ),
|
||||
boost::detail::sp_forward<A2>( a2 ),
|
||||
boost::detail::sp_forward<A3>( a3 ),
|
||||
boost::detail::sp_forward<A4>( a4 ),
|
||||
boost::detail::sp_forward<A5>( a5 ),
|
||||
boost::detail::sp_forward<A6>( a6 )
|
||||
);
|
||||
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7 >
|
||||
boost::shared_ptr< T > make_shared( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T(
|
||||
boost::detail::sp_forward<A1>( a1 ),
|
||||
boost::detail::sp_forward<A2>( a2 ),
|
||||
boost::detail::sp_forward<A3>( a3 ),
|
||||
boost::detail::sp_forward<A4>( a4 ),
|
||||
boost::detail::sp_forward<A5>( a5 ),
|
||||
boost::detail::sp_forward<A6>( a6 ),
|
||||
boost::detail::sp_forward<A7>( a7 )
|
||||
);
|
||||
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7 >
|
||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T(
|
||||
boost::detail::sp_forward<A1>( a1 ),
|
||||
boost::detail::sp_forward<A2>( a2 ),
|
||||
boost::detail::sp_forward<A3>( a3 ),
|
||||
boost::detail::sp_forward<A4>( a4 ),
|
||||
boost::detail::sp_forward<A5>( a5 ),
|
||||
boost::detail::sp_forward<A6>( a6 ),
|
||||
boost::detail::sp_forward<A7>( a7 )
|
||||
);
|
||||
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 >
|
||||
boost::shared_ptr< T > make_shared( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7, A8 && a8 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T(
|
||||
boost::detail::sp_forward<A1>( a1 ),
|
||||
boost::detail::sp_forward<A2>( a2 ),
|
||||
boost::detail::sp_forward<A3>( a3 ),
|
||||
boost::detail::sp_forward<A4>( a4 ),
|
||||
boost::detail::sp_forward<A5>( a5 ),
|
||||
boost::detail::sp_forward<A6>( a6 ),
|
||||
boost::detail::sp_forward<A7>( a7 ),
|
||||
boost::detail::sp_forward<A8>( a8 )
|
||||
);
|
||||
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 >
|
||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7, A8 && a8 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T(
|
||||
boost::detail::sp_forward<A1>( a1 ),
|
||||
boost::detail::sp_forward<A2>( a2 ),
|
||||
boost::detail::sp_forward<A3>( a3 ),
|
||||
boost::detail::sp_forward<A4>( a4 ),
|
||||
boost::detail::sp_forward<A5>( a5 ),
|
||||
boost::detail::sp_forward<A6>( a6 ),
|
||||
boost::detail::sp_forward<A7>( a7 ),
|
||||
boost::detail::sp_forward<A8>( a8 )
|
||||
);
|
||||
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 >
|
||||
boost::shared_ptr< T > make_shared( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7, A8 && a8, A9 && a9 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T(
|
||||
boost::detail::sp_forward<A1>( a1 ),
|
||||
boost::detail::sp_forward<A2>( a2 ),
|
||||
boost::detail::sp_forward<A3>( a3 ),
|
||||
boost::detail::sp_forward<A4>( a4 ),
|
||||
boost::detail::sp_forward<A5>( a5 ),
|
||||
boost::detail::sp_forward<A6>( a6 ),
|
||||
boost::detail::sp_forward<A7>( a7 ),
|
||||
boost::detail::sp_forward<A8>( a8 ),
|
||||
boost::detail::sp_forward<A9>( a9 )
|
||||
);
|
||||
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 >
|
||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7, A8 && a8, A9 && a9 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T(
|
||||
boost::detail::sp_forward<A1>( a1 ),
|
||||
boost::detail::sp_forward<A2>( a2 ),
|
||||
boost::detail::sp_forward<A3>( a3 ),
|
||||
boost::detail::sp_forward<A4>( a4 ),
|
||||
boost::detail::sp_forward<A5>( a5 ),
|
||||
boost::detail::sp_forward<A6>( a6 ),
|
||||
boost::detail::sp_forward<A7>( a7 ),
|
||||
boost::detail::sp_forward<A8>( a8 ),
|
||||
boost::detail::sp_forward<A9>( a9 )
|
||||
);
|
||||
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// C++03 version
|
||||
|
||||
template< class T, class A1 >
|
||||
boost::shared_ptr< T > make_shared( A1 const & a1 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T( a1 );
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A, class A1 >
|
||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T( a1 );
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A1, class A2 >
|
||||
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T( a1, a2 );
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A, class A1, class A2 >
|
||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T( a1, a2 );
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A1, class A2, class A3 >
|
||||
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T( a1, a2, a3 );
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A, class A1, class A2, class A3 >
|
||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T( a1, a2, a3 );
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A1, class A2, class A3, class A4 >
|
||||
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T( a1, a2, a3, a4 );
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A, class A1, class A2, class A3, class A4 >
|
||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T( a1, a2, a3, a4 );
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A1, class A2, class A3, class A4, class A5 >
|
||||
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T( a1, a2, a3, a4, a5 );
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A, class A1, class A2, class A3, class A4, class A5 >
|
||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T( a1, a2, a3, a4, a5 );
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A1, class A2, class A3, class A4, class A5, class A6 >
|
||||
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T( a1, a2, a3, a4, a5, a6 );
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6 >
|
||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T( a1, a2, a3, a4, a5, a6 );
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7 >
|
||||
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T( a1, a2, a3, a4, a5, a6, a7 );
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7 >
|
||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T( a1, a2, a3, a4, a5, a6, a7 );
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 >
|
||||
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8 );
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 >
|
||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8 );
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 >
|
||||
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8, A9 const & a9 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8, a9 );
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 >
|
||||
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8, A9 const & a9 )
|
||||
{
|
||||
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
|
||||
|
||||
boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
|
||||
|
||||
void * pv = pd->address();
|
||||
|
||||
::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8, a9 );
|
||||
pd->set_initialized();
|
||||
|
||||
T * pt2 = static_cast< T* >( pv );
|
||||
|
||||
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
|
||||
return boost::shared_ptr< T >( pt, pt2 );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#undef BOOST_SP_MSD
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_MAKE_SHARED_HPP_INCLUDED
|
||||
|
158
include/boost/smart_ptr/make_shared_array.hpp
Normal file
158
include/boost/smart_ptr/make_shared_array.hpp
Normal file
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* 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_MAKE_SHARED_ARRAY_HPP
|
||||
#define BOOST_SMART_PTR_MAKE_SHARED_ARRAY_HPP
|
||||
|
||||
#include <boost/smart_ptr/detail/array_count_impl.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_if_array.hpp>
|
||||
|
||||
namespace boost {
|
||||
template<class T>
|
||||
inline typename boost::detail::sp_if_array<T>::type
|
||||
make_shared(std::size_t size) {
|
||||
typedef typename boost::detail::array_inner<T>::type T1;
|
||||
typedef typename boost::detail::array_base<T1>::type T2;
|
||||
typedef boost::detail::ms_allocator<T> A1;
|
||||
typedef boost::detail::ms_in_allocator_tag D1;
|
||||
std::size_t n1 = size * boost::detail::array_total<T1>::size;
|
||||
T1* p1 = 0;
|
||||
T2* p2 = 0;
|
||||
D1 d1;
|
||||
A1 a1(size, &p2);
|
||||
shared_ptr<T> s1(p1, d1, a1);
|
||||
A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter());
|
||||
a2->set(0);
|
||||
boost::detail::ms_init(p2, n1);
|
||||
a2->set(p2);
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
return shared_ptr<T>(s1, p1);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline typename boost::detail::sp_if_size_array<T>::type
|
||||
make_shared() {
|
||||
typedef typename boost::detail::array_inner<T>::type T1;
|
||||
typedef typename boost::detail::array_base<T1>::type T2;
|
||||
typedef boost::detail::ms_allocator<T> A1;
|
||||
typedef boost::detail::ms_in_allocator_tag D1;
|
||||
enum {
|
||||
N = boost::detail::array_total<T>::size
|
||||
};
|
||||
T1* p1 = 0;
|
||||
T2* p2 = 0;
|
||||
D1 d1;
|
||||
A1 a1(&p2);
|
||||
shared_ptr<T> s1(p1, d1, a1);
|
||||
A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter());
|
||||
a2->set(0);
|
||||
boost::detail::ms_init(p2, N);
|
||||
a2->set(p2);
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
return shared_ptr<T>(s1, p1);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline typename boost::detail::sp_if_array<T>::type
|
||||
make_shared(std::size_t size,
|
||||
const typename boost::detail::array_inner<T>::type& value) {
|
||||
typedef typename boost::detail::array_inner<T>::type T1;
|
||||
typedef typename boost::detail::array_base<T1>::type T2;
|
||||
typedef const T2 T3;
|
||||
typedef boost::detail::ms_allocator<T> A1;
|
||||
typedef boost::detail::ms_in_allocator_tag D1;
|
||||
enum {
|
||||
M = boost::detail::array_total<T1>::size
|
||||
};
|
||||
std::size_t n1 = M * size;
|
||||
T1* p1 = 0;
|
||||
T2* p2 = 0;
|
||||
T3* p3 = reinterpret_cast<T3*>(&value);
|
||||
D1 d1;
|
||||
A1 a1(size, &p2);
|
||||
shared_ptr<T> s1(p1, d1, a1);
|
||||
A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter());
|
||||
a2->set(0);
|
||||
boost::detail::ms_init<T2, M>(p2, n1, p3);
|
||||
a2->set(p2);
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
return shared_ptr<T>(s1, p1);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline typename boost::detail::sp_if_size_array<T>::type
|
||||
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_base<T1>::type T2;
|
||||
typedef const T2 T3;
|
||||
typedef boost::detail::ms_allocator<T> A1;
|
||||
typedef boost::detail::ms_in_allocator_tag D1;
|
||||
enum {
|
||||
M = boost::detail::array_total<T1>::size,
|
||||
N = boost::detail::array_total<T>::size
|
||||
};
|
||||
T1* p1 = 0;
|
||||
T2* p2 = 0;
|
||||
T3* p3 = reinterpret_cast<T3*>(&value);
|
||||
D1 d1;
|
||||
A1 a1(&p2);
|
||||
shared_ptr<T> s1(p1, d1, a1);
|
||||
A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter());
|
||||
a2->set(0);
|
||||
boost::detail::ms_init<T2, M>(p2, N, p3);
|
||||
a2->set(p2);
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
return shared_ptr<T>(s1, p1);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline typename boost::detail::sp_if_array<T>::type
|
||||
make_shared_noinit(std::size_t size) {
|
||||
typedef typename boost::detail::array_inner<T>::type T1;
|
||||
typedef typename boost::detail::array_base<T1>::type T2;
|
||||
typedef boost::detail::ms_allocator<T> A1;
|
||||
typedef boost::detail::ms_in_allocator_tag D1;
|
||||
std::size_t n1 = size * boost::detail::array_total<T1>::size;
|
||||
T1* p1 = 0;
|
||||
T2* p2 = 0;
|
||||
D1 d1;
|
||||
A1 a1(size, &p2);
|
||||
shared_ptr<T> s1(p1, d1, a1);
|
||||
A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter());
|
||||
a2->set(0);
|
||||
boost::detail::ms_noinit(p2, n1);
|
||||
a2->set(p2);
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
return shared_ptr<T>(s1, p1);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline typename boost::detail::sp_if_size_array<T>::type
|
||||
make_shared_noinit() {
|
||||
typedef typename boost::detail::array_inner<T>::type T1;
|
||||
typedef typename boost::detail::array_base<T1>::type T2;
|
||||
typedef boost::detail::ms_allocator<T> A1;
|
||||
typedef boost::detail::ms_in_allocator_tag D1;
|
||||
enum {
|
||||
N = boost::detail::array_total<T>::size
|
||||
};
|
||||
T1* p1 = 0;
|
||||
T2* p2 = 0;
|
||||
D1 d1;
|
||||
A1 a1(&p2);
|
||||
shared_ptr<T> s1(p1, d1, a1);
|
||||
A1* a2 = static_cast<A1*>(s1._internal_get_untyped_deleter());
|
||||
a2->set(0);
|
||||
boost::detail::ms_noinit(p2, N);
|
||||
a2->set(p2);
|
||||
p1 = reinterpret_cast<T1*>(p2);
|
||||
return shared_ptr<T>(s1, p1);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
1131
include/boost/smart_ptr/make_shared_object.hpp
Normal file
1131
include/boost/smart_ptr/make_shared_object.hpp
Normal file
File diff suppressed because it is too large
Load Diff
15
include/boost/smart_ptr/make_unique.hpp
Normal file
15
include/boost/smart_ptr/make_unique.hpp
Normal 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
|
31
include/boost/smart_ptr/make_unique_array.hpp
Normal file
31
include/boost/smart_ptr/make_unique_array.hpp
Normal 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<class 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<class 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
|
45
include/boost/smart_ptr/make_unique_object.hpp
Normal file
45
include/boost/smart_ptr/make_unique_object.hpp
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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 <boost/type_traits/add_rvalue_reference.hpp>
|
||||
#include <utility>
|
||||
|
||||
namespace boost {
|
||||
template<class 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<class T, class... 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<class T>
|
||||
inline typename boost::detail::up_if_not_array<T>::type
|
||||
make_unique(typename add_rvalue_reference<T>::type value) {
|
||||
return std::unique_ptr<T>(new T(std::move(value)));
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline typename boost::detail::up_if_not_array<T>::type
|
||||
make_unique_noinit() {
|
||||
return std::unique_ptr<T>(new T);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@@ -11,9 +11,10 @@
|
||||
// http://www.boost.org/libs/smart_ptr/scoped_array.htm
|
||||
//
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/checked_delete.hpp>
|
||||
#include <boost/config.hpp> // in case ptrdiff_t not in std
|
||||
#include <boost/smart_ptr/detail/sp_nullptr_t.hpp>
|
||||
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
@@ -53,7 +54,7 @@ public:
|
||||
|
||||
typedef T element_type;
|
||||
|
||||
explicit scoped_array( T * p = 0 ) : px( p ) // never throws
|
||||
explicit scoped_array( T * p = 0 ) BOOST_NOEXCEPT : px( p )
|
||||
{
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
boost::sp_array_constructor_hook( px );
|
||||
@@ -68,20 +69,20 @@ public:
|
||||
boost::checked_array_delete( px );
|
||||
}
|
||||
|
||||
void reset(T * p = 0) // never throws
|
||||
void reset(T * p = 0) // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT)
|
||||
{
|
||||
BOOST_ASSERT( p == 0 || p != px ); // catch self-reset errors
|
||||
this_type(p).swap(*this);
|
||||
}
|
||||
|
||||
T & operator[](std::ptrdiff_t i) const // never throws
|
||||
T & operator[](std::ptrdiff_t i) const // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT)
|
||||
{
|
||||
BOOST_ASSERT( px != 0 );
|
||||
BOOST_ASSERT( i >= 0 );
|
||||
return px[i];
|
||||
}
|
||||
|
||||
T * get() const // never throws
|
||||
T * get() const BOOST_NOEXCEPT
|
||||
{
|
||||
return px;
|
||||
}
|
||||
@@ -89,7 +90,7 @@ public:
|
||||
// implicit conversion to "bool"
|
||||
#include <boost/smart_ptr/detail/operator_bool.hpp>
|
||||
|
||||
void swap(scoped_array & b) // never throws
|
||||
void swap(scoped_array & b) BOOST_NOEXCEPT
|
||||
{
|
||||
T * tmp = b.px;
|
||||
b.px = px;
|
||||
@@ -97,7 +98,31 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template<class T> inline void swap(scoped_array<T> & a, scoped_array<T> & b) // never throws
|
||||
#if !defined( BOOST_NO_CXX11_NULLPTR )
|
||||
|
||||
template<class T> inline bool operator==( scoped_array<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
|
||||
{
|
||||
return p.get() == 0;
|
||||
}
|
||||
|
||||
template<class T> inline bool operator==( boost::detail::sp_nullptr_t, scoped_array<T> const & p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return p.get() == 0;
|
||||
}
|
||||
|
||||
template<class T> inline bool operator!=( scoped_array<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
|
||||
{
|
||||
return p.get() != 0;
|
||||
}
|
||||
|
||||
template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, scoped_array<T> const & p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return p.get() != 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template<class T> inline void swap(scoped_array<T> & a, scoped_array<T> & b) BOOST_NOEXCEPT
|
||||
{
|
||||
a.swap(b);
|
||||
}
|
||||
|
@@ -11,8 +11,10 @@
|
||||
// http://www.boost.org/libs/smart_ptr/scoped_ptr.htm
|
||||
//
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/checked_delete.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_nullptr_t.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
#ifndef BOOST_NO_AUTO_PTR
|
||||
@@ -63,7 +65,7 @@ public:
|
||||
|
||||
#ifndef BOOST_NO_AUTO_PTR
|
||||
|
||||
explicit scoped_ptr( std::auto_ptr<T> p ): px( p.release() ) // never throws
|
||||
explicit scoped_ptr( std::auto_ptr<T> p ) BOOST_NOEXCEPT : px( p.release() )
|
||||
{
|
||||
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
||||
boost::sp_scalar_constructor_hook( px );
|
||||
@@ -98,7 +100,7 @@ public:
|
||||
return px;
|
||||
}
|
||||
|
||||
T * get() const // never throws
|
||||
T * get() const BOOST_NOEXCEPT
|
||||
{
|
||||
return px;
|
||||
}
|
||||
@@ -106,7 +108,7 @@ public:
|
||||
// implicit conversion to "bool"
|
||||
#include <boost/smart_ptr/detail/operator_bool.hpp>
|
||||
|
||||
void swap(scoped_ptr & b) // never throws
|
||||
void swap(scoped_ptr & b) BOOST_NOEXCEPT
|
||||
{
|
||||
T * tmp = b.px;
|
||||
b.px = px;
|
||||
@@ -114,14 +116,38 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template<class T> inline void swap(scoped_ptr<T> & a, scoped_ptr<T> & b) // never throws
|
||||
#if !defined( BOOST_NO_CXX11_NULLPTR )
|
||||
|
||||
template<class T> inline bool operator==( scoped_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
|
||||
{
|
||||
return p.get() == 0;
|
||||
}
|
||||
|
||||
template<class T> inline bool operator==( boost::detail::sp_nullptr_t, scoped_ptr<T> const & p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return p.get() == 0;
|
||||
}
|
||||
|
||||
template<class T> inline bool operator!=( scoped_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
|
||||
{
|
||||
return p.get() != 0;
|
||||
}
|
||||
|
||||
template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, scoped_ptr<T> const & p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return p.get() != 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template<class T> inline void swap(scoped_ptr<T> & a, scoped_ptr<T> & b) BOOST_NOEXCEPT
|
||||
{
|
||||
a.swap(b);
|
||||
}
|
||||
|
||||
// get_pointer(p) is a generic way to say p.get()
|
||||
|
||||
template<class T> inline T * get_pointer(scoped_ptr<T> const & p)
|
||||
template<class T> inline T * get_pointer(scoped_ptr<T> const & p) BOOST_NOEXCEPT
|
||||
{
|
||||
return p.get();
|
||||
}
|
||||
|
@@ -5,7 +5,7 @@
|
||||
// shared_array.hpp
|
||||
//
|
||||
// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
|
||||
// Copyright (c) 2001, 2002 Peter Dimov
|
||||
// Copyright (c) 2001, 2002, 2012 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -16,16 +16,14 @@
|
||||
|
||||
#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 <boost/assert.hpp>
|
||||
#include <boost/checked_delete.hpp>
|
||||
|
||||
#include <boost/smart_ptr/shared_ptr.hpp>
|
||||
#include <boost/smart_ptr/detail/shared_count.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_nullptr_t.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
#include <cstddef> // for std::ptrdiff_t
|
||||
@@ -55,59 +53,154 @@ public:
|
||||
|
||||
typedef T element_type;
|
||||
|
||||
explicit shared_array(T * p = 0): px(p), pn(p, deleter())
|
||||
shared_array() BOOST_NOEXCEPT : px( 0 ), pn()
|
||||
{
|
||||
}
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_NULLPTR )
|
||||
|
||||
shared_array( boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT : px( 0 ), pn()
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template<class Y>
|
||||
explicit shared_array( Y * p ): px( p ), pn( p, checked_array_deleter<Y>() )
|
||||
{
|
||||
boost::detail::sp_assert_convertible< Y[], T[] >();
|
||||
}
|
||||
|
||||
//
|
||||
// Requirements: D's copy constructor must not throw
|
||||
//
|
||||
// shared_array will release p by calling d(p)
|
||||
//
|
||||
|
||||
template<class D> shared_array(T * p, D d): px(p), pn(p, d)
|
||||
template<class Y, class D> shared_array( Y * p, D d ): px( p ), pn( p, d )
|
||||
{
|
||||
boost::detail::sp_assert_convertible< Y[], T[] >();
|
||||
}
|
||||
|
||||
// As above, but with allocator. A's copy constructor shall not throw.
|
||||
|
||||
template<class Y, class D, class A> shared_array( Y * p, D d, A a ): px( p ), pn( p, d, a )
|
||||
{
|
||||
boost::detail::sp_assert_convertible< Y[], T[] >();
|
||||
}
|
||||
|
||||
// generated copy constructor, destructor are fine...
|
||||
|
||||
#if defined( BOOST_HAS_RVALUE_REFS )
|
||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||
|
||||
// ... except in C++0x, move disables the implicit copy
|
||||
|
||||
shared_array( shared_array const & r ): px( r.px ), pn( r.pn ) // never throws
|
||||
shared_array( shared_array const & r ) BOOST_NOEXCEPT : px( r.px ), pn( r.pn )
|
||||
{
|
||||
}
|
||||
|
||||
shared_array( shared_array && r ) BOOST_NOEXCEPT : px( r.px ), pn()
|
||||
{
|
||||
pn.swap( r.pn );
|
||||
r.px = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// conversion
|
||||
|
||||
template<class Y>
|
||||
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
|
||||
|
||||
shared_array( shared_array<Y> const & r, typename boost::detail::sp_enable_if_convertible< Y[], T[] >::type = boost::detail::sp_empty() )
|
||||
|
||||
#else
|
||||
|
||||
shared_array( shared_array<Y> const & r )
|
||||
|
||||
#endif
|
||||
BOOST_NOEXCEPT : px( r.px ), pn( r.pn ) // never throws
|
||||
{
|
||||
boost::detail::sp_assert_convertible< Y[], T[] >();
|
||||
}
|
||||
|
||||
// aliasing
|
||||
|
||||
template< class Y >
|
||||
shared_array( shared_array<Y> const & r, element_type * p ) BOOST_NOEXCEPT : px( p ), pn( r.pn )
|
||||
{
|
||||
}
|
||||
|
||||
// assignment
|
||||
|
||||
shared_array & operator=( shared_array const & r ) // never throws
|
||||
shared_array & operator=( shared_array const & r ) BOOST_NOEXCEPT
|
||||
{
|
||||
this_type( r ).swap( *this );
|
||||
return *this;
|
||||
}
|
||||
|
||||
void reset(T * p = 0)
|
||||
#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1400)
|
||||
|
||||
template<class Y>
|
||||
shared_array & operator=( shared_array<Y> const & r ) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_ASSERT(p == 0 || p != px);
|
||||
this_type( r ).swap( *this );
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||
|
||||
shared_array & operator=( shared_array && r ) BOOST_NOEXCEPT
|
||||
{
|
||||
this_type( static_cast< shared_array && >( r ) ).swap( *this );
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class Y>
|
||||
shared_array & operator=( shared_array<Y> && r ) BOOST_NOEXCEPT
|
||||
{
|
||||
this_type( static_cast< shared_array<Y> && >( r ) ).swap( *this );
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void reset() BOOST_NOEXCEPT
|
||||
{
|
||||
this_type().swap( *this );
|
||||
}
|
||||
|
||||
template<class Y> void reset( Y * p ) // Y must be complete
|
||||
{
|
||||
BOOST_ASSERT( p == 0 || p != px ); // catch self-reset errors
|
||||
this_type( p ).swap( *this );
|
||||
}
|
||||
|
||||
template <class D> void reset(T * p, D d)
|
||||
template<class Y, class D> void reset( Y * p, D d )
|
||||
{
|
||||
this_type( p, d ).swap( *this );
|
||||
}
|
||||
|
||||
T & operator[] (std::ptrdiff_t i) const // never throws
|
||||
template<class Y, class D, class A> void reset( Y * p, D d, A a )
|
||||
{
|
||||
this_type( p, d, a ).swap( *this );
|
||||
}
|
||||
|
||||
template<class Y> void reset( shared_array<Y> const & r, element_type * p )
|
||||
{
|
||||
this_type( r, p ).swap( *this );
|
||||
}
|
||||
|
||||
T & operator[] (std::ptrdiff_t i) const // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT)
|
||||
{
|
||||
BOOST_ASSERT(px != 0);
|
||||
BOOST_ASSERT(i >= 0);
|
||||
return px[i];
|
||||
}
|
||||
|
||||
T * get() const // never throws
|
||||
T * get() const BOOST_NOEXCEPT
|
||||
{
|
||||
return px;
|
||||
}
|
||||
@@ -115,17 +208,17 @@ public:
|
||||
// implicit conversion to "bool"
|
||||
#include <boost/smart_ptr/detail/operator_bool.hpp>
|
||||
|
||||
bool unique() const // never throws
|
||||
bool unique() const BOOST_NOEXCEPT
|
||||
{
|
||||
return pn.unique();
|
||||
}
|
||||
|
||||
long use_count() const // never throws
|
||||
long use_count() const BOOST_NOEXCEPT
|
||||
{
|
||||
return pn.use_count();
|
||||
}
|
||||
|
||||
void swap(shared_array<T> & other) // never throws
|
||||
void swap(shared_array<T> & other) BOOST_NOEXCEPT
|
||||
{
|
||||
std::swap(px, other.px);
|
||||
pn.swap(other.pn);
|
||||
@@ -138,27 +231,53 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
template<class Y> friend class shared_array;
|
||||
|
||||
T * px; // contained pointer
|
||||
detail::shared_count pn; // reference counter
|
||||
|
||||
}; // shared_array
|
||||
|
||||
template<class T> inline bool operator==(shared_array<T> const & a, shared_array<T> const & b) // never throws
|
||||
template<class T> inline bool operator==(shared_array<T> const & a, shared_array<T> const & b) BOOST_NOEXCEPT
|
||||
{
|
||||
return a.get() == b.get();
|
||||
}
|
||||
|
||||
template<class T> inline bool operator!=(shared_array<T> const & a, shared_array<T> const & b) // never throws
|
||||
template<class T> inline bool operator!=(shared_array<T> const & a, shared_array<T> const & b) BOOST_NOEXCEPT
|
||||
{
|
||||
return a.get() != b.get();
|
||||
}
|
||||
|
||||
template<class T> inline bool operator<(shared_array<T> const & a, shared_array<T> const & b) // never throws
|
||||
#if !defined( BOOST_NO_CXX11_NULLPTR )
|
||||
|
||||
template<class T> inline bool operator==( shared_array<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
|
||||
{
|
||||
return p.get() == 0;
|
||||
}
|
||||
|
||||
template<class T> inline bool operator==( boost::detail::sp_nullptr_t, shared_array<T> const & p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return p.get() == 0;
|
||||
}
|
||||
|
||||
template<class T> inline bool operator!=( shared_array<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
|
||||
{
|
||||
return p.get() != 0;
|
||||
}
|
||||
|
||||
template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, shared_array<T> const & p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return p.get() != 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template<class T> inline bool operator<(shared_array<T> const & a, shared_array<T> const & b) BOOST_NOEXCEPT
|
||||
{
|
||||
return std::less<T*>()(a.get(), b.get());
|
||||
}
|
||||
|
||||
template<class T> void swap(shared_array<T> & a, shared_array<T> & b) // never throws
|
||||
template<class T> void swap(shared_array<T> & a, shared_array<T> & b) BOOST_NOEXCEPT
|
||||
{
|
||||
a.swap(b);
|
||||
}
|
||||
@@ -170,6 +289,4 @@ template< class D, class T > D * get_deleter( shared_array<T> const & p )
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_SHARED_ARRAY_HPP_INCLUDED
|
||||
|
@@ -16,10 +16,6 @@
|
||||
|
||||
#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
|
||||
// we make sure that our include of <memory> doesn't try to
|
||||
// pull in the TR1 headers: that's why we use this header
|
||||
@@ -32,10 +28,10 @@
|
||||
#include <boost/smart_ptr/detail/shared_count.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_convertible.hpp>
|
||||
#include <boost/smart_ptr/detail/sp_nullptr_t.hpp>
|
||||
|
||||
#if !defined(BOOST_SP_NO_ATOMIC_ACCESS)
|
||||
#include <boost/smart_ptr/detail/spinlock_pool.hpp>
|
||||
#include <boost/memory_order.hpp>
|
||||
#endif
|
||||
|
||||
#include <algorithm> // for std::swap
|
||||
@@ -57,45 +53,151 @@ namespace boost
|
||||
template<class T> class shared_ptr;
|
||||
template<class T> class weak_ptr;
|
||||
template<class T> class enable_shared_from_this;
|
||||
template<class T> class enable_shared_from_this2;
|
||||
class enable_shared_from_raw;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
struct static_cast_tag {};
|
||||
struct const_cast_tag {};
|
||||
struct dynamic_cast_tag {};
|
||||
struct polymorphic_cast_tag {};
|
||||
// sp_element, element_type
|
||||
|
||||
template<class T> struct shared_ptr_traits
|
||||
template< class T > struct sp_element
|
||||
{
|
||||
typedef T & reference;
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<> struct shared_ptr_traits<void>
|
||||
#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
|
||||
|
||||
template< class T > struct sp_element< T[] >
|
||||
{
|
||||
typedef void reference;
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
#if !defined( __BORLANDC__ ) || !BOOST_WORKAROUND( __BORLANDC__, < 0x600 )
|
||||
|
||||
template< class T, std::size_t N > struct sp_element< T[N] >
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
|
||||
|
||||
// sp_dereference, return type of operator*
|
||||
|
||||
template< class T > struct sp_dereference
|
||||
{
|
||||
typedef T & type;
|
||||
};
|
||||
|
||||
template<> struct sp_dereference< void >
|
||||
{
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
#if !defined(BOOST_NO_CV_VOID_SPECIALIZATIONS)
|
||||
|
||||
template<> struct shared_ptr_traits<void const>
|
||||
template<> struct sp_dereference< void const >
|
||||
{
|
||||
typedef void reference;
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
template<> struct shared_ptr_traits<void volatile>
|
||||
template<> struct sp_dereference< void volatile >
|
||||
{
|
||||
typedef void reference;
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
template<> struct shared_ptr_traits<void const volatile>
|
||||
template<> struct sp_dereference< void const volatile >
|
||||
{
|
||||
typedef void reference;
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
#endif // !defined(BOOST_NO_CV_VOID_SPECIALIZATIONS)
|
||||
|
||||
#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
|
||||
|
||||
template< class T > struct sp_dereference< T[] >
|
||||
{
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
#if !defined( __BORLANDC__ ) || !BOOST_WORKAROUND( __BORLANDC__, < 0x600 )
|
||||
|
||||
template< class T, std::size_t N > struct sp_dereference< T[N] >
|
||||
{
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
|
||||
|
||||
// sp_member_access, return type of operator->
|
||||
|
||||
template< class T > struct sp_member_access
|
||||
{
|
||||
typedef T * type;
|
||||
};
|
||||
|
||||
#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
|
||||
|
||||
template< class T > struct sp_member_access< T[] >
|
||||
{
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
#if !defined( __BORLANDC__ ) || !BOOST_WORKAROUND( __BORLANDC__, < 0x600 )
|
||||
|
||||
template< class T, std::size_t N > struct sp_member_access< T[N] >
|
||||
{
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
|
||||
|
||||
// sp_array_access, return type of operator[]
|
||||
|
||||
template< class T > struct sp_array_access
|
||||
{
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
|
||||
|
||||
template< class T > struct sp_array_access< T[] >
|
||||
{
|
||||
typedef T & type;
|
||||
};
|
||||
|
||||
#if !defined( __BORLANDC__ ) || !BOOST_WORKAROUND( __BORLANDC__, < 0x600 )
|
||||
|
||||
template< class T, std::size_t N > struct sp_array_access< T[N] >
|
||||
{
|
||||
typedef T & type;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
|
||||
|
||||
// sp_extent, for operator[] index check
|
||||
|
||||
template< class T > struct sp_extent
|
||||
{
|
||||
enum _vt { value = 0 };
|
||||
};
|
||||
|
||||
#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
|
||||
|
||||
template< class T, std::size_t N > struct sp_extent< T[N] >
|
||||
{
|
||||
enum _vt { value = N };
|
||||
};
|
||||
|
||||
#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
|
||||
|
||||
// enable_shared_from_this support
|
||||
|
||||
template< class X, class Y, class T > inline void sp_enable_shared_from_this( boost::shared_ptr<X> const * ppx, Y const * py, boost::enable_shared_from_this< T > const * pe )
|
||||
@@ -106,13 +208,7 @@ template< class X, class Y, class T > inline void sp_enable_shared_from_this( bo
|
||||
}
|
||||
}
|
||||
|
||||
template< class X, class Y, class T > inline void sp_enable_shared_from_this( boost::shared_ptr<X> * ppx, Y const * py, boost::enable_shared_from_this2< T > const * pe )
|
||||
{
|
||||
if( pe != 0 )
|
||||
{
|
||||
pe->_internal_accept_owner( ppx, const_cast< Y* >( py ) );
|
||||
}
|
||||
}
|
||||
template< class X, class Y > inline void sp_enable_shared_from_this( boost::shared_ptr<X> * ppx, Y const * py, boost::enable_shared_from_raw const * pe );
|
||||
|
||||
#ifdef _MANAGED
|
||||
|
||||
@@ -150,6 +246,69 @@ template< class T, class R > struct sp_enable_if_auto_ptr< std::auto_ptr< T >, R
|
||||
|
||||
#endif
|
||||
|
||||
// sp_assert_convertible
|
||||
|
||||
template< class Y, class T > inline void sp_assert_convertible()
|
||||
{
|
||||
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
|
||||
|
||||
// static_assert( sp_convertible< Y, T >::value );
|
||||
typedef char tmp[ sp_convertible< Y, T >::value? 1: -1 ];
|
||||
(void)sizeof( tmp );
|
||||
|
||||
#else
|
||||
|
||||
T* p = static_cast< Y* >( 0 );
|
||||
(void)p;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
// pointer constructor helper
|
||||
|
||||
template< class T, class Y > inline void sp_pointer_construct( boost::shared_ptr< T > * ppx, Y * p, boost::detail::shared_count & pn )
|
||||
{
|
||||
boost::detail::shared_count( p ).swap( pn );
|
||||
boost::detail::sp_enable_shared_from_this( ppx, p, p );
|
||||
}
|
||||
|
||||
#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
|
||||
|
||||
template< class T, class Y > inline void sp_pointer_construct( boost::shared_ptr< T[] > * /*ppx*/, Y * p, boost::detail::shared_count & pn )
|
||||
{
|
||||
sp_assert_convertible< Y[], T[] >();
|
||||
boost::detail::shared_count( p, boost::checked_array_deleter< T >() ).swap( pn );
|
||||
}
|
||||
|
||||
template< class T, std::size_t N, class Y > inline void sp_pointer_construct( boost::shared_ptr< T[N] > * /*ppx*/, Y * p, boost::detail::shared_count & pn )
|
||||
{
|
||||
sp_assert_convertible< Y[N], T[N] >();
|
||||
boost::detail::shared_count( p, boost::checked_array_deleter< T >() ).swap( pn );
|
||||
}
|
||||
|
||||
#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
|
||||
|
||||
// deleter constructor helper
|
||||
|
||||
template< class T, class Y > inline void sp_deleter_construct( boost::shared_ptr< T > * ppx, Y * p )
|
||||
{
|
||||
boost::detail::sp_enable_shared_from_this( ppx, p, p );
|
||||
}
|
||||
|
||||
#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
|
||||
|
||||
template< class T, class Y > inline void sp_deleter_construct( boost::shared_ptr< T[] > * /*ppx*/, Y * /*p*/ )
|
||||
{
|
||||
sp_assert_convertible< Y[], T[] >();
|
||||
}
|
||||
|
||||
template< class T, std::size_t N, class Y > inline void sp_deleter_construct( boost::shared_ptr< T[N] > * /*ppx*/, Y * /*p*/ )
|
||||
{
|
||||
sp_assert_convertible< Y[N], T[N] >();
|
||||
}
|
||||
|
||||
#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
@@ -170,19 +329,24 @@ private:
|
||||
|
||||
public:
|
||||
|
||||
typedef T element_type;
|
||||
typedef T value_type;
|
||||
typedef T * pointer;
|
||||
typedef typename boost::detail::shared_ptr_traits<T>::reference reference;
|
||||
typedef typename boost::detail::sp_element< T >::type element_type;
|
||||
|
||||
shared_ptr(): px(0), pn() // never throws in 1.30+
|
||||
shared_ptr() BOOST_NOEXCEPT : px( 0 ), pn() // never throws in 1.30+
|
||||
{
|
||||
}
|
||||
|
||||
template<class Y>
|
||||
explicit shared_ptr( Y * p ): px( p ), pn( p ) // Y must be complete
|
||||
#if !defined( BOOST_NO_CXX11_NULLPTR )
|
||||
|
||||
shared_ptr( boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT : px( 0 ), pn() // never throws
|
||||
{
|
||||
boost::detail::sp_enable_shared_from_this( this, p, p );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template<class Y>
|
||||
explicit shared_ptr( Y * p ): px( p ), pn() // Y must be complete
|
||||
{
|
||||
boost::detail::sp_pointer_construct( this, p, pn );
|
||||
}
|
||||
|
||||
//
|
||||
@@ -193,23 +357,39 @@ public:
|
||||
|
||||
template<class Y, class D> shared_ptr( Y * p, D d ): px( p ), pn( p, d )
|
||||
{
|
||||
boost::detail::sp_enable_shared_from_this( this, p, p );
|
||||
boost::detail::sp_deleter_construct( this, p );
|
||||
}
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_NULLPTR )
|
||||
|
||||
template<class D> shared_ptr( boost::detail::sp_nullptr_t p, D d ): px( p ), pn( p, d )
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// As above, but with allocator. A's copy constructor shall not throw.
|
||||
|
||||
template<class Y, class D, class A> shared_ptr( Y * p, D d, A a ): px( p ), pn( p, d, a )
|
||||
{
|
||||
boost::detail::sp_enable_shared_from_this( this, p, p );
|
||||
boost::detail::sp_deleter_construct( this, p );
|
||||
}
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_NULLPTR )
|
||||
|
||||
template<class D, class A> shared_ptr( boost::detail::sp_nullptr_t p, D d, A a ): px( p ), pn( p, d, a )
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// generated copy constructor, destructor are fine...
|
||||
|
||||
#if defined( BOOST_HAS_RVALUE_REFS )
|
||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||
|
||||
// ... except in C++0x, move disables the implicit copy
|
||||
|
||||
shared_ptr( shared_ptr const & r ): px( r.px ), pn( r.pn ) // never throws
|
||||
shared_ptr( shared_ptr const & r ) BOOST_NOEXCEPT : px( r.px ), pn( r.pn )
|
||||
{
|
||||
}
|
||||
|
||||
@@ -218,12 +398,15 @@ public:
|
||||
template<class Y>
|
||||
explicit shared_ptr( weak_ptr<Y> const & r ): pn( r.pn ) // may throw
|
||||
{
|
||||
boost::detail::sp_assert_convertible< Y, T >();
|
||||
|
||||
// it is now safe to copy r.px, as pn(r.pn) did not throw
|
||||
px = r.px;
|
||||
}
|
||||
|
||||
template<class Y>
|
||||
shared_ptr( weak_ptr<Y> const & r, boost::detail::sp_nothrow_tag ): px( 0 ), pn( r.pn, boost::detail::sp_nothrow_tag() ) // never throws
|
||||
shared_ptr( weak_ptr<Y> const & r, boost::detail::sp_nothrow_tag )
|
||||
BOOST_NOEXCEPT : px( 0 ), pn( r.pn, boost::detail::sp_nothrow_tag() )
|
||||
{
|
||||
if( !pn.empty() )
|
||||
{
|
||||
@@ -241,72 +424,80 @@ public:
|
||||
shared_ptr( shared_ptr<Y> const & r )
|
||||
|
||||
#endif
|
||||
: px( r.px ), pn( r.pn ) // never throws
|
||||
BOOST_NOEXCEPT : px( r.px ), pn( r.pn )
|
||||
{
|
||||
boost::detail::sp_assert_convertible< Y, T >();
|
||||
}
|
||||
|
||||
// aliasing
|
||||
template< class Y >
|
||||
shared_ptr( shared_ptr<Y> const & r, T * p ): px( p ), pn( r.pn ) // never throws
|
||||
shared_ptr( shared_ptr<Y> const & r, element_type * p ) BOOST_NOEXCEPT : px( p ), pn( r.pn )
|
||||
{
|
||||
}
|
||||
|
||||
template<class Y>
|
||||
shared_ptr(shared_ptr<Y> const & r, boost::detail::static_cast_tag): px(static_cast<element_type *>(r.px)), pn(r.pn)
|
||||
{
|
||||
}
|
||||
|
||||
template<class Y>
|
||||
shared_ptr(shared_ptr<Y> const & r, boost::detail::const_cast_tag): px(const_cast<element_type *>(r.px)), pn(r.pn)
|
||||
{
|
||||
}
|
||||
|
||||
template<class Y>
|
||||
shared_ptr(shared_ptr<Y> const & r, boost::detail::dynamic_cast_tag): px(dynamic_cast<element_type *>(r.px)), pn(r.pn)
|
||||
{
|
||||
if(px == 0) // need to allocate new counter -- the cast failed
|
||||
{
|
||||
pn = boost::detail::shared_count();
|
||||
}
|
||||
}
|
||||
|
||||
template<class Y>
|
||||
shared_ptr(shared_ptr<Y> const & r, boost::detail::polymorphic_cast_tag): px(dynamic_cast<element_type *>(r.px)), pn(r.pn)
|
||||
{
|
||||
if(px == 0)
|
||||
{
|
||||
boost::throw_exception(std::bad_cast());
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_AUTO_PTR
|
||||
|
||||
template<class Y>
|
||||
explicit shared_ptr( std::auto_ptr<Y> & r ): px(r.get()), pn()
|
||||
{
|
||||
boost::detail::sp_assert_convertible< Y, T >();
|
||||
|
||||
Y * tmp = r.get();
|
||||
pn = boost::detail::shared_count( r );
|
||||
boost::detail::sp_enable_shared_from_this( this, tmp, tmp );
|
||||
|
||||
boost::detail::sp_deleter_construct( this, tmp );
|
||||
}
|
||||
|
||||
#if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
|
||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||
|
||||
template<class Y>
|
||||
shared_ptr( std::auto_ptr<Y> && r ): px(r.get()), pn()
|
||||
{
|
||||
boost::detail::sp_assert_convertible< Y, T >();
|
||||
|
||||
Y * tmp = r.get();
|
||||
pn = boost::detail::shared_count( r );
|
||||
|
||||
boost::detail::sp_deleter_construct( this, tmp );
|
||||
}
|
||||
|
||||
#elif !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
|
||||
|
||||
template<class Ap>
|
||||
explicit shared_ptr( Ap r, typename boost::detail::sp_enable_if_auto_ptr<Ap, int>::type = 0 ): px( r.get() ), pn()
|
||||
{
|
||||
typename Ap::element_type * tmp = r.get();
|
||||
pn = boost::detail::shared_count( r );
|
||||
boost::detail::sp_enable_shared_from_this( this, tmp, tmp );
|
||||
}
|
||||
typedef typename Ap::element_type Y;
|
||||
|
||||
boost::detail::sp_assert_convertible< Y, T >();
|
||||
|
||||
Y * tmp = r.get();
|
||||
pn = boost::detail::shared_count( r );
|
||||
|
||||
boost::detail::sp_deleter_construct( this, tmp );
|
||||
}
|
||||
|
||||
#endif // BOOST_NO_SFINAE, BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
#endif // BOOST_NO_AUTO_PTR
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_SMART_PTR ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||
|
||||
template< class Y, class D >
|
||||
shared_ptr( std::unique_ptr< Y, D > && r ): px( r.get() ), pn()
|
||||
{
|
||||
boost::detail::sp_assert_convertible< Y, T >();
|
||||
|
||||
typename std::unique_ptr< Y, D >::pointer tmp = r.get();
|
||||
pn = boost::detail::shared_count( r );
|
||||
|
||||
boost::detail::sp_deleter_construct( this, tmp );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// assignment
|
||||
|
||||
shared_ptr & operator=( shared_ptr const & r ) // never throws
|
||||
shared_ptr & operator=( shared_ptr const & r ) BOOST_NOEXCEPT
|
||||
{
|
||||
this_type(r).swap(*this);
|
||||
return *this;
|
||||
@@ -315,7 +506,7 @@ public:
|
||||
#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1400)
|
||||
|
||||
template<class Y>
|
||||
shared_ptr & operator=(shared_ptr<Y> const & r) // never throws
|
||||
shared_ptr & operator=(shared_ptr<Y> const & r) BOOST_NOEXCEPT
|
||||
{
|
||||
this_type(r).swap(*this);
|
||||
return *this;
|
||||
@@ -332,7 +523,16 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
|
||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||
|
||||
template<class Y>
|
||||
shared_ptr & operator=( std::auto_ptr<Y> && r )
|
||||
{
|
||||
this_type( static_cast< std::auto_ptr<Y> && >( r ) ).swap( *this );
|
||||
return *this;
|
||||
}
|
||||
|
||||
#elif !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
|
||||
|
||||
template<class Ap>
|
||||
typename boost::detail::sp_enable_if_auto_ptr< Ap, shared_ptr & >::type operator=( Ap r )
|
||||
@@ -341,16 +541,26 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
#endif // BOOST_NO_SFINAE, BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
#endif // BOOST_NO_AUTO_PTR
|
||||
|
||||
#if !defined( BOOST_NO_CXX11_SMART_PTR ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||
|
||||
template<class Y, class D>
|
||||
shared_ptr & operator=( std::unique_ptr<Y, D> && r )
|
||||
{
|
||||
this_type( static_cast< std::unique_ptr<Y, D> && >( r ) ).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// Move support
|
||||
|
||||
#if defined( BOOST_HAS_RVALUE_REFS )
|
||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||
|
||||
shared_ptr( shared_ptr && r ): px( r.px ), pn() // never throws
|
||||
shared_ptr( shared_ptr && r ) BOOST_NOEXCEPT : px( r.px ), pn()
|
||||
{
|
||||
pn.swap( r.pn );
|
||||
r.px = 0;
|
||||
@@ -366,20 +576,22 @@ public:
|
||||
shared_ptr( shared_ptr<Y> && r )
|
||||
|
||||
#endif
|
||||
: px( r.px ), pn() // never throws
|
||||
BOOST_NOEXCEPT : px( r.px ), pn()
|
||||
{
|
||||
boost::detail::sp_assert_convertible< Y, T >();
|
||||
|
||||
pn.swap( r.pn );
|
||||
r.px = 0;
|
||||
}
|
||||
|
||||
shared_ptr & operator=( shared_ptr && r ) // never throws
|
||||
shared_ptr & operator=( shared_ptr && r ) BOOST_NOEXCEPT
|
||||
{
|
||||
this_type( static_cast< shared_ptr && >( r ) ).swap( *this );
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class Y>
|
||||
shared_ptr & operator=( shared_ptr<Y> && r ) // never throws
|
||||
shared_ptr & operator=( shared_ptr<Y> && r ) BOOST_NOEXCEPT
|
||||
{
|
||||
this_type( static_cast< shared_ptr<Y> && >( r ) ).swap( *this );
|
||||
return *this;
|
||||
@@ -387,7 +599,17 @@ public:
|
||||
|
||||
#endif
|
||||
|
||||
void reset() // never throws in 1.30+
|
||||
#if !defined( BOOST_NO_CXX11_NULLPTR )
|
||||
|
||||
shared_ptr & operator=( boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT // never throws
|
||||
{
|
||||
this_type().swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void reset() BOOST_NOEXCEPT // never throws in 1.30+
|
||||
{
|
||||
this_type().swap(*this);
|
||||
}
|
||||
@@ -408,24 +630,35 @@ public:
|
||||
this_type( p, d, a ).swap( *this );
|
||||
}
|
||||
|
||||
template<class Y> void reset( shared_ptr<Y> const & r, T * p )
|
||||
template<class Y> void reset( shared_ptr<Y> const & r, element_type * p )
|
||||
{
|
||||
this_type( r, p ).swap( *this );
|
||||
}
|
||||
|
||||
reference operator* () const // never throws
|
||||
// never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT)
|
||||
typename boost::detail::sp_dereference< T >::type operator* () const
|
||||
{
|
||||
BOOST_ASSERT( px != 0 );
|
||||
return *px;
|
||||
}
|
||||
|
||||
T * operator-> () const // never throws
|
||||
// never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT)
|
||||
typename boost::detail::sp_member_access< T >::type operator-> () const
|
||||
{
|
||||
BOOST_ASSERT( px != 0 );
|
||||
return px;
|
||||
}
|
||||
|
||||
T * get() const // never throws
|
||||
// never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT)
|
||||
typename boost::detail::sp_array_access< T >::type operator[] ( std::ptrdiff_t i ) const
|
||||
{
|
||||
BOOST_ASSERT( px != 0 );
|
||||
BOOST_ASSERT( i >= 0 && ( i < boost::detail::sp_extent< T >::value || boost::detail::sp_extent< T >::value == 0 ) );
|
||||
|
||||
return px[ i ];
|
||||
}
|
||||
|
||||
element_type * get() const BOOST_NOEXCEPT
|
||||
{
|
||||
return px;
|
||||
}
|
||||
@@ -433,38 +666,43 @@ public:
|
||||
// implicit conversion to "bool"
|
||||
#include <boost/smart_ptr/detail/operator_bool.hpp>
|
||||
|
||||
bool unique() const // never throws
|
||||
bool unique() const BOOST_NOEXCEPT
|
||||
{
|
||||
return pn.unique();
|
||||
}
|
||||
|
||||
long use_count() const // never throws
|
||||
long use_count() const BOOST_NOEXCEPT
|
||||
{
|
||||
return pn.use_count();
|
||||
}
|
||||
|
||||
void swap(shared_ptr<T> & other) // never throws
|
||||
void swap( shared_ptr & other ) BOOST_NOEXCEPT
|
||||
{
|
||||
std::swap(px, other.px);
|
||||
pn.swap(other.pn);
|
||||
}
|
||||
|
||||
template<class Y> bool owner_before( shared_ptr<Y> const & rhs ) const
|
||||
template<class Y> bool owner_before( shared_ptr<Y> const & rhs ) const BOOST_NOEXCEPT
|
||||
{
|
||||
return pn < rhs.pn;
|
||||
}
|
||||
|
||||
template<class Y> bool owner_before( weak_ptr<Y> const & rhs ) const
|
||||
template<class Y> bool owner_before( weak_ptr<Y> const & rhs ) const BOOST_NOEXCEPT
|
||||
{
|
||||
return pn < rhs.pn;
|
||||
}
|
||||
|
||||
void * _internal_get_deleter( boost::detail::sp_typeinfo const & ti ) const
|
||||
void * _internal_get_deleter( boost::detail::sp_typeinfo const & ti ) const BOOST_NOEXCEPT
|
||||
{
|
||||
return pn.get_deleter( ti );
|
||||
}
|
||||
|
||||
bool _internal_equiv( shared_ptr const & r ) const
|
||||
void * _internal_get_untyped_deleter() const BOOST_NOEXCEPT
|
||||
{
|
||||
return pn.get_untyped_deleter();
|
||||
}
|
||||
|
||||
bool _internal_equiv( shared_ptr const & r ) const BOOST_NOEXCEPT
|
||||
{
|
||||
return px == r.px && pn == r.pn;
|
||||
}
|
||||
@@ -482,17 +720,17 @@ private:
|
||||
|
||||
#endif
|
||||
|
||||
T * px; // contained pointer
|
||||
element_type * px; // contained pointer
|
||||
boost::detail::shared_count pn; // reference counter
|
||||
|
||||
}; // shared_ptr
|
||||
|
||||
template<class T, class U> inline bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b)
|
||||
template<class T, class U> inline bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b) BOOST_NOEXCEPT
|
||||
{
|
||||
return a.get() == b.get();
|
||||
}
|
||||
|
||||
template<class T, class U> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b)
|
||||
template<class T, class U> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b) BOOST_NOEXCEPT
|
||||
{
|
||||
return a.get() != b.get();
|
||||
}
|
||||
@@ -501,64 +739,90 @@ template<class T, class U> inline bool operator!=(shared_ptr<T> const & a, share
|
||||
|
||||
// Resolve the ambiguity between our op!= and the one in rel_ops
|
||||
|
||||
template<class T> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<T> const & b)
|
||||
template<class T> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<T> const & b) BOOST_NOEXCEPT
|
||||
{
|
||||
return a.get() != b.get();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template<class T, class U> inline bool operator<(shared_ptr<T> const & a, shared_ptr<U> const & b)
|
||||
#if !defined( BOOST_NO_CXX11_NULLPTR )
|
||||
|
||||
template<class T> inline bool operator==( shared_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
|
||||
{
|
||||
return p.get() == 0;
|
||||
}
|
||||
|
||||
template<class T> inline bool operator==( boost::detail::sp_nullptr_t, shared_ptr<T> const & p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return p.get() == 0;
|
||||
}
|
||||
|
||||
template<class T> inline bool operator!=( shared_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
|
||||
{
|
||||
return p.get() != 0;
|
||||
}
|
||||
|
||||
template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, shared_ptr<T> const & p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return p.get() != 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template<class T, class U> inline bool operator<(shared_ptr<T> const & a, shared_ptr<U> const & b) BOOST_NOEXCEPT
|
||||
{
|
||||
return a.owner_before( b );
|
||||
}
|
||||
|
||||
template<class T> inline void swap(shared_ptr<T> & a, shared_ptr<T> & b)
|
||||
template<class T> inline void swap(shared_ptr<T> & a, shared_ptr<T> & b) BOOST_NOEXCEPT
|
||||
{
|
||||
a.swap(b);
|
||||
}
|
||||
|
||||
template<class T, class U> shared_ptr<T> static_pointer_cast(shared_ptr<U> const & r)
|
||||
template<class T, class U> shared_ptr<T> static_pointer_cast( shared_ptr<U> const & r ) BOOST_NOEXCEPT
|
||||
{
|
||||
return shared_ptr<T>(r, boost::detail::static_cast_tag());
|
||||
(void) static_cast< T* >( static_cast< U* >( 0 ) );
|
||||
|
||||
typedef typename shared_ptr<T>::element_type E;
|
||||
|
||||
E * p = static_cast< E* >( r.get() );
|
||||
return shared_ptr<T>( r, p );
|
||||
}
|
||||
|
||||
template<class T, class U> shared_ptr<T> const_pointer_cast(shared_ptr<U> const & r)
|
||||
template<class T, class U> shared_ptr<T> const_pointer_cast( shared_ptr<U> const & r ) BOOST_NOEXCEPT
|
||||
{
|
||||
return shared_ptr<T>(r, boost::detail::const_cast_tag());
|
||||
(void) const_cast< T* >( static_cast< U* >( 0 ) );
|
||||
|
||||
typedef typename shared_ptr<T>::element_type E;
|
||||
|
||||
E * p = const_cast< E* >( r.get() );
|
||||
return shared_ptr<T>( r, p );
|
||||
}
|
||||
|
||||
template<class T, class U> shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const & r)
|
||||
template<class T, class U> shared_ptr<T> dynamic_pointer_cast( shared_ptr<U> const & r ) BOOST_NOEXCEPT
|
||||
{
|
||||
return shared_ptr<T>(r, boost::detail::dynamic_cast_tag());
|
||||
(void) dynamic_cast< T* >( static_cast< U* >( 0 ) );
|
||||
|
||||
typedef typename shared_ptr<T>::element_type E;
|
||||
|
||||
E * p = dynamic_cast< E* >( r.get() );
|
||||
return p? shared_ptr<T>( r, p ): shared_ptr<T>();
|
||||
}
|
||||
|
||||
// shared_*_cast names are deprecated. Use *_pointer_cast instead.
|
||||
|
||||
template<class T, class U> shared_ptr<T> shared_static_cast(shared_ptr<U> const & r)
|
||||
template<class T, class U> shared_ptr<T> reinterpret_pointer_cast( shared_ptr<U> const & r ) BOOST_NOEXCEPT
|
||||
{
|
||||
return shared_ptr<T>(r, boost::detail::static_cast_tag());
|
||||
}
|
||||
(void) reinterpret_cast< T* >( static_cast< U* >( 0 ) );
|
||||
|
||||
template<class T, class U> shared_ptr<T> shared_dynamic_cast(shared_ptr<U> const & r)
|
||||
{
|
||||
return shared_ptr<T>(r, boost::detail::dynamic_cast_tag());
|
||||
}
|
||||
typedef typename shared_ptr<T>::element_type E;
|
||||
|
||||
template<class T, class U> shared_ptr<T> shared_polymorphic_cast(shared_ptr<U> const & r)
|
||||
{
|
||||
return shared_ptr<T>(r, boost::detail::polymorphic_cast_tag());
|
||||
}
|
||||
|
||||
template<class T, class U> shared_ptr<T> shared_polymorphic_downcast(shared_ptr<U> const & r)
|
||||
{
|
||||
BOOST_ASSERT(dynamic_cast<T *>(r.get()) == r.get());
|
||||
return shared_static_cast<T>(r);
|
||||
E * p = reinterpret_cast< E* >( r.get() );
|
||||
return shared_ptr<T>( r, p );
|
||||
}
|
||||
|
||||
// get_pointer() enables boost::mem_fn to recognize shared_ptr
|
||||
|
||||
template<class T> inline T * get_pointer(shared_ptr<T> const & p)
|
||||
template<class T> inline typename shared_ptr<T>::element_type * get_pointer(shared_ptr<T> const & p) BOOST_NOEXCEPT
|
||||
{
|
||||
return p.get();
|
||||
}
|
||||
@@ -600,6 +864,9 @@ template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::
|
||||
|
||||
// get_deleter
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
#if ( defined(__GNUC__) && BOOST_WORKAROUND(__GNUC__, < 3) ) || \
|
||||
( defined(__EDG_VERSION__) && BOOST_WORKAROUND(__EDG_VERSION__, <= 238) ) || \
|
||||
( defined(__HP_aCC) && BOOST_WORKAROUND(__HP_aCC, <= 33500) )
|
||||
@@ -607,7 +874,7 @@ template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::
|
||||
// g++ 2.9x doesn't allow static_cast<X const *>(void *)
|
||||
// apparently EDG 2.38 and HP aCC A.03.35 also don't accept it
|
||||
|
||||
template<class D, class T> D * get_deleter(shared_ptr<T> const & p)
|
||||
template<class D, class T> D * basic_get_deleter(shared_ptr<T> const & p)
|
||||
{
|
||||
void const * q = p._internal_get_deleter(BOOST_SP_TYPEID(D));
|
||||
return const_cast<D *>(static_cast<D const *>(q));
|
||||
@@ -615,18 +882,64 @@ template<class D, class T> D * get_deleter(shared_ptr<T> const & p)
|
||||
|
||||
#else
|
||||
|
||||
template<class D, class T> D * get_deleter(shared_ptr<T> const & p)
|
||||
template<class D, class T> D * basic_get_deleter( shared_ptr<T> const & p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return static_cast<D *>( p._internal_get_deleter(BOOST_SP_TYPEID(D)) );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
class esft2_deleter_wrapper
|
||||
{
|
||||
private:
|
||||
|
||||
shared_ptr<void> deleter_;
|
||||
|
||||
public:
|
||||
|
||||
esft2_deleter_wrapper()
|
||||
{
|
||||
}
|
||||
|
||||
template< class T > void set_deleter( shared_ptr<T> const & deleter )
|
||||
{
|
||||
deleter_ = deleter;
|
||||
}
|
||||
|
||||
template<typename D> D* get_deleter() const BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::detail::basic_get_deleter<D>( deleter_ );
|
||||
}
|
||||
|
||||
template< class T> void operator()( T* )
|
||||
{
|
||||
BOOST_ASSERT( deleter_.use_count() <= 1 );
|
||||
deleter_.reset();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class D, class T> D * get_deleter( shared_ptr<T> const & p ) BOOST_NOEXCEPT
|
||||
{
|
||||
D *del = boost::detail::basic_get_deleter<D>(p);
|
||||
|
||||
if(del == 0)
|
||||
{
|
||||
boost::detail::esft2_deleter_wrapper *del_wrapper = boost::detail::basic_get_deleter<boost::detail::esft2_deleter_wrapper>(p);
|
||||
// The following get_deleter method call is fully qualified because
|
||||
// older versions of gcc (2.95, 3.2.3) fail to compile it when written del_wrapper->get_deleter<D>()
|
||||
if(del_wrapper) del = del_wrapper->::boost::detail::esft2_deleter_wrapper::get_deleter<D>();
|
||||
}
|
||||
|
||||
return del;
|
||||
}
|
||||
|
||||
// atomic access
|
||||
|
||||
#if !defined(BOOST_SP_NO_ATOMIC_ACCESS)
|
||||
|
||||
template<class T> inline bool atomic_is_lock_free( shared_ptr<T> const * /*p*/ )
|
||||
template<class T> inline bool atomic_is_lock_free( shared_ptr<T> const * /*p*/ ) BOOST_NOEXCEPT
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -637,7 +950,7 @@ template<class T> shared_ptr<T> atomic_load( shared_ptr<T> const * p )
|
||||
return *p;
|
||||
}
|
||||
|
||||
template<class T> inline shared_ptr<T> atomic_load_explicit( shared_ptr<T> const * p, memory_order /*mo*/ )
|
||||
template<class T> inline shared_ptr<T> atomic_load_explicit( shared_ptr<T> const * p, /*memory_order mo*/ int )
|
||||
{
|
||||
return atomic_load( p );
|
||||
}
|
||||
@@ -648,7 +961,7 @@ template<class T> void atomic_store( shared_ptr<T> * p, shared_ptr<T> r )
|
||||
p->swap( r );
|
||||
}
|
||||
|
||||
template<class T> inline void atomic_store_explicit( shared_ptr<T> * p, shared_ptr<T> r, memory_order /*mo*/ )
|
||||
template<class T> inline void atomic_store_explicit( shared_ptr<T> * p, shared_ptr<T> r, /*memory_order mo*/ int )
|
||||
{
|
||||
atomic_store( p, r ); // std::move( r )
|
||||
}
|
||||
@@ -664,7 +977,7 @@ template<class T> shared_ptr<T> atomic_exchange( shared_ptr<T> * p, shared_ptr<T
|
||||
return r; // return std::move( r )
|
||||
}
|
||||
|
||||
template<class T> shared_ptr<T> atomic_exchange_explicit( shared_ptr<T> * p, shared_ptr<T> r, memory_order /*mo*/ )
|
||||
template<class T> shared_ptr<T> atomic_exchange_explicit( shared_ptr<T> * p, shared_ptr<T> r, /*memory_order mo*/ int )
|
||||
{
|
||||
return atomic_exchange( p, r ); // std::move( r )
|
||||
}
|
||||
@@ -694,7 +1007,7 @@ template<class T> bool atomic_compare_exchange( shared_ptr<T> * p, shared_ptr<T>
|
||||
}
|
||||
}
|
||||
|
||||
template<class T> inline bool atomic_compare_exchange_explicit( shared_ptr<T> * p, shared_ptr<T> * v, shared_ptr<T> w, memory_order /*success*/, memory_order /*failure*/ )
|
||||
template<class T> inline bool atomic_compare_exchange_explicit( shared_ptr<T> * p, shared_ptr<T> * v, shared_ptr<T> w, /*memory_order success*/ int, /*memory_order failure*/ int )
|
||||
{
|
||||
return atomic_compare_exchange( p, v, w ); // std::move( w )
|
||||
}
|
||||
@@ -705,13 +1018,11 @@ template<class T> inline bool atomic_compare_exchange_explicit( shared_ptr<T> *
|
||||
|
||||
template< class T > struct hash;
|
||||
|
||||
template< class T > std::size_t hash_value( boost::shared_ptr<T> const & p )
|
||||
template< class T > std::size_t hash_value( boost::shared_ptr<T> const & p ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::hash< T* >()( p.get() );
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
|
||||
|
||||
#endif // #ifndef BOOST_SMART_PTR_SHARED_PTR_HPP_INCLUDED
|
||||
|
@@ -29,23 +29,23 @@ private:
|
||||
|
||||
public:
|
||||
|
||||
typedef T element_type;
|
||||
typedef typename boost::detail::sp_element< T >::type element_type;
|
||||
|
||||
weak_ptr(): px(0), pn() // never throws in 1.30+
|
||||
weak_ptr() BOOST_NOEXCEPT : px(0), pn() // never throws in 1.30+
|
||||
{
|
||||
}
|
||||
|
||||
// generated copy constructor, assignment, destructor are fine...
|
||||
|
||||
#if defined( BOOST_HAS_RVALUE_REFS )
|
||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||
|
||||
// ... except in C++0x, move disables the implicit copy
|
||||
|
||||
weak_ptr( weak_ptr const & r ): px( r.px ), pn( r.pn ) // never throws
|
||||
weak_ptr( weak_ptr const & r ) BOOST_NOEXCEPT : px( r.px ), pn( r.pn )
|
||||
{
|
||||
}
|
||||
|
||||
weak_ptr & operator=( weak_ptr const & r ) // never throws
|
||||
weak_ptr & operator=( weak_ptr const & r ) BOOST_NOEXCEPT
|
||||
{
|
||||
px = r.px;
|
||||
pn = r.pn;
|
||||
@@ -81,11 +81,12 @@ public:
|
||||
weak_ptr( weak_ptr<Y> const & r )
|
||||
|
||||
#endif
|
||||
: px(r.lock().get()), pn(r.pn) // never throws
|
||||
BOOST_NOEXCEPT : px(r.lock().get()), pn(r.pn)
|
||||
{
|
||||
boost::detail::sp_assert_convertible< Y, T >();
|
||||
}
|
||||
|
||||
#if defined( BOOST_HAS_RVALUE_REFS )
|
||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||
|
||||
template<class Y>
|
||||
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
|
||||
@@ -97,19 +98,21 @@ public:
|
||||
weak_ptr( weak_ptr<Y> && r )
|
||||
|
||||
#endif
|
||||
: px( r.lock().get() ), pn( static_cast< boost::detail::weak_count && >( r.pn ) ) // never throws
|
||||
BOOST_NOEXCEPT : px( r.lock().get() ), pn( static_cast< boost::detail::weak_count && >( r.pn ) )
|
||||
{
|
||||
boost::detail::sp_assert_convertible< Y, T >();
|
||||
r.px = 0;
|
||||
}
|
||||
|
||||
// for better efficiency in the T == Y case
|
||||
weak_ptr( weak_ptr && r )
|
||||
BOOST_NOEXCEPT : px( r.px ), pn( static_cast< boost::detail::weak_count && >( r.pn ) )
|
||||
{
|
||||
r.px = 0;
|
||||
}
|
||||
|
||||
// for better efficiency in the T == Y case
|
||||
weak_ptr( weak_ptr && r ): px( r.px ), pn( static_cast< boost::detail::weak_count && >( r.pn ) ) // never throws
|
||||
{
|
||||
r.px = 0;
|
||||
}
|
||||
|
||||
// for better efficiency in the T == Y case
|
||||
weak_ptr & operator=( weak_ptr && r ) // never throws
|
||||
weak_ptr & operator=( weak_ptr && r ) BOOST_NOEXCEPT
|
||||
{
|
||||
this_type( static_cast< weak_ptr && >( r ) ).swap( *this );
|
||||
return *this;
|
||||
@@ -128,24 +131,28 @@ public:
|
||||
weak_ptr( shared_ptr<Y> const & r )
|
||||
|
||||
#endif
|
||||
: px( r.px ), pn( r.pn ) // never throws
|
||||
BOOST_NOEXCEPT : px( r.px ), pn( r.pn )
|
||||
{
|
||||
boost::detail::sp_assert_convertible< Y, T >();
|
||||
}
|
||||
|
||||
#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300)
|
||||
|
||||
template<class Y>
|
||||
weak_ptr & operator=(weak_ptr<Y> const & r) // never throws
|
||||
weak_ptr & operator=( weak_ptr<Y> const & r ) BOOST_NOEXCEPT
|
||||
{
|
||||
boost::detail::sp_assert_convertible< Y, T >();
|
||||
|
||||
px = r.lock().get();
|
||||
pn = r.pn;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if defined( BOOST_HAS_RVALUE_REFS )
|
||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
||||
|
||||
template<class Y>
|
||||
weak_ptr & operator=( weak_ptr<Y> && r )
|
||||
weak_ptr & operator=( weak_ptr<Y> && r ) BOOST_NOEXCEPT
|
||||
{
|
||||
this_type( static_cast< weak_ptr<Y> && >( r ) ).swap( *this );
|
||||
return *this;
|
||||
@@ -154,26 +161,29 @@ public:
|
||||
#endif
|
||||
|
||||
template<class Y>
|
||||
weak_ptr & operator=(shared_ptr<Y> const & r) // never throws
|
||||
weak_ptr & operator=( shared_ptr<Y> const & r ) BOOST_NOEXCEPT
|
||||
{
|
||||
boost::detail::sp_assert_convertible< Y, T >();
|
||||
|
||||
px = r.px;
|
||||
pn = r.pn;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
shared_ptr<T> lock() const // never throws
|
||||
shared_ptr<T> lock() const BOOST_NOEXCEPT
|
||||
{
|
||||
return shared_ptr<element_type>( *this, boost::detail::sp_nothrow_tag() );
|
||||
return shared_ptr<T>( *this, boost::detail::sp_nothrow_tag() );
|
||||
}
|
||||
|
||||
long use_count() const // never throws
|
||||
long use_count() const BOOST_NOEXCEPT
|
||||
{
|
||||
return pn.use_count();
|
||||
}
|
||||
|
||||
bool expired() const // never throws
|
||||
bool expired() const BOOST_NOEXCEPT
|
||||
{
|
||||
return pn.use_count() == 0;
|
||||
}
|
||||
@@ -183,29 +193,30 @@ public:
|
||||
return pn.empty();
|
||||
}
|
||||
|
||||
void reset() // never throws in 1.30+
|
||||
void reset() BOOST_NOEXCEPT // never throws in 1.30+
|
||||
{
|
||||
this_type().swap(*this);
|
||||
}
|
||||
|
||||
void swap(this_type & other) // never throws
|
||||
void swap(this_type & other) BOOST_NOEXCEPT
|
||||
{
|
||||
std::swap(px, other.px);
|
||||
pn.swap(other.pn);
|
||||
}
|
||||
|
||||
void _internal_assign(T * px2, boost::detail::shared_count const & pn2)
|
||||
template<typename Y>
|
||||
void _internal_aliasing_assign(weak_ptr<Y> const & r, element_type * px2)
|
||||
{
|
||||
px = px2;
|
||||
pn = pn2;
|
||||
pn = r.pn;
|
||||
}
|
||||
|
||||
template<class Y> bool owner_before( weak_ptr<Y> const & rhs ) const
|
||||
template<class Y> bool owner_before( weak_ptr<Y> const & rhs ) const BOOST_NOEXCEPT
|
||||
{
|
||||
return pn < rhs.pn;
|
||||
}
|
||||
|
||||
template<class Y> bool owner_before( shared_ptr<Y> const & rhs ) const
|
||||
template<class Y> bool owner_before( shared_ptr<Y> const & rhs ) const BOOST_NOEXCEPT
|
||||
{
|
||||
return pn < rhs.pn;
|
||||
}
|
||||
@@ -222,17 +233,17 @@ private:
|
||||
|
||||
#endif
|
||||
|
||||
T * px; // contained pointer
|
||||
element_type * px; // contained pointer
|
||||
boost::detail::weak_count pn; // reference counter
|
||||
|
||||
}; // weak_ptr
|
||||
|
||||
template<class T, class U> inline bool operator<(weak_ptr<T> const & a, weak_ptr<U> const & b)
|
||||
template<class T, class U> inline bool operator<(weak_ptr<T> const & a, weak_ptr<U> const & b) BOOST_NOEXCEPT
|
||||
{
|
||||
return a.owner_before( b );
|
||||
}
|
||||
|
||||
template<class T> void swap(weak_ptr<T> & a, weak_ptr<T> & b)
|
||||
template<class T> void swap(weak_ptr<T> & a, weak_ptr<T> & b) BOOST_NOEXCEPT
|
||||
{
|
||||
a.swap(b);
|
||||
}
|
||||
|
@@ -1,14 +1,17 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<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">
|
||||
</head>
|
||||
<body>
|
||||
<body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
|
||||
Automatic redirection failed, please go to
|
||||
<a href="smart_ptr.htm">smart_ptr.htm</a>.
|
||||
</body>
|
||||
</html>
|
||||
<!--
|
||||
<09> Copyright Beman Dawes, 2001
|
||||
(C) Copyright Beman Dawes, 2001
|
||||
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
|
||||
|
@@ -1,47 +1,49 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>intrusive_ptr</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
</head>
|
||||
<body text="#000000" bgColor="#ffffff">
|
||||
<h1><A href="../../index.htm"><IMG height="86" alt="boost.png (6897 bytes)" src="../../boost.png" width="277" align="middle"
|
||||
border="0"></A>intrusive_ptr class template</h1>
|
||||
<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">intrusive_ptr class template</h1>
|
||||
<p>
|
||||
<A href="#Introduction">Introduction</A><br>
|
||||
<A href="#Synopsis">Synopsis</A><br>
|
||||
<A href="#Members">Members</A><br>
|
||||
<A href="#functions">Free Functions</A><br>
|
||||
<a href="#Introduction">Introduction</a><br>
|
||||
<a href="#Synopsis">Synopsis</a><br>
|
||||
<a href="#Members">Members</a><br>
|
||||
<a href="#functions">Free Functions</a><br>
|
||||
</p>
|
||||
<h2><a name="Introduction">Introduction</a></h2>
|
||||
<p>The <b>intrusive_ptr</b> class template stores a pointer to an object with an
|
||||
embedded reference count. Every new <b>intrusive_ptr</b> instance increments
|
||||
the reference count by using an unqualified call to the function <STRONG>intrusive_ptr_add_ref</STRONG>,
|
||||
passing it the pointer as an argument. Similarly, when an <STRONG>intrusive_ptr</STRONG>
|
||||
is destroyed, it calls <STRONG>intrusive_ptr_release</STRONG>; this function is
|
||||
<p>The <code>intrusive_ptr</code> class template stores a pointer to an object with an
|
||||
embedded reference count. Every new <code>intrusive_ptr</code> instance increments
|
||||
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 <code>intrusive_ptr</code>
|
||||
is destroyed, it calls <code>intrusive_ptr_release</code>; this function is
|
||||
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
|
||||
compilers that support argument-dependent lookup, <STRONG>intrusive_ptr_add_ref</STRONG>
|
||||
and <STRONG>intrusive_ptr_release</STRONG> should be defined in the namespace
|
||||
compilers that support argument-dependent lookup, <code>intrusive_ptr_add_ref</code>
|
||||
and <code>intrusive_ptr_release</code> should be defined in the namespace
|
||||
that corresponds to their parameter; otherwise, the definitions need to go in
|
||||
namespace <STRONG>boost</STRONG>.</p>
|
||||
<p>The class template is parameterized on <b>T</b>, the type of the object pointed
|
||||
to. <STRONG>intrusive_ptr<T></STRONG> can be implicitly converted to <STRONG>intrusive_ptr<U></STRONG>
|
||||
whenever <STRONG>T*</STRONG> can be implicitly converted to <STRONG>U*</STRONG>.</p>
|
||||
<P>The main reasons to use <STRONG>intrusive_ptr</STRONG> are:</P>
|
||||
<UL>
|
||||
<LI>
|
||||
namespace <code>boost</code>. The library provides a helper base class template
|
||||
<code><a href="intrusive_ref_counter.html">intrusive_ref_counter</a></code> which may
|
||||
help adding support for <code>intrusive_ptr</code> to user types.</p>
|
||||
<p>The class template is parameterized on <code>T</code>, the type of the object pointed
|
||||
to. <code>intrusive_ptr<T></code> can be implicitly converted to <code>intrusive_ptr<U></code>
|
||||
whenever <code>T*</code> can be implicitly converted to <code>U*</code>.</p>
|
||||
<p>The main reasons to use <code>intrusive_ptr</code> are:</p>
|
||||
<ul>
|
||||
<li>
|
||||
Some existing frameworks or OSes provide objects with embedded reference
|
||||
counts;
|
||||
<LI>
|
||||
The memory footprint of <STRONG>intrusive_ptr</STRONG>
|
||||
is the same as the corresponding raw pointer;
|
||||
<LI>
|
||||
<STRONG>intrusive_ptr<T></STRONG> can be constructed from an arbitrary
|
||||
raw pointer of type <STRONG>T *</STRONG>.</LI></UL>
|
||||
<P>As a general rule, if it isn't obvious whether <STRONG>intrusive_ptr</STRONG> better
|
||||
fits your needs than <STRONG>shared_ptr</STRONG>, try a <STRONG>shared_ptr</STRONG>-based
|
||||
design first.</P>
|
||||
counts;</li>
|
||||
<li>
|
||||
The memory footprint of <code>intrusive_ptr</code>
|
||||
is the same as the corresponding raw pointer;</li>
|
||||
<li>
|
||||
<code>intrusive_ptr<T></code> can be constructed from an arbitrary
|
||||
raw pointer of type <code>T *</code>.</li></ul>
|
||||
<p>As a general rule, if it isn't obvious whether <code>intrusive_ptr</code> better
|
||||
fits your needs than <code>shared_ptr</code>, try a <code>shared_ptr</code>-based
|
||||
design first.</p>
|
||||
<h2><a name="Synopsis">Synopsis</a></h2>
|
||||
<pre>namespace boost {
|
||||
|
||||
@@ -49,75 +51,77 @@
|
||||
|
||||
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>(T * p, bool add_ref = true);
|
||||
<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>(intrusive_ptr const & r);
|
||||
template<class Y> <A href="#constructors" >intrusive_ptr</A>(intrusive_ptr<Y> const & r);
|
||||
<a href="#constructors" >intrusive_ptr</a>(intrusive_ptr const & r);
|
||||
template<class Y> <a href="#constructors" >intrusive_ptr</a>(intrusive_ptr<Y> const & r);
|
||||
|
||||
<A href="#destructor" >~intrusive_ptr</A>();
|
||||
<a href="#destructor" >~intrusive_ptr</a>();
|
||||
|
||||
intrusive_ptr & <A href="#assignment" >operator=</A>(intrusive_ptr const & r);
|
||||
template<class Y> intrusive_ptr & <A href="#assignment" >operator=</A>(intrusive_ptr<Y> const & r);
|
||||
intrusive_ptr & <A href="#assignment" >operator=</A>(T * r);
|
||||
intrusive_ptr & <a href="#assignment" >operator=</a>(intrusive_ptr const & r);
|
||||
template<class Y> intrusive_ptr & <a href="#assignment" >operator=</a>(intrusive_ptr<Y> const & r);
|
||||
intrusive_ptr & <a href="#assignment" >operator=</a>(T * r);
|
||||
|
||||
void <a href="#reset" >reset</a>();
|
||||
void <a href="#reset" >reset</a>(T * r);
|
||||
void <a href="#reset" >reset</a>(T * r, bool add_ref);
|
||||
|
||||
T & <A href="#indirection" >operator*</A>() const; // never throws
|
||||
T * <A href="#indirection" >operator-></A>() const; // never throws
|
||||
T * <A href="#get" >get</A>() const; // never throws
|
||||
T & <a href="#indirection" >operator*</a>() const; // never throws
|
||||
T * <a href="#indirection" >operator-></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 & b); // never throws
|
||||
void <a href="#swap" >swap</a>(intrusive_ptr & b); // never throws
|
||||
};
|
||||
|
||||
template<class T, class U>
|
||||
bool <A href="#comparison" >operator==</A>(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b); // never throws
|
||||
bool <a href="#comparison" >operator==</a>(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b); // never throws
|
||||
|
||||
template<class T, class U>
|
||||
bool <A href="#comparison" >operator!=</A>(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b); // never throws
|
||||
bool <a href="#comparison" >operator!=</a>(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b); // never throws
|
||||
|
||||
template<class T>
|
||||
bool <A href="#comparison" >operator==</A>(intrusive_ptr<T> const & a, T * b); // never throws
|
||||
bool <a href="#comparison" >operator==</a>(intrusive_ptr<T> const & a, T * b); // never throws
|
||||
|
||||
template<class T>
|
||||
bool <A href="#comparison" >operator!=</A>(intrusive_ptr<T> const & a, T * b); // never throws
|
||||
bool <a href="#comparison" >operator!=</a>(intrusive_ptr<T> const & a, T * b); // never throws
|
||||
|
||||
template<class T>
|
||||
bool <A href="#comparison" >operator==</A>(T * a, intrusive_ptr<T> const & b); // never throws
|
||||
bool <a href="#comparison" >operator==</a>(T * a, intrusive_ptr<T> const & b); // never throws
|
||||
|
||||
template<class T>
|
||||
bool <A href="#comparison" >operator!=</A>(T * a, intrusive_ptr<T> const & b); // never throws
|
||||
bool <a href="#comparison" >operator!=</a>(T * a, intrusive_ptr<T> const & b); // never throws
|
||||
|
||||
template<class T, class U>
|
||||
bool <A href="#comparison" >operator<</A>(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b); // never throws
|
||||
bool <a href="#comparison" >operator<</a>(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b); // never throws
|
||||
|
||||
template<class T> void <A href="#free-swap" >swap</A>(intrusive_ptr<T> & a, intrusive_ptr<T> & b); // never throws
|
||||
template<class T> void <a href="#free-swap" >swap</a>(intrusive_ptr<T> & a, intrusive_ptr<T> & b); // never throws
|
||||
|
||||
template<class T> T * <A href="#get_pointer" >get_pointer</A>(intrusive_ptr<T> const & p); // never throws
|
||||
template<class T> T * <a href="#get_pointer" >get_pointer</a>(intrusive_ptr<T> const & p); // never throws
|
||||
|
||||
template<class T, class U>
|
||||
intrusive_ptr<T> <A href="#static_pointer_cast" >static_pointer_cast</A>(intrusive_ptr<U> const & r); // never throws
|
||||
intrusive_ptr<T> <a href="#static_pointer_cast" >static_pointer_cast</a>(intrusive_ptr<U> const & r); // never throws
|
||||
|
||||
template<class T, class U>
|
||||
intrusive_ptr<T> <A href="#const_pointer_cast" >const_pointer_cast</A>(intrusive_ptr<U> const & r); // never throws
|
||||
intrusive_ptr<T> <a href="#const_pointer_cast" >const_pointer_cast</a>(intrusive_ptr<U> const & r); // never throws
|
||||
|
||||
template<class T, class U>
|
||||
intrusive_ptr<T> <A href="#dynamic_pointer_cast" >dynamic_pointer_cast</A>(intrusive_ptr<U> const & r); // never throws
|
||||
intrusive_ptr<T> <a href="#dynamic_pointer_cast" >dynamic_pointer_cast</a>(intrusive_ptr<U> const & r); // never throws
|
||||
|
||||
template<class E, class T, class Y>
|
||||
std::basic_ostream<E, T> & <A href="#insertion-operator" >operator<<</A> (std::basic_ostream<E, T> & os, intrusive_ptr<Y> const & p);
|
||||
std::basic_ostream<E, T> & <a href="#insertion-operator" >operator<<</a> (std::basic_ostream<E, T> & os, intrusive_ptr<Y> const & p);
|
||||
|
||||
}</pre>
|
||||
<h2><a name="Members">Members</a></h2>
|
||||
<h3><a name="element_type">element_type</a></h3>
|
||||
<pre>typedef T element_type;</pre>
|
||||
<blockquote>
|
||||
<p>Provides the type of the template parameter T.</p>
|
||||
<p>Provides the type of the template parameter <code>T</code>.</p>
|
||||
</blockquote>
|
||||
<h3><a name="constructors">constructors</a></h3>
|
||||
<pre>intrusive_ptr(); // never throws</pre>
|
||||
@@ -138,26 +142,30 @@ template<class Y> intrusive_ptr(intrusive_ptr<Y> const & r);</pr
|
||||
</blockquote>
|
||||
<h3><a name="destructor">destructor</a></h3>
|
||||
<pre>~intrusive_ptr();</pre>
|
||||
<BLOCKQUOTE>
|
||||
<P><B>Effects:</B> <code>if(get() != 0) intrusive_ptr_release(get());</code>.</P>
|
||||
</BLOCKQUOTE>
|
||||
<H3><a name="assignment">assignment</a></H3>
|
||||
<blockquote>
|
||||
<p><b>Effects:</b> <code>if(get() != 0) intrusive_ptr_release(get());</code>.</p>
|
||||
</blockquote>
|
||||
<h3><a name="assignment">assignment</a></h3>
|
||||
<pre>intrusive_ptr & operator=(intrusive_ptr const & r);
|
||||
template<class Y> intrusive_ptr & operator=(intrusive_ptr<Y> const & r);
|
||||
intrusive_ptr & operator=(T * r);</pre>
|
||||
<BLOCKQUOTE>
|
||||
<P><B>Effects:</B> Equivalent to <code>intrusive_ptr(r).swap(*this)</code>.</P>
|
||||
<P><B>Returns:</B> <code>*this</code>.</P>
|
||||
</BLOCKQUOTE>
|
||||
<H3><a name="reset">reset</a></H3>
|
||||
<blockquote>
|
||||
<p><b>Effects:</b> Equivalent to <code>intrusive_ptr(r).swap(*this)</code>.</p>
|
||||
<p><b>Returns:</b> <code>*this</code>.</p>
|
||||
</blockquote>
|
||||
<h3><a name="reset">reset</a></h3>
|
||||
<pre>void reset();</pre>
|
||||
<BLOCKQUOTE>
|
||||
<P><B>Effects:</B> Equivalent to <code>intrusive_ptr().swap(*this)</code>.</P>
|
||||
</BLOCKQUOTE>
|
||||
<blockquote>
|
||||
<p><b>Effects:</b> Equivalent to <code>intrusive_ptr().swap(*this)</code>.</p>
|
||||
</blockquote>
|
||||
<pre>void reset(T * r);</pre>
|
||||
<BLOCKQUOTE>
|
||||
<P><B>Effects:</B> Equivalent to <code>intrusive_ptr(r).swap(*this)</code>.</P>
|
||||
</BLOCKQUOTE>
|
||||
<blockquote>
|
||||
<p><b>Effects:</b> Equivalent to <code>intrusive_ptr(r).swap(*this)</code>.</p>
|
||||
</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>
|
||||
<pre>T & operator*() const; // never throws</pre>
|
||||
<blockquote>
|
||||
@@ -177,16 +185,32 @@ intrusive_ptr & operator=(T * r);</pre>
|
||||
<p><b>Returns:</b> the stored pointer.</p>
|
||||
<p><b>Throws:</b> nothing.</p>
|
||||
</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>
|
||||
<pre>operator <i>unspecified-bool-type</i> () const; // never throws</pre>
|
||||
<blockquote>
|
||||
<p><b>Returns:</b> an unspecified value that, when used in boolean contexts, is
|
||||
equivalent to <code>get() != 0</code>.</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 && p->valid()) {}</code>.
|
||||
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>
|
||||
<h3><a name="swap">swap</a></h3>
|
||||
<pre>void swap(intrusive_ptr & b); // never throws</pre>
|
||||
@@ -237,61 +261,60 @@ intrusive_ptr & operator=(T * r);</pre>
|
||||
<blockquote>
|
||||
<p><b>Returns:</b> <code>std::less<T *>()(a.get(), b.get())</code>.</p>
|
||||
<p><b>Throws:</b> nothing.</p>
|
||||
<P><B>Notes:</B> Allows <STRONG>intrusive_ptr</STRONG> objects to be used as keys
|
||||
in associative containers.</P>
|
||||
<p><b>Notes:</b> Allows <code>intrusive_ptr</code> objects to be used as keys
|
||||
in associative containers.</p>
|
||||
</blockquote>
|
||||
<h3><a name="free-swap">swap</a></h3>
|
||||
<pre>template<class T>
|
||||
void swap(intrusive_ptr<T> & a, intrusive_ptr<T> & b); // never throws</pre>
|
||||
<BLOCKQUOTE>
|
||||
<P><B>Effects:</B> Equivalent to <code>a.swap(b)</code>.</P>
|
||||
<P><B>Throws:</B> nothing.</P>
|
||||
<P><B>Notes:</B> Matches the interface of <B>std::swap</B>. Provided as an aid to
|
||||
generic programming.</P>
|
||||
</BLOCKQUOTE>
|
||||
<blockquote>
|
||||
<p><b>Effects:</b> Equivalent to <code>a.swap(b)</code>.</p>
|
||||
<p><b>Throws:</b> nothing.</p>
|
||||
<p><b>Notes:</b> Matches the interface of <code>std::swap</code>. Provided as an aid to
|
||||
generic programming.</p>
|
||||
</blockquote>
|
||||
<h3><a name="get_pointer">get_pointer</a></h3>
|
||||
<pre>template<class T>
|
||||
T * get_pointer(intrusive_ptr<T> const & p); // never throws</pre>
|
||||
<BLOCKQUOTE>
|
||||
<P><B>Returns:</B> <code>p.get()</code>.</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">
|
||||
mem_fn</A>.</P>
|
||||
</BLOCKQUOTE>
|
||||
<blockquote>
|
||||
<p><b>Returns:</b> <code>p.get()</code>.</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">
|
||||
mem_fn</a>.</p>
|
||||
</blockquote>
|
||||
<h3><a name="static_pointer_cast">static_pointer_cast</a></h3>
|
||||
<pre>template<class T, class U>
|
||||
intrusive_ptr<T> static_pointer_cast(intrusive_ptr<U> const & r); // never throws</pre>
|
||||
<BLOCKQUOTE>
|
||||
<P><B>Returns:</B> <code>intrusive_ptr<T>(static_cast<T*>(r.get()))</code>.</P>
|
||||
<P><B>Throws:</B> nothing.</P>
|
||||
</BLOCKQUOTE>
|
||||
<blockquote>
|
||||
<p><b>Returns:</b> <code>intrusive_ptr<T>(static_cast<T*>(r.get()))</code>.</p>
|
||||
<p><b>Throws:</b> nothing.</p>
|
||||
</blockquote>
|
||||
<h3><a name="const_pointer_cast">const_pointer_cast</a></h3>
|
||||
<pre>template<class T, class U>
|
||||
intrusive_ptr<T> const_pointer_cast(intrusive_ptr<U> const & r); // never throws</pre>
|
||||
<BLOCKQUOTE>
|
||||
<P><B>Returns:</B> <code>intrusive_ptr<T>(const_cast<T*>(r.get()))</code>.</P>
|
||||
<P><B>Throws:</B> nothing.</P>
|
||||
</BLOCKQUOTE>
|
||||
<blockquote>
|
||||
<p><b>Returns:</b> <code>intrusive_ptr<T>(const_cast<T*>(r.get()))</code>.</p>
|
||||
<p><b>Throws:</b> nothing.</p>
|
||||
</blockquote>
|
||||
<h3><a name="dynamic_pointer_cast">dynamic_pointer_cast</a></h3>
|
||||
<pre>template<class T, class U>
|
||||
intrusive_ptr<T> dynamic_pointer_cast(intrusive_ptr<U> const & r);</pre>
|
||||
<BLOCKQUOTE>
|
||||
<P><B>Returns:</B> <code>intrusive_ptr<T>(dynamic_cast<T*>(r.get()))</code>.</P>
|
||||
<P><B>Throws:</B> nothing.</P>
|
||||
</BLOCKQUOTE>
|
||||
<blockquote>
|
||||
<p><b>Returns:</b> <code>intrusive_ptr<T>(dynamic_cast<T*>(r.get()))</code>.</p>
|
||||
<p><b>Throws:</b> nothing.</p>
|
||||
</blockquote>
|
||||
<h3><a name="insertion-operator">operator<<</a></h3>
|
||||
<pre>template<class E, class T, class Y>
|
||||
std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, intrusive_ptr<Y> const & p);</pre>
|
||||
<BLOCKQUOTE>
|
||||
<p><STRONG>Effects:</STRONG> <code>os << p.get();</code>.</p>
|
||||
<P><B>Returns:</B> <code>os</code>.</P>
|
||||
</BLOCKQUOTE>
|
||||
<blockquote>
|
||||
<p><b>Effects:</b> <code>os << p.get();</code>.</p>
|
||||
<p><b>Returns:</b> <code>os</code>.</p>
|
||||
</blockquote>
|
||||
<hr>
|
||||
<p>$Date$</p>
|
||||
<p>
|
||||
$Date$</p>
|
||||
<p>
|
||||
<small>Copyright <20> 2003-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
|
||||
copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
|
||||
<small>Copyright © 2003-2005, 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> 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>
|
||||
|
94
intrusive_ref_counter.html
Normal file
94
intrusive_ref_counter.html
Normal file
@@ -0,0 +1,94 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>intrusive_ref_counter</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
</head>
|
||||
<body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
|
||||
<h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
|
||||
width="277" align="middle" border="0">basic_intrusive_ref_counter class template</h1>
|
||||
<p>
|
||||
<A href="#Introduction">Introduction</A><br>
|
||||
<A href="#Synopsis">Synopsis</A><br>
|
||||
<A href="#Members">Members</A><br>
|
||||
</p>
|
||||
<h2><a name="Introduction">Introduction</a></h2>
|
||||
<p>The <STRONG>intrusive_ref_counter</STRONG> class template implements a reference counter for a derived
|
||||
user's class that is intended to be used with <STRONG><a href="intrusive_ptr.html">intrusive_ptr</a></STRONG>.
|
||||
The base class has associated <STRONG>intrusive_ptr_add_ref</STRONG> and <STRONG>intrusive_ptr_release</STRONG> functions
|
||||
which modify the reference counter as needed and destroy the user's object when the counter drops to zero.</p>
|
||||
<p>The class template is parameterized on <STRONG>DerivedT</STRONG> and <STRONG>CounterPolicyT</STRONG> parameters.
|
||||
The first parameter is the user's class that derives from <STRONG>intrusive_ref_counter</STRONG>. This type
|
||||
is needed in order to destroy the object correctly when there are no references to it left.</p>
|
||||
<p>The second parameter is a policy that defines the nature of the reference counter.
|
||||
Boost.SmartPtr provides two such policies: <STRONG>thread_unsafe_counter</STRONG> and <STRONG>thread_safe_counter</STRONG>. The former
|
||||
instructs the <STRONG>intrusive_ref_counter</STRONG> base class to use a counter only suitable for a single-threaded use.
|
||||
Pointers to a single object that uses this kind of reference counter must not be used in different threads. The latter policy
|
||||
makes the reference counter thread-safe, unless the target platform doesn't support threading. Since in modern systems support for
|
||||
threading is common, the default counter policy is <STRONG>thread_safe_counter</STRONG>.</p>
|
||||
<h2><a name="Synopsis">Synopsis</a></h2>
|
||||
<pre>namespace boost {
|
||||
|
||||
struct thread_unsafe_counter;
|
||||
struct thread_safe_counter;
|
||||
|
||||
template<class DerivedT, class CounterPolicyT = thread_safe_counter>
|
||||
class intrusive_ref_counter
|
||||
{
|
||||
public:
|
||||
<A href="#constructors" >intrusive_ref_counter</A>() = noexcept;
|
||||
<A href="#constructors" >intrusive_ref_counter</A>(intrusive_ref_counter const & r) = noexcept;
|
||||
|
||||
intrusive_ref_counter & <A href="#assignment" >operator=</A>(intrusive_ref_counter const & r) noexcept;
|
||||
|
||||
unsigned int <a href="#use_count" >use_count</a>() const noexcept;
|
||||
|
||||
protected:
|
||||
<A href="#destructor" >~intrusive_ref_counter</A>() = default;
|
||||
};
|
||||
|
||||
}</pre>
|
||||
<h2><a name="Members">Members</a></h2>
|
||||
<h3><a name="constructors">constructors</a></h3>
|
||||
<pre>intrusive_ref_counter();</pre>
|
||||
<blockquote>
|
||||
<p><b>Postconditions:</b> <code>use_count() == 0</code>.</p>
|
||||
<p><b>Throws:</b> nothing.</p>
|
||||
<P><B>Notes:</B> The pointer to the constructed object is expected to be passed to <STRONG>intrusive_ptr</STRONG>
|
||||
constructor, assignment operator or <STRONG>reset()</STRONG> method, which would increment the reference counter.</P>
|
||||
</blockquote>
|
||||
<pre>intrusive_ref_counter(intrusive_ref_counter const &);</pre>
|
||||
<blockquote>
|
||||
<p><b>Postconditions:</b> <code>use_count() == 0</code>.</p>
|
||||
<p><b>Throws:</b> nothing.</p>
|
||||
<P><B>Notes:</B> The pointer to the constructed object is expected to be passed to <STRONG>intrusive_ptr</STRONG>
|
||||
constructor, assignment operator or <STRONG>reset()</STRONG> method, which would increment the reference counter.</P>
|
||||
</blockquote>
|
||||
<h3><a name="destructor">destructor</a></h3>
|
||||
<pre>~intrusive_ref_counter();</pre>
|
||||
<BLOCKQUOTE>
|
||||
<p><b>Throws:</b> nothing.</p>
|
||||
<P><B>Effects:</B> Destroys the counter object.</P>
|
||||
<P><B>Notes:</B> The destructor is protected so that the object can only be destroyed through the <STRONG>DerivedT</STRONG> class.</P>
|
||||
</BLOCKQUOTE>
|
||||
<H3><a name="assignment">assignment</a></H3>
|
||||
<pre>intrusive_ref_counter & operator=(intrusive_ref_counter const & r) noexcept;</pre>
|
||||
<BLOCKQUOTE>
|
||||
<P><B>Effects:</B> Does nothing, reference counter is not modified.</P>
|
||||
<P><B>Returns:</B> <code>*this</code>.</P>
|
||||
</BLOCKQUOTE>
|
||||
<H3><a name="use_count">use_count</a></H3>
|
||||
<pre>unsigned int use_count() const noexcept;</pre>
|
||||
<BLOCKQUOTE>
|
||||
<p><b>Returns:</b> The current value of the reference counter.</p>
|
||||
<p><b>Throws:</b> nothing.</p>
|
||||
<P><B>Notes:</B> The returned value may not be actual in multi-threaded applications.</P>
|
||||
</BLOCKQUOTE>
|
||||
<hr>
|
||||
<p>$Date$</p>
|
||||
<p>
|
||||
<small>Copyright © 2013 Andrey Semashev. Distributed under the Boost Software License, Version
|
||||
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or
|
||||
copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
|
||||
</body>
|
||||
</html>
|
@@ -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>
|
||||
<head>
|
||||
<title>make_shared and allocate_shared</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
</head>
|
||||
<body text="#000000" bgColor="#ffffff">
|
||||
<h1><A href="../../index.htm"><IMG height="86" alt="boost.png (6897 bytes)" src="../../boost.png" width="277" align="middle"
|
||||
border="0"></A>make_shared and allocate_shared function templates</h1>
|
||||
<body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
|
||||
<h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
|
||||
width="277" align="middle" border="0">make_shared and allocate_shared
|
||||
function templates</h1>
|
||||
<p><A href="#Introduction">Introduction</A><br>
|
||||
<A href="#Synopsis">Synopsis</A><br>
|
||||
<A href="#functions">Free Functions</A><br>
|
||||
@@ -41,7 +42,7 @@
|
||||
template<typename T, typename A>
|
||||
shared_ptr<T> <a href="#functions">allocate_shared</a>( A const & );
|
||||
|
||||
#if defined( BOOST_HAS_VARIADIC_TMPL ) && defined( BOOST_HAS_RVALUE_REFS ) // C++0x prototypes
|
||||
#if !defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) // C++0x prototypes
|
||||
|
||||
template<typename T, typename... Args>
|
||||
shared_ptr<T> <a href="#functions">make_shared</a>( Args && ... args );
|
||||
@@ -79,7 +80,7 @@ template<class T, class A, class... Args>
|
||||
where <code>pv</code> is a <code>void*</code> pointing to storage suitable
|
||||
to hold an object of type <code>T</code>,
|
||||
shall be well-formed. <code>A</code> shall be an <em>Allocator</em>,
|
||||
as described in section 20.1.5 (<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>
|
||||
<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>
|
||||
@@ -109,8 +110,7 @@ template<class T, class A, class... Args>
|
||||
<pre>boost::shared_ptr<std::string> x = boost::make_shared<std::string>("hello, world!");
|
||||
std::cout << *x;</pre>
|
||||
<hr>
|
||||
<p>
|
||||
$Date: 2008-05-19 15:42:39 -0400 (Mon, 19 May 2008) $</p>
|
||||
<p>$Date$</p>
|
||||
<p><small>Copyright 2008 Peter Dimov. Copyright 2008 Frank Mori Hess.
|
||||
Distributed under the Boost Software License,
|
||||
Version 1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A>
|
||||
|
273
make_shared_array.html
Normal file
273
make_shared_array.html
Normal file
@@ -0,0 +1,273 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>make_shared and allocate_shared for arrays</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
</head>
|
||||
<body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
|
||||
<h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
|
||||
width="277" align="middle" border="0">make_shared and allocate_shared
|
||||
for arrays</h1>
|
||||
<p><a href="#introduction">Introduction</a><br>
|
||||
<a href="#synopsis">Synopsis</a><br>
|
||||
<a href="#common">Common Requirements</a><br>
|
||||
<a href="#functions">Free Functions</a><br>
|
||||
<a href="#history">History</a><br>
|
||||
<a href="#references">References</a></p>
|
||||
<h2><a name="introduction">Introduction</a></h2>
|
||||
<p>Originally the Boost function templates <code>make_shared</code> and
|
||||
<code>allocate_shared</code> were for efficient allocation of shared
|
||||
objects only. There was a need to have efficient allocation of
|
||||
shared arrays. One criticism of class template <code>shared_array</code>
|
||||
was always the lack of a <a href="make_shared.html">make_shared</a>
|
||||
utility which ensures only a single allocation.</p>
|
||||
<p>The header files <boost/smart_ptr/make_shared_array.hpp> and
|
||||
<boost/smart_ptr/allocate_shared_array.hpp> provide function
|
||||
templates, overloads of <code>make_shared</code> and
|
||||
<code>allocate_shared</code> for array types, to address this need.
|
||||
<code>make_shared</code> uses the global operator <code>new</code> to
|
||||
allocate memory, whereas <code>allocate_shared</code> uses an
|
||||
user-supplied allocator, allowing finer control.</p>
|
||||
<h2><a name="synopsis">Synopsis</a></h2>
|
||||
<pre>namespace boost {
|
||||
template<class U> // U is T[]
|
||||
shared_ptr<U> <a href="#functions">make_shared</a>(size_t size);
|
||||
|
||||
template<class U, class A> // U is T[]
|
||||
shared_ptr<U> <a href="#functions">allocate_shared</a>(const A& allocator, size_t size);
|
||||
|
||||
template<class U> // U is T[N]
|
||||
shared_ptr<U> <a href="#functions">make_shared</a>();
|
||||
|
||||
template<class U, class A> // U is T[N]
|
||||
shared_ptr<U> <a href="#functions">allocate_shared</a>(const A& allocator);
|
||||
|
||||
template<class U> // U is T[]
|
||||
shared_ptr<U> <a href="#functions">make_shared</a>(size_t size, const T& value);
|
||||
|
||||
template<class U, class A> // U is T[]
|
||||
shared_ptr<U> <a href="#functions">allocate_shared</a>(const A& allocator, size_t size, const T& value);
|
||||
|
||||
template<class U> // U is T[N]
|
||||
shared_ptr<U> <a href="#functions">make_shared</a>(const T& value);
|
||||
|
||||
template<class U, class A> // U is T[N]
|
||||
shared_ptr<U> <a href="#functions">allocate_shared</a>(const A& allocator, const T& value);
|
||||
|
||||
template<class U> // U is T[]
|
||||
shared_ptr<U> <a href="#functions">make_shared_noinit</a>(size_t size);
|
||||
|
||||
template<class U, class A> // U is T[]
|
||||
shared_ptr<U> <a href="#functions">allocate_shared_noinit</a>(const A& allocator, size_t size);
|
||||
|
||||
template<class U> // U is T[N]
|
||||
shared_ptr<U> <a href="#functions">make_shared_noinit</a>();
|
||||
|
||||
template<class U, class A> // U is T[N]
|
||||
shared_ptr<U> <a href="#functions">allocate_shared_noinit</a>(const A& allocator);
|
||||
}</pre>
|
||||
<h2><a name="common">Common Requirements</a></h2>
|
||||
<pre>template<class U>
|
||||
shared_ptr<U> make_shared(<em>args</em>);
|
||||
template<class U, class A>
|
||||
shared_ptr<U> allocate_shared(const A& allocator, <em>args</em>);
|
||||
template<class U>
|
||||
shared_ptr<U> make_shared_noinit(<em>args</em>);
|
||||
template<class U, class A>
|
||||
shared_ptr<U> allocate_shared_noinit(const A& allocator, <em>args</em>);</pre>
|
||||
<blockquote>
|
||||
<p><b>Requires:</b> <code>U</code> is of the form <code>T[]</code> or
|
||||
<code>T[N]</code>. <code>A</code> shall be an <em>Allocator</em>, as
|
||||
described in section 17.6.3.5 [<strong>Allocator
|
||||
requirements</strong>] of the C++ Standard. The copy constructor and
|
||||
destructor of <code>A</code> shall not throw exceptions.</p>
|
||||
<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><em>args</em></code>
|
||||
as specified by the concrete overload). The object is initialized as
|
||||
specified by the concrete overload. The templates
|
||||
<code>allocate_shared</code> and <code>allocate_shared_noinit</code>
|
||||
use a copy of <code>allocator</code> to allocate memory. If an
|
||||
exception is thrown, the functions have no effect.</p>
|
||||
<p><b>Returns:</b> A <code>shared_ptr</code> instance that stores and
|
||||
owns the address of the newly constructed object.</p>
|
||||
<p><b>Postconditions:</b> <code>r.get() != 0 &&
|
||||
r.use_count() == 1</code>, where <code>r</code> is the return
|
||||
value.</p>
|
||||
<p><b>Throws:</b> <code>bad_alloc</code>, an exception thrown from
|
||||
<code>A::allocate</code>, or from the initialization of the
|
||||
object.</p>
|
||||
<p><b>Remarks:</b></p>
|
||||
<blockquote>
|
||||
<p>This implementation performs no more than one memory
|
||||
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<A2>::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<A2>::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>
|
||||
<p><b>Notes:</b> These functions will typically allocate more memory
|
||||
than <code>sizeof(U)</code> to allow for internal bookkeeping
|
||||
structures such as the reference counts.</p>
|
||||
</blockquote>
|
||||
<h2><a name="functions">Free Functions</a></h2>
|
||||
<pre>template<class U>
|
||||
shared_ptr<U> make_shared(size_t size);
|
||||
template<class U, class A>
|
||||
shared_ptr<U> allocate_shared(const A& allocator, size_t size);</pre>
|
||||
<blockquote>
|
||||
<p><b>Returns:</b> A <code>shared_ptr</code> to a value-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<int[]> a1 = boost::make_shared<int[]>(size);
|
||||
boost::shared_ptr<int[][2]> a2 = boost::make_shared<int[][2]>(size);</pre>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
<pre>template<class U>
|
||||
shared_ptr<U> make_shared();
|
||||
template<class U, class A>
|
||||
shared_ptr<U> allocate_shared(const A& allocator);</pre>
|
||||
<blockquote>
|
||||
<p><b>Returns:</b> A <code>shared_ptr</code> to a value-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<int[8]> a1 = boost::make_shared<int[8]>();
|
||||
boost::shared_ptr<int[4][2]> a2 = boost::make_shared<int[4][2]>();</pre>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
<pre>template<class U>
|
||||
shared_ptr<U> make_shared(size_t size, const T& value);
|
||||
template<class U, class A>
|
||||
shared_ptr<U> allocate_shared(const A& allocator, size_t size, const T& 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<int[]> a1 = boost::make_shared<int[]>(size, 1);
|
||||
boost::shared_ptr<int[][2]> a2 = boost::make_shared<int[][2]>(size, {1, 2});</pre>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
<pre>template<class U>
|
||||
shared_ptr<U> make_shared(const T& value);
|
||||
template<class U, class A>
|
||||
shared_ptr<U> allocate_shared(const A& allocator, const T& 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<int[8]> a1 = boost::make_shared<int[8]>(1);
|
||||
boost::shared_ptr<int[4][2]> a2 = boost::make_shared<int[4][2]>({1, 2});</pre>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
<pre>template<class U>
|
||||
shared_ptr<U> make_shared_noinit(size_t size);
|
||||
template<class U, class A>
|
||||
shared_ptr<U> allocate_shared_noinit(const A& 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<int[]> a1 = boost::make_shared_noinit<int[]>(size);
|
||||
boost::shared_ptr<int[][2]> a2 = boost::make_shared_noinit<int[][2]>(size);</pre>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
<pre>template<class U>
|
||||
shared_ptr<U> make_shared_noinit();
|
||||
template<class U, class A>
|
||||
shared_ptr<U> allocate_shared_noinit(const A& 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<int[8]> a1 = boost::make_shared_noinit<int[8]>();
|
||||
boost::shared_ptr<int[4][2]> a2 = boost::make_shared_noinit<int[4][2]>();</pre>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
<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, and reduced the spatial overhead of the internal
|
||||
bookkeeping structures.</p>
|
||||
<p>November 2012. Glen Fernandes contributed implementations of
|
||||
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
|
||||
& Glen Fernandes, January, 2014.</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>
|
152
make_unique.html
Normal file
152
make_unique.html
Normal 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 <boost/make_unique.hpp> 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<class U> // U is not array
|
||||
unique_ptr<U> <a href="#functions">make_unique</a>();
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template<class U, class... Args> // U is not array
|
||||
unique_ptr<U> <a href="#functions">make_unique</a>(Args&&... args);
|
||||
#endif
|
||||
|
||||
template<class U> // U is not array
|
||||
unique_ptr<U> <a href="#functions">make_unique</a>(U&& value);
|
||||
|
||||
template<class U> // U is T[]
|
||||
unique_ptr<U> <a href="#functions">make_unique</a>(size_t size);
|
||||
|
||||
template<class U> // U is not array
|
||||
unique_ptr<U> <a href="#functions">make_unique_noinit</a>();
|
||||
|
||||
template<class U> // U is T[]
|
||||
unique_ptr<U> <a href="#functions">make_unique_noinit</a>(size_t size);
|
||||
}</pre>
|
||||
<h2><a name="common">Common Requirements</a></h2>
|
||||
<pre>template<class U>
|
||||
unique_ptr<U> make_unique(<em>args</em>);
|
||||
template<class U>
|
||||
unique_ptr<U> 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<class U, class... Args>
|
||||
unique_ptr<U> make_unique(Args&&... args);</pre>
|
||||
<blockquote>
|
||||
<p><b>Returns:</b> A unique_ptr to an object of type <code>U</code>,
|
||||
initialized to <code>U(forward<Args>(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<float> p1 = boost::make_unique<float>();
|
||||
unique_ptr<point> p2 = boost::make_unique<point>(x, y);</pre>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
<pre>template<class U>
|
||||
unique_ptr<U> make_unique(U&& 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<string> p1 = boost::make_unique<string>({'a', 'b'});
|
||||
unique_ptr<point> p2 = boost::make_unique<point>({-10, 25});</pre>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
<pre>template<class U>
|
||||
unique_ptr<U> 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<double[]> p1 = boost::make_unique<double[]>(4);
|
||||
unique_ptr<int[][2]> p2 = boost::make_unique<int[][2]>(2);</pre>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
<pre>template<class U>
|
||||
unique_ptr<U> 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<float> p1 = boost::make_unique_noinit<float>();
|
||||
unique_ptr<point> p2 = boost::make_unique_noinit<point>();</pre>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
<pre>template<class U>
|
||||
unique_ptr<U> 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<double[]> p1 = boost::make_unique_noinit<double[]>(4);
|
||||
unique_ptr<int[][2]> p2 = boost::make_unique_noinit<int[][2]>(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>
|
@@ -1,11 +1,12 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>pointer_cast.hpp</title>
|
||||
<title>pointer_cast</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
</head>
|
||||
<body>
|
||||
<h1><IMG height="86" alt="C++ Boost" src="../../boost.png" width="277" align="middle" border="0">Pointer
|
||||
cast functions</h1>
|
||||
<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">pointer_cast</h1>
|
||||
<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>)
|
||||
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
|
||||
independent code.</P>
|
||||
<hr>
|
||||
<p>Revised: $Date$</p>
|
||||
<p>$Date$</p>
|
||||
<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">
|
||||
LICENSE_1_0.txt</A> or a copy at <<A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>>.)</p>
|
||||
|
@@ -1,12 +1,12 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>pointer_to_other.hpp</title>
|
||||
<title>pointer_to_other</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
</head>
|
||||
<body bgcolor="#ffffff" text="#000000">
|
||||
<h1><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" WIDTH="277" HEIGHT="86">Header
|
||||
<a href="../../boost/pointer_to_other.hpp">boost/pointer_to_other.hpp</a></h1>
|
||||
<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">pointer_to_other</h1>
|
||||
<p>
|
||||
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
|
||||
@@ -99,7 +99,7 @@ class memory_allocator
|
||||
};</pre>
|
||||
<p>As we can see, using pointer_to_other we can create pointer independent code.</p>
|
||||
<hr>
|
||||
<p>Last revised: $Date$</p>
|
||||
<p>$Date$</p>
|
||||
<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>
|
||||
(See accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or a
|
||||
|
@@ -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>
|
||||
<head>
|
||||
<title>scoped_array</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
</head>
|
||||
<body bgcolor="#ffffff" text="#000000">
|
||||
<h1><A href="../../index.htm"><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="277" height="86"
|
||||
border="0"></A>scoped_array class template</h1>
|
||||
<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">scoped_array class template</h1>
|
||||
<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>
|
||||
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>.
|
||||
Provided as an aid to generic programming.</p>
|
||||
<hr>
|
||||
<p>Revised <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan-->
|
||||
09 January 2003<!--webbot bot="Timestamp" endspan i-checksum="32310"--></p>
|
||||
<p>$Date$</p>
|
||||
<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
|
||||
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or
|
||||
|
@@ -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>
|
||||
<head>
|
||||
<title>scoped_ptr</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
</head>
|
||||
<body bgcolor="#ffffff" text="#000000">
|
||||
<h1><A href="../../index.htm"><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="277" height="86"
|
||||
border="0"></A>scoped_ptr class template</h1>
|
||||
<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">scoped_ptr class template</h1>
|
||||
<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.)
|
||||
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
|
||||
is required. (supplied by Dave Abrahams)</p>
|
||||
<hr>
|
||||
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B %Y" startspan -->
|
||||
09 January 2003<!--webbot bot="Timestamp" endspan i-checksum="32310" --></p>
|
||||
<p>$Date</p>
|
||||
<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
|
||||
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or
|
||||
|
@@ -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>
|
||||
<head>
|
||||
<title>shared_array</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
</head>
|
||||
<body bgcolor="#ffffff" text="#000000">
|
||||
<h1><A href="../../index.htm"><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="277" height="86"
|
||||
border="0"></A>shared_array class template</h1>
|
||||
<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">shared_array class template</h1>
|
||||
<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>
|
||||
expression.) The object pointed to is guaranteed to be deleted when the last <b>shared_array</b>
|
||||
@@ -174,9 +174,7 @@ template<class T>
|
||||
<p>Equivalent to <b>a.swap(b)</b>. Matches the interface of <b>std::swap</b>.
|
||||
Provided as an aid to generic programming.</p>
|
||||
<hr>
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan -->
|
||||
09 January 2003<!--webbot bot="Timestamp" endspan i-checksum="32310" --></p>
|
||||
<p>$Date$</p>
|
||||
<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
|
||||
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or
|
||||
|
1034
shared_ptr.htm
1034
shared_ptr.htm
File diff suppressed because it is too large
Load Diff
@@ -4,9 +4,9 @@
|
||||
<title>Smart Pointers</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
</head>
|
||||
<body bgcolor="#ffffff" text="#000000">
|
||||
<h1><A href="../../index.htm"><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="277" height="86"
|
||||
border="0"></A>Smart Pointers</h1>
|
||||
<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">Smart Pointers</h1>
|
||||
<p><a href="#Introduction">Introduction</a><br>
|
||||
<a href="#common_requirements">Common Requirements</a><br>
|
||||
<a href="#Exception_Safety">Exception Safety</a><br>
|
||||
@@ -62,14 +62,24 @@
|
||||
described in Bjarne Stroustrup's "The C++ Programming Language", 3rd edition,
|
||||
Section 14.4, Resource Management.</p>
|
||||
<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">
|
||||
<table border="1" cellpadding="4" cellspacing="0">
|
||||
<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"><boost/make_shared.hpp></a></td>
|
||||
<td>Efficient creation of <code>shared_ptr</code> objects.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="make_shared_array.html"><b>make_shared, allocate_shared</b></a> for arrays</td>
|
||||
<td><a href="../../boost/make_shared.hpp"><boost/make_shared.hpp></a></td>
|
||||
<td>Efficient creation of <code>shared_ptr</code> arrays.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="make_unique.html"><b>make_unique</b></a></td>
|
||||
<td><a href="../../boost/make_unique.hpp"><boost/make_unique.hpp></a></td>
|
||||
<td>Creation of <code>unique_ptr</code> objects and arrays.</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<p>A test program, <a href="test/smart_ptr_test.cpp">smart_ptr_test.cpp</a>, is
|
||||
@@ -126,6 +136,18 @@
|
||||
<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>
|
||||
<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&F-14">[D&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>
|
||||
and <b>allocate_shared</b> for arrays. They achieve a single allocation for an
|
||||
array that can be initialized with constructor arguments or initializer lists
|
||||
as well as overloads for default initialization and no value initialization.
|
||||
See the <a href="make_shared_array.html">make_shared and allocate_shared for
|
||||
arrays</a> page for more information.</p>
|
||||
<p>January 2002. Peter Dimov reworked all four classes, adding features, fixing
|
||||
bugs, and splitting them into four separate headers, and added <b>weak_ptr</b>.
|
||||
See the <a href="compatibility.htm">compatibility</a> page for a summary of the
|
||||
@@ -179,7 +201,10 @@
|
||||
the full committee, <b>counted_ptr</b> was rejected and surprising
|
||||
transfer-of-ownership semantics were added to <b>auto_ptr</b>.</p>
|
||||
<h2><a name="References">References</a></h2>
|
||||
<p>[<a name="Col-94">Col-94</a>] Gregory Colvin, <a href="http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/1994/N0555.pdf">
|
||||
<p>[<a name="D&F-14">D&F-14</a>] Peter Dimov & 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">
|
||||
Exception Safe Smart Pointers</a>, C++ committee document 94-168/N0555,
|
||||
July, 1994.</p>
|
||||
<p>[<a name="E&D-94">E&D-94</a>] John R. Ellis & David L. Detlefs, <a href="http://www.usenix.org/publications/library/proceedings/c++94/full_papers/ellis.a">
|
||||
|
@@ -7,9 +7,9 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
</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
|
||||
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>
|
||||
</ul>
|
||||
<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>
|
||||
<p><EFBFBD> Copyright Gavin Collings 2000. Permission to copy, use, modify, sell
|
||||
<p>$Date$</p>
|
||||
<p>© Copyright Gavin Collings 2000. Permission to copy, use, modify, sell
|
||||
and distribute this document is granted provided this copyright notice appears in all
|
||||
copies. This document is provided "as is" without express or implied warranty,
|
||||
and with no claim as to its suitability for any purpose.</p>
|
||||
|
@@ -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>
|
||||
<head>
|
||||
<title>Smart Pointer Programming Techniques</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
</head>
|
||||
<body text="#000000" bgColor="#ffffff">
|
||||
<h1><A href="../../index.htm"><IMG height="86" alt="boost.png (6897 bytes)" src="../../boost.png" width="277" align="middle"
|
||||
border="0"></A>Smart Pointer Programming Techniques</h1>
|
||||
<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">Smart Pointer Programming Techniques</h1>
|
||||
<p><A href="#incomplete">Using incomplete classes for implementation hiding</A><br>
|
||||
<A href="#pimpl">The "Pimpl" idiom</A><br>
|
||||
<A href="#abstract">Using abstract classes for implementation hiding</A><br>
|
||||
@@ -624,7 +624,7 @@ public:
|
||||
<h2><A name="wrapper">Using <code>shared_ptr</code> to wrap member function calls</A></h2>
|
||||
<p><code>shared_ptr</code> implements the ownership semantics required from the <code>Wrap</code>/<code>CallProxy</code>
|
||||
scheme described in Bjarne Stroustrup's article "Wrapping C++ Member Function
|
||||
Calls" (available online at <A href="http://www.research.att.com/~bs/wrapper.pdf">http://www.research.att.com/~bs/wrapper.pdf</A>).
|
||||
Calls" (available online at <A href="http://www.stroustrup.com/wrapper.pdf">http://www.stroustrup.com/wrapper.pdf</A>).
|
||||
An implementation is given below:</p>
|
||||
<pre>template<class T> class pointer
|
||||
{
|
||||
@@ -758,7 +758,7 @@ public:
|
||||
all weak pointers will automatically expire.</p>
|
||||
<hr>
|
||||
<p>$Date$</p>
|
||||
<p><small>Copyright <EFBFBD> 2003 Peter Dimov. Distributed under the Boost Software License, Version
|
||||
<p><small>Copyright © 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
|
||||
copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
|
||||
</body>
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# Boost.SmartPtr Library test Jamfile
|
||||
#
|
||||
# Copyright (c) 2003-2007 Peter Dimov
|
||||
# Copyright (c) 2003-2013 Peter Dimov
|
||||
# Copyright (c) 2003 Dave Abrahams
|
||||
#
|
||||
# Distributed under the Boost Software License, Version 1.0. (See
|
||||
@@ -21,6 +21,7 @@ import testing ;
|
||||
[ run get_deleter_test.cpp ]
|
||||
[ run intrusive_ptr_test.cpp ]
|
||||
[ run intrusive_ptr_move_test.cpp ]
|
||||
[ run intrusive_ref_counter_test.cpp ]
|
||||
[ run atomic_count_test.cpp ]
|
||||
[ run lw_mutex_test.cpp ]
|
||||
[ compile-fail shared_ptr_assign_fail.cpp ]
|
||||
@@ -46,7 +47,7 @@ import testing ;
|
||||
[ run spinlock_pool_test.cpp ]
|
||||
[ run make_shared_test.cpp ]
|
||||
[ run make_shared_perfect_forwarding_test.cpp ]
|
||||
[ run sp_convertible_test.cpp ]
|
||||
[ run shared_ptr_convertible_test.cpp ]
|
||||
[ run wp_convertible_test.cpp ]
|
||||
[ run ip_convertible_test.cpp ]
|
||||
[ run allocate_shared_test.cpp ]
|
||||
@@ -60,6 +61,7 @@ import testing ;
|
||||
[ run sp_recursive_assign_rv_test.cpp ]
|
||||
[ run sp_recursive_assign2_rv_test.cpp ]
|
||||
[ run esft_constructor_test.cpp ]
|
||||
[ run enable_shared_from_raw_test.cpp ]
|
||||
[ compile-fail auto_ptr_lv_fail.cpp ]
|
||||
[ run atomic_count_test2.cpp ]
|
||||
[ run sp_typeinfo_test.cpp ]
|
||||
@@ -68,5 +70,98 @@ import testing ;
|
||||
[ run get_deleter_array_test.cpp ]
|
||||
[ run ip_hash_test.cpp ]
|
||||
[ run owner_less_test.cpp ]
|
||||
[ run sp_unique_ptr_test.cpp ]
|
||||
[ run sp_array_test.cpp ]
|
||||
[ compile sp_array_cv_test.cpp ]
|
||||
[ run sp_convertible_test.cpp ]
|
||||
[ run sp_array_n_test.cpp ]
|
||||
[ run sp_array_cast_test.cpp ]
|
||||
[ run sp_zero_compare_test.cpp ]
|
||||
[ run sp_nullptr_test.cpp ]
|
||||
[ 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 ]
|
||||
[ run sp_interlocked_test.cpp ]
|
||||
|
||||
[ compile-fail array_fail_spa_sp_c.cpp ]
|
||||
[ compile-fail array_fail_sp_spa_c.cpp ]
|
||||
[ compile-fail array_fail_spa_spa_c.cpp ]
|
||||
[ compile-fail array_fail_spa_wp_c.cpp ]
|
||||
[ compile-fail array_fail_sp_wpa_c.cpp ]
|
||||
[ compile-fail array_fail_spa_wpa_c.cpp ]
|
||||
[ compile-fail array_fail_wpa_wp_c.cpp ]
|
||||
[ compile-fail array_fail_wp_wpa_c.cpp ]
|
||||
[ compile-fail array_fail_wpa_wpa_c.cpp ]
|
||||
[ compile-fail array_fail_ap_spa_c.cpp ]
|
||||
[ compile-fail array_fail_upa_sp_c.cpp ]
|
||||
[ compile-fail array_fail_up_spa_c.cpp ]
|
||||
|
||||
[ compile-fail array_fail_spa_sp_mc.cpp ]
|
||||
[ compile-fail array_fail_sp_spa_mc.cpp ]
|
||||
[ compile-fail array_fail_spa_spa_mc.cpp ]
|
||||
[ compile-fail array_fail_spa_wp_mc.cpp ]
|
||||
[ compile-fail array_fail_sp_wpa_mc.cpp ]
|
||||
[ compile-fail array_fail_spa_wpa_mc.cpp ]
|
||||
[ compile-fail array_fail_wpa_wp_mc.cpp ]
|
||||
[ compile-fail array_fail_wp_wpa_mc.cpp ]
|
||||
[ compile-fail array_fail_wpa_wpa_mc.cpp ]
|
||||
[ compile-fail array_fail_ap_spa_mc.cpp ]
|
||||
[ compile-fail array_fail_upa_sp_mc.cpp ]
|
||||
[ compile-fail array_fail_up_spa_mc.cpp ]
|
||||
|
||||
[ compile-fail array_fail_spa_sp_a.cpp ]
|
||||
[ compile-fail array_fail_sp_spa_a.cpp ]
|
||||
[ compile-fail array_fail_spa_spa_a.cpp ]
|
||||
[ compile-fail array_fail_spa_wp_a.cpp ]
|
||||
[ compile-fail array_fail_sp_wpa_a.cpp ]
|
||||
[ compile-fail array_fail_spa_wpa_a.cpp ]
|
||||
[ compile-fail array_fail_wpa_wp_a.cpp ]
|
||||
[ compile-fail array_fail_wp_wpa_a.cpp ]
|
||||
[ compile-fail array_fail_wpa_wpa_a.cpp ]
|
||||
[ compile-fail array_fail_ap_spa_a.cpp ]
|
||||
[ compile-fail array_fail_upa_sp_a.cpp ]
|
||||
[ compile-fail array_fail_up_spa_a.cpp ]
|
||||
|
||||
[ compile-fail array_fail_spa_sp_ma.cpp ]
|
||||
[ compile-fail array_fail_sp_spa_ma.cpp ]
|
||||
[ compile-fail array_fail_spa_spa_ma.cpp ]
|
||||
[ compile-fail array_fail_spa_wp_ma.cpp ]
|
||||
[ compile-fail array_fail_sp_wpa_ma.cpp ]
|
||||
[ compile-fail array_fail_spa_wpa_ma.cpp ]
|
||||
[ compile-fail array_fail_wpa_wp_ma.cpp ]
|
||||
[ compile-fail array_fail_wp_wpa_ma.cpp ]
|
||||
[ compile-fail array_fail_wpa_wpa_ma.cpp ]
|
||||
[ compile-fail array_fail_ap_spa_ma.cpp ]
|
||||
[ compile-fail array_fail_upa_sp_ma.cpp ]
|
||||
[ compile-fail array_fail_up_spa_ma.cpp ]
|
||||
|
||||
[ compile-fail array_fail_dereference.cpp ]
|
||||
[ compile-fail array_fail_member_access.cpp ]
|
||||
[ compile-fail array_fail_array_access.cpp ]
|
||||
|
||||
[ run make_shared_array_test.cpp ]
|
||||
[ run make_shared_arrays_test.cpp : : : <toolset>gcc-4.6.3_0x:<cxxflags>-fno-deduce-init-list ]
|
||||
[ run make_shared_array_throws_test.cpp ]
|
||||
[ run make_shared_array_esft_test.cpp ]
|
||||
[ run make_shared_array_noinit_test.cpp ]
|
||||
[ run make_shared_array_value_test.cpp ]
|
||||
[ run allocate_shared_array_test.cpp ]
|
||||
[ run allocate_shared_arrays_test.cpp : : : <toolset>gcc-4.6.3_0x:<cxxflags>-fno-deduce-init-list ]
|
||||
[ run allocate_shared_array_throws_test.cpp ]
|
||||
[ run allocate_shared_array_esft_test.cpp ]
|
||||
[ run allocate_shared_array_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 ]
|
||||
;
|
||||
}
|
||||
|
241
test/allocate_shared_alloc11_test.cpp
Normal file
241
test/allocate_shared_alloc11_test.cpp
Normal 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
|
160
test/allocate_shared_array_construct_test.cpp
Normal file
160
test/allocate_shared_array_construct_test.cpp
Normal file
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
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
|
57
test/allocate_shared_array_esft_test.cpp
Normal file
57
test/allocate_shared_array_esft_test.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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/enable_shared_from_this.hpp>
|
||||
|
||||
class type
|
||||
: public boost::enable_shared_from_this<type> {
|
||||
public:
|
||||
static unsigned int instances;
|
||||
|
||||
explicit type() {
|
||||
instances++;
|
||||
}
|
||||
|
||||
~type() {
|
||||
instances--;
|
||||
}
|
||||
|
||||
private:
|
||||
type(const type&);
|
||||
type& operator=(const type&);
|
||||
};
|
||||
|
||||
unsigned int type::instances = 0;
|
||||
|
||||
int main() {
|
||||
BOOST_TEST(type::instances == 0);
|
||||
{
|
||||
boost::shared_ptr<type[]> a1 = boost::allocate_shared<type[]>(std::allocator<type>(), 3);
|
||||
try {
|
||||
a1[0].shared_from_this();
|
||||
BOOST_ERROR("shared_from_this did not throw");
|
||||
} catch (...) {
|
||||
BOOST_TEST(type::instances == 3);
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_TEST(type::instances == 0);
|
||||
{
|
||||
boost::shared_ptr<type[]> a1 = boost::allocate_shared_noinit<type[]>(std::allocator<type>(), 3);
|
||||
try {
|
||||
a1[0].shared_from_this();
|
||||
BOOST_ERROR("shared_from_this did not throw");
|
||||
} catch (...) {
|
||||
BOOST_TEST(type::instances == 3);
|
||||
}
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
181
test/allocate_shared_array_noinit_test.cpp
Normal file
181
test/allocate_shared_array_noinit_test.cpp
Normal 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();
|
||||
}
|
209
test/allocate_shared_array_test.cpp
Normal file
209
test/allocate_shared_array_test.cpp
Normal file
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
* 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<int[]>(std::allocator<int>(), 3);
|
||||
int* a2 = a1.get();
|
||||
BOOST_TEST(a1.use_count() == 1);
|
||||
BOOST_TEST(a2 != 0);
|
||||
BOOST_TEST(size_t(a2) % boost::alignment_of<int>::value == 0);
|
||||
BOOST_TEST(a1[0] == 0);
|
||||
BOOST_TEST(a1[1] == 0);
|
||||
BOOST_TEST(a1[2] == 0);
|
||||
}
|
||||
|
||||
{
|
||||
boost::shared_ptr<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);
|
||||
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[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::shared_ptr<type[]> a1 = boost::allocate_shared<type[]>(std::allocator<type>(), 3);
|
||||
type* a2 = a1.get();
|
||||
BOOST_TEST(a1.use_count() == 1);
|
||||
BOOST_TEST(a2 != 0);
|
||||
BOOST_TEST(size_t(a2) % boost::alignment_of<type>::value == 0);
|
||||
BOOST_TEST(type::instances == 3);
|
||||
boost::weak_ptr<type[]> w1 = a1;
|
||||
a1.reset();
|
||||
BOOST_TEST(type::instances == 0);
|
||||
}
|
||||
|
||||
BOOST_TEST(type::instances == 0);
|
||||
{
|
||||
boost::shared_ptr<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::shared_ptr<const type[]> a1 = boost::allocate_shared<const type[]>(std::allocator<type>(), 3);
|
||||
const type* a2 = a1.get();
|
||||
BOOST_TEST(a1.use_count() == 1);
|
||||
BOOST_TEST(a2 != 0);
|
||||
BOOST_TEST(size_t(a2) % boost::alignment_of<type>::value == 0);
|
||||
BOOST_TEST(type::instances == 3);
|
||||
a1.reset();
|
||||
BOOST_TEST(type::instances == 0);
|
||||
}
|
||||
|
||||
BOOST_TEST(type::instances == 0);
|
||||
{
|
||||
boost::shared_ptr<const type[3]> a1 = boost::allocate_shared<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<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<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();
|
||||
}
|
100
test/allocate_shared_array_throws_test.cpp
Normal file
100
test/allocate_shared_array_throws_test.cpp
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* 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>
|
||||
|
||||
class type {
|
||||
public:
|
||||
static unsigned int instances;
|
||||
|
||||
explicit type() {
|
||||
if (instances == 5) {
|
||||
throw true;
|
||||
}
|
||||
instances++;
|
||||
}
|
||||
|
||||
~type() {
|
||||
instances--;
|
||||
}
|
||||
|
||||
private:
|
||||
type(const type&);
|
||||
type& operator=(const type&);
|
||||
};
|
||||
|
||||
unsigned int type::instances = 0;
|
||||
|
||||
int main() {
|
||||
BOOST_TEST(type::instances == 0);
|
||||
try {
|
||||
boost::allocate_shared<type[]>(std::allocator<type>(), 6);
|
||||
BOOST_ERROR("allocate_shared did not throw");
|
||||
} catch (...) {
|
||||
BOOST_TEST(type::instances == 0);
|
||||
}
|
||||
|
||||
BOOST_TEST(type::instances == 0);
|
||||
try {
|
||||
boost::allocate_shared<type[][2]>(std::allocator<type>(), 3);
|
||||
BOOST_ERROR("allocate_shared did not throw");
|
||||
} catch (...) {
|
||||
BOOST_TEST(type::instances == 0);
|
||||
}
|
||||
|
||||
BOOST_TEST(type::instances == 0);
|
||||
try {
|
||||
boost::allocate_shared<type[6]>(std::allocator<type>());
|
||||
BOOST_ERROR("allocate_shared did not throw");
|
||||
} catch (...) {
|
||||
BOOST_TEST(type::instances == 0);
|
||||
}
|
||||
|
||||
BOOST_TEST(type::instances == 0);
|
||||
try {
|
||||
boost::allocate_shared<type[3][2]>(std::allocator<type>());
|
||||
BOOST_ERROR("allocate_shared did not throw");
|
||||
} catch (...) {
|
||||
BOOST_TEST(type::instances == 0);
|
||||
}
|
||||
|
||||
BOOST_TEST(type::instances == 0);
|
||||
try {
|
||||
boost::allocate_shared_noinit<type[]>(std::allocator<type>(), 6);
|
||||
BOOST_ERROR("allocate_shared_noinit did not throw");
|
||||
} catch (...) {
|
||||
BOOST_TEST(type::instances == 0);
|
||||
}
|
||||
|
||||
BOOST_TEST(type::instances == 0);
|
||||
try {
|
||||
boost::allocate_shared_noinit<type[][2]>(std::allocator<type>(), 3);
|
||||
BOOST_ERROR("allocate_shared_noinit did not throw");
|
||||
} catch (...) {
|
||||
BOOST_TEST(type::instances == 0);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
46
test/allocate_shared_array_value_test.cpp
Normal file
46
test/allocate_shared_array_value_test.cpp
Normal 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();
|
||||
}
|
48
test/allocate_shared_arrays_test.cpp
Normal file
48
test/allocate_shared_arrays_test.cpp
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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() {
|
||||
#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
|
||||
{
|
||||
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>(), { 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<const int[][2]> a1 = boost::allocate_shared<const 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<const int[2][2]> a1 = boost::allocate_shared<const 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);
|
||||
}
|
||||
#endif
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
240
test/allocate_shared_construct11_test.cpp
Normal file
240
test/allocate_shared_construct11_test.cpp
Normal 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
|
20
test/array_fail_ap_spa_a.cpp
Normal file
20
test/array_fail_ap_spa_a.cpp
Normal file
@@ -0,0 +1,20 @@
|
||||
//
|
||||
// Copyright (c) 2012 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <memory>
|
||||
|
||||
struct X
|
||||
{
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
std::auto_ptr<X> px;
|
||||
boost::shared_ptr<X[]> px2; px2 = px;
|
||||
}
|
20
test/array_fail_ap_spa_c.cpp
Normal file
20
test/array_fail_ap_spa_c.cpp
Normal file
@@ -0,0 +1,20 @@
|
||||
//
|
||||
// Copyright (c) 2012 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
//
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <memory>
|
||||
|
||||
struct X
|
||||
{
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
std::auto_ptr<X> px;
|
||||
boost::shared_ptr<X[]> px2( px );
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user