Compare commits

...

458 Commits

Author SHA1 Message Date
Glen Fernandes
0bab2cc658 Rename member because _CRTDBG_MAP_ALLOC in VS does not allow it
_CRTDBG_MAP_ALLOC has issues with member functions named "free".
2014-07-25 23:44:34 -07:00
Peter Dimov
d28b0d07fc Revert "Fix warnings on gcc 4.4"
This reverts commit b1beb11a45.
2014-07-16 15:24:17 +03:00
Peter Dimov
1c83d65701 Merge branch 'develop' 2014-07-15 13:06:44 +03:00
Peter Dimov
1d41a328f7 Merge pull request #5 from Lastique/patch-2
Fix warnings on gcc 4.4
2014-07-15 12:30:54 +03:00
Andrey Semashev
b1beb11a45 Fix warnings on gcc 4.4
Added a special version of sp_forward for an outdated version of rvalue references supported by gcc 4.4. The compiler would create a temporary and return an rvalue reference to it in the original code. This resulted in warnings about 'returning reference to temporary'.

The added version is similar to std::forward on that compiler, except it doesn't prohibit template argument deduction (which is in line with the original sp_forward).
2014-07-14 22:33:16 +04:00
Peter Dimov
bf3e9cc7af -Wshadow fixes. 2014-07-12 20:35:14 +03:00
Peter Dimov
506239bef5 Merge branch 'develop' 2014-06-11 22:30:00 +03:00
Peter Dimov
d6841e6d71 Remove trailing whitespace. 2014-06-11 22:29:15 +03:00
Peter Dimov
56ae9f86c1 Merge pull request #4 from stgates/winrt
[winrt support] Replacing banned APIs Sleep and InitializeCriticalSection
2014-06-11 22:12:25 +03:00
Steve Gates
1a74757cfa Adding missing include for boost\predef.h. 2014-06-11 11:44:25 -07:00
Steve Gates
07e222217b Updating to use BOOST_PLAT_WINDOWS_RUNTIME based on review feedback. 2014-06-11 11:33:03 -07:00
Steve Gates
71c9165119 Replacing banned APIs Sleep and InitializeCriticalSection for Windows store and phone. 2014-06-10 22:07:51 -07:00
Peter Dimov
f32669400c Remove headers moved into core. 2014-06-03 20:25:38 +03:00
Peter Dimov
b550e028f5 Move boost/memory_order.hpp to Boost.Atomic 2014-05-20 23:33:03 +03:00
Peter Dimov
ed2eaddc5d Check BOOST_NO_CXX11_RVALUE_REFERENCES in tests that use std::unique_ptr. 2014-05-15 18:51:27 +03:00
Glen Fernandes
d523c3423e Use Boost.Align for alignment 2014-05-04 08:20:37 -07:00
Glen Fernandes
1968d17d2f Use add_rvalue_reference in make_unique overload 2014-03-12 20:27:36 -07:00
Glen Fernandes
e1e99c5ba3 Merge pull request #3 from Lastique/patch-1
Fix warnings about struct/class mismatch
2014-03-08 10:36:20 -08:00
Andrey Semashev
d586469d60 Fix warnings about struct/class mismatch
ms_allocator_state template was declared as class but its specializations were as structs. This caused Clang 3.2 warnings. The commit changes ms_allocator_state declaration to struct to fix that.
2014-03-08 18:31:31 +03:00
Peter Dimov
fbb851097f Disable the std::atomic spinlock implementation on Clang 2014-03-01 02:14:56 +02:00
Glen Fernandes
75add10b1d Simplify ms_allocator and as_allocator design 2014-02-28 10:19:50 -08:00
Peter Dimov
71b2f87e35 Merge branch 'develop' 2014-02-26 15:10:01 +02:00
Peter Dimov
c759321782 Remove interlocked.hpp, was left behind by the merge 2014-02-26 14:57:59 +02:00
Peter Dimov
3e625c07e8 Switch to sp_interlocked.hpp 2014-02-25 01:32:19 +02:00
Peter Dimov
7ff1c65494 Merge branch 'develop' 2014-02-24 20:34:18 +02:00
Glen Fernandes
75cab39801 Drop the BOOST_NO_CXX11_STD_ALIGN-undefined path
Until the merge of Boost.Config develop to master
2014-02-24 08:35:59 -08:00
Glen Fernandes
38cb523713 Derive empty base optimization from rebound allocator 2014-02-18 00:16:57 -08:00
Glen Fernandes
5f1d4eae4f Factor out alignment code into sp_align 2014-02-16 12:15:29 -08:00
Glen Fernandes
adc0cdddff Make as_allocator::deallocate consistent 2014-02-14 18:31:52 -08:00
Peter Dimov
dcfa031de7 Do not include sp_interlocked.hpp when not on Windows 2014-02-13 12:51:23 +02:00
Glen Fernandes
8c9e8b5556 Further simplification of ms_allocator 2014-02-12 22:15:15 -08:00
Glen Fernandes
d9333e5375 Simplify array_allocator; update documentation 2014-02-12 19:34:56 -08:00
Glen Fernandes
3d279e6c6d Save additional sizeof(void*) bytes for arrays 2014-02-12 13:52:58 -08:00
Peter Dimov
c003fba3a0 Renamed, cleaned up interlocked.hpp; added test 2014-02-12 20:48:35 +02:00
Peter Dimov
0c29e86728 Add spinlock_std_atomic.hpp 2014-02-12 20:20:56 +02:00
Glen Fernandes
016af907bd Make sp_counted_impl_ specialization more generic 2014-02-12 08:46:59 -08:00
Peter Dimov
0337743c8c Revert "Remove obsolete MSVC check from pragma guard"
This reverts commit b7ee788845.
2014-02-12 16:57:45 +02:00
Peter Dimov
208bfd78f9 Move interlocked.hpp to smart_ptr/detail 2014-02-12 16:42:24 +02:00
Peter Dimov
2c32bf91b7 Add BOOST_USE_INTRIN_H support; remove #pragma intrinsic, not needed and not supported on Intel.
[SVN r85994]
2014-02-12 16:41:23 +02:00
Stephen Kelly
b7ee788845 Remove obsolete MSVC check from pragma guard
git grep -h -B1 "^#\s*pragma once" | grep -v pragma | sort | uniq

is now clean.

[SVN r85952]
2014-02-12 16:41:22 +02:00
Andrey Semashev
a56378ee35 Enabled #pragma once for all compilers that support it, not only MSVC.
[SVN r85866]
2014-02-12 16:41:22 +02:00
Andrey Semashev
443302306e Fixed compilation problems with MinGW-w64.
[SVN r85865]
2014-02-12 16:41:21 +02:00
Peter Dimov
f5402a937e Fix the _WIN32_WCE >= 0x600 case.
[SVN r80935]
2014-02-12 16:41:21 +02:00
Jürgen Hunold
fe04bea979 Fix: intrin.h is available in msvc-9.0 (_MSC_VER 1500)
[SVN r80626]
2014-02-12 16:41:21 +02:00
Vicente J. Botet Escriba
8fbb5e9e7f Thread: Try again to fix 5431
[SVN r80127]
2014-02-12 16:41:20 +02:00
Vicente J. Botet Escriba
0401afc106 Thread: Rollback last modification as it breaks regression test VeecoFTC/msvc-9.0~wm5~stlport5.2
[SVN r80067]
2014-02-12 16:41:20 +02:00
Vicente J. Botet Escriba
b69ca7aaa5 Thread: Try to fix 5431
[SVN r80042]
2014-02-12 16:41:19 +02:00
Peter Dimov
dffbf7c931 Use <intrin.h> for VS2010+. Refs #4678.
[SVN r75396]
2014-02-12 16:41:19 +02:00
Anthony Williams
5dabdf635c Applied patch from issue #4849
[SVN r70383]
2014-02-12 16:41:19 +02:00
Anthony Williams
3dbde36076 Applied patch from issue #3377
[SVN r62509]
2014-02-12 16:41:18 +02:00
Peter Dimov
97a9aac5f0 Fix interlocked.hpp to compile under /clr:pure. Refs #3378.
[SVN r57958]
2014-02-12 16:41:17 +02:00
Peter Dimov
bd5b684fd3 Move smart_ptr into boost/smart_ptr/*.hpp (refs #2239).
[SVN r51509]
2014-02-12 16:41:17 +02:00
Peter Dimov
6ede4ec4c6 Factored out boost/detail/lightweight_thread.hpp.
[SVN r44638]
2014-02-12 16:41:16 +02:00
Peter Dimov
aab1328e06 spinlock_nt.hpp added, Cygwin fixes.
[SVN r44055]
2014-02-12 16:41:16 +02:00
Anthony Williams
451c71c1bd Added changes from David Deakins to enable compilation on Windows CE
[SVN r40679]
2014-02-12 16:41:16 +02:00
Peter Dimov
6341b8802a Windows CE patch by Michael Fink
[SVN r33986]
2014-02-12 16:41:15 +02:00
Anthony Williams
e274885fd2 Win32 implementation of boost::timed_mutex
[SVN r33272]
2014-02-12 16:41:15 +02:00
Peter Dimov
82fe5f5095 Fixed a couple of syntax errors (reported by Juergen Hunold)
[SVN r31946]
2014-02-12 16:41:14 +02:00
Peter Dimov
8c50214e3f Fixed bug #1370716, static shared_ptr instances not working w/ quick_allocator
[SVN r31931]
2014-02-12 16:41:14 +02:00
Anthony Williams
21198d07fd Moved BOOST_INTERLOCKED_READ stuff into its own header
[SVN r31098]
2014-02-12 16:41:14 +02:00
Anthony Williams
b4c8cf3958 Removed :: qualification on _Interlocked functions
[SVN r31097]
2014-02-12 16:41:13 +02:00
Anthony Williams
77aeaee7a7 Added BOOST_INTERLOCKED_EXCHANGE_POINTER in all branches of the #if
[SVN r31012]
2014-02-12 16:41:13 +02:00
Anthony Williams
677a0777d2 Added InterlockedExchangePointer
[SVN r31010]
2014-02-12 16:41:12 +02:00
Anthony Williams
7c7250379b InterlockedCompareExchangePointer is only intrinsic on 64 bit platforms, otherwise it's just a synonym for InterlockedCompareExchange
[SVN r30951]
2014-02-12 16:41:12 +02:00
Anthony Williams
142eb95986 Added interlocked compare/exchange for pointers, and interlocked_read for values and pointers
[SVN r30941]
2014-02-12 16:41:11 +02:00
Anthony Williams
d9f24f882e New version of call_once for win32
[SVN r30847]
2014-02-12 16:41:11 +02:00
Peter Dimov
0fd3947e19 <intrin.h> appears broken.
[SVN r27737]
2014-02-12 16:41:10 +02:00
Peter Dimov
43bc30e576 Split sp_counted_base into no threads (nt), win32 lock-free (w32) and pthreads (pt)
[SVN r27729]
2014-02-12 16:41:10 +02:00
Douglas Gregor
e0ec2a0aaa Converted to Boost Software License, Version 1.0
[SVN r24055]
2014-02-12 16:41:10 +02:00
Peter Dimov
5320981cbb _MSC_VER use clarified.
[SVN r20992]
2014-02-12 16:41:09 +02:00
Peter Dimov
d676bac36a -Wundef fixes.
[SVN r18788]
2014-02-12 16:41:09 +02:00
Peter Dimov
ec1c6ed414 Fixes for Comeau with Borland as backend.
[SVN r17588]
2014-02-12 16:41:08 +02:00
Peter Dimov
ce36b11fd5 Made the default page size 512 (g++ 2.96 on Red Hat 7.2 dislikes 496.)
[SVN r17272]
2014-02-12 16:41:08 +02:00
Peter Dimov
eee70bdcab Added BOOST_QA_PAGE_SIZE.
[SVN r17270]
2014-02-12 16:41:07 +02:00
Peter Dimov
97eed20d9b Quick_allocator updates.
[SVN r17267]
2014-02-12 16:41:07 +02:00
Peter Dimov
6b6b63ef37 Dave's quick_allocator added, #define BOOST_SP_USE_QUICK_ALLOCATOR to make shared_ptr use it.
[SVN r17087]
2014-02-12 16:41:07 +02:00
Peter Dimov
1bdabdb96b Move interlocked.hpp to smart_ptr/detail 2014-02-12 16:39:56 +02:00
Peter Dimov
0876e67ac7 Merged revision(s) 85994 from trunk: Add BOOST_USE_INTRIN_H support; remove #pragma intrinsic, not needed and not supported on Intel. Refs #6646. Refs #7318. Refs #9174.
[SVN r86416]
2014-02-12 16:37:26 +02:00
Andrey Semashev
fdcb2572a3 Merged latest changes from trunk.
[SVN r85988]
2014-02-12 16:37:26 +02:00
Peter Dimov
71d99e89e9 Merged revision(s) [80935] from trunk: Fix the _WIN32_WCE >= 0x600 case.
[SVN r80960]
2014-02-12 16:37:25 +02:00
Vicente J. Botet Escriba
2dc506f4bc Thread: Updated from trunk 1.52
[SVN r80473]
2014-02-12 16:37:25 +02:00
Peter Dimov
7161dc5842 Merge [75396] to release. Fixes #4678.
[SVN r75757]
2014-02-12 16:37:25 +02:00
Anthony Williams
ec97270c01 Merged fix for issue #4849 from trunk (fix boost.thread on mingw64) (authorized by rene)
[SVN r72657]
2014-02-12 16:37:24 +02:00
Peter Dimov
b7a759f00f Merge [57958] to release. Fixes #3378.
[SVN r58069]
2014-02-12 16:37:24 +02:00
Peter Dimov
4f2392ffa5 Merge [51509], [51519] to release. Closes #2239.
[SVN r51531]
2014-02-12 16:37:23 +02:00
Peter Dimov
80a06c8883 Merged 44595, 44638, 44707, 44711, 44728 from trunk to release
[SVN r47341]
2014-02-12 16:37:23 +02:00
Peter Dimov
d0a458616f Merged 43316, 43317, 43318, 43733, 43782, 43873, 43888, 43916, 43950, 44055, 44056, 44058, 44073, 44074, 44132, 44137, 44138, 44140, 44344 from trunk to release
[SVN r47339]
2014-02-12 16:37:21 +02:00
Beman Dawes
def81b1941 config, detail, filesystem, system, tools, at 41278.
[SVN r41316]
2014-02-12 16:37:21 +02:00
Peter Dimov
4f276715ce Windows CE patch by Michael Fink
[SVN r33986]
2014-02-12 16:37:20 +02:00
Anthony Williams
a47bbfe95c Win32 implementation of boost::timed_mutex
[SVN r33272]
2014-02-12 16:37:20 +02:00
Peter Dimov
90fe855f1b Fixed a couple of syntax errors (reported by Juergen Hunold)
[SVN r31946]
2014-02-12 16:37:20 +02:00
Peter Dimov
991436303d Fixed bug #1370716, static shared_ptr instances not working w/ quick_allocator
[SVN r31931]
2014-02-12 16:37:19 +02:00
Anthony Williams
b274ed4cc3 Moved BOOST_INTERLOCKED_READ stuff into its own header
[SVN r31098]
2014-02-12 16:37:18 +02:00
Anthony Williams
870a989fcf Removed :: qualification on _Interlocked functions
[SVN r31097]
2014-02-12 16:37:18 +02:00
Anthony Williams
5f7a5a5912 Added BOOST_INTERLOCKED_EXCHANGE_POINTER in all branches of the #if
[SVN r31012]
2014-02-12 16:37:17 +02:00
Anthony Williams
82db88f4fa Added InterlockedExchangePointer
[SVN r31010]
2014-02-12 16:37:17 +02:00
Anthony Williams
c8df85434e InterlockedCompareExchangePointer is only intrinsic on 64 bit platforms, otherwise it's just a synonym for InterlockedCompareExchange
[SVN r30951]
2014-02-12 16:37:16 +02:00
Anthony Williams
68517b43bd Added interlocked compare/exchange for pointers, and interlocked_read for values and pointers
[SVN r30941]
2014-02-12 16:37:16 +02:00
Anthony Williams
72ac0e8bfd New version of call_once for win32
[SVN r30847]
2014-02-12 16:37:15 +02:00
Peter Dimov
6c7578e206 <intrin.h> appears broken.
[SVN r27737]
2014-02-12 16:37:15 +02:00
Peter Dimov
3149446fe8 Split sp_counted_base into no threads (nt), win32 lock-free (w32) and pthreads (pt)
[SVN r27729]
2014-02-12 16:37:14 +02:00
Douglas Gregor
b11d734f73 Converted to Boost Software License, Version 1.0
[SVN r24055]
2014-02-12 16:37:14 +02:00
Peter Dimov
6f5f8babf4 _MSC_VER use clarified.
[SVN r20992]
2014-02-12 16:37:13 +02:00
Peter Dimov
7d7f32c3a9 -Wundef fixes.
[SVN r18788]
2014-02-12 16:37:13 +02:00
Peter Dimov
cb697fe9cb Fixes for Comeau with Borland as backend.
[SVN r17588]
2014-02-12 16:37:12 +02:00
Peter Dimov
8422135bf2 Made the default page size 512 (g++ 2.96 on Red Hat 7.2 dislikes 496.)
[SVN r17272]
2014-02-12 16:37:12 +02:00
Peter Dimov
fd60899dfb Added BOOST_QA_PAGE_SIZE.
[SVN r17270]
2014-02-12 16:37:12 +02:00
Peter Dimov
a11ab16010 Quick_allocator updates.
[SVN r17267]
2014-02-12 16:37:11 +02:00
Peter Dimov
9b9cad3f5b Dave's quick_allocator added, #define BOOST_SP_USE_QUICK_ALLOCATOR to make shared_ptr use it.
[SVN r17087]
2014-02-12 16:37:11 +02:00
Glen Fernandes
7ce5b6b2a9 Fix use of ms_init in no C++11 allocator case 2014-02-11 08:39:52 -08:00
Glen Fernandes
7e3ae44bc2 Fix use of size in make_shared for arrays 2014-02-10 21:09:13 -08:00
Glen Fernandes
57dc400fbf Cosmetic changes in make_shared and make_unique 2014-02-10 21:04:41 -08:00
Glen Fernandes
5f485c2952 Spatial optimization for make_shared for arrays
Saves up to sizeof(void*) + sizeof(size_t) bytes for make_shared and saves
sizeof(void*) + sizeof(size_t) + sizeof(A) bytes for allocate_shared where A is the
supplied allocator type.
2014-02-10 20:54:48 -08:00
Peter Dimov
260af64027 Merge branch 'develop' 2014-02-11 01:29:29 +02:00
Peter Dimov
f837c7f56c Revert "Merge from branch 'develop' into 'master'"
This reverts commit 83b3b703e0.
2014-02-11 01:29:02 +02:00
Glen Fernandes
54fb49a5be Use typedef A1 (warnings about unused typedefs) 2014-02-09 11:27:22 -08:00
Glen Fernandes
c23bd41c44 Refactor make_shared for arrays
Refactor implementation to later simplify making an optimization [for the C++11
allocator case] for when sp_counted_impl_pda destruction invokes the
allocator's destroy function instead of the type's destructor.
2014-02-07 08:03:47 -08:00
Peter Dimov
a64cc5c41c Use allocator)traits<>::destroy in sp_counted_impl_pda::destroy 2014-02-07 17:37:00 +02:00
Glen Fernandes
e1f170cd49 Drop variadic templates in unit test for VC11 2014-02-06 17:09:27 -08:00
Glen Fernandes
52a5c422a1 Correct typo in shared_array documentation 2014-02-06 01:40:46 -08:00
Glen Fernandes
d46e3c7cbd Simplify/tidy array_allocator and array_deleter 2014-02-06 01:38:58 -08:00
Glen Fernandes
5008957bd0 Remove type2 tests in a_s_construct_test 2014-02-05 09:10:45 -08:00
Glen Fernandes
6d73b4aa54 Work around VC11 which has broken rebind_traits
VC11 has only partial support for C++11 allocators. For example it has a
non-conforming rebind_alloc and rebind_traits in std::allocator_traits
because it does not support C++11 template aliases.
2014-02-04 23:56:34 -08:00
Glen Fernandes
540149f019 Tidy documentation in smart_ptr 2014-02-04 22:45:58 -08:00
Peter Dimov
9f5822f427 Add support and test for C++11 construct/destroy in allocate_shared 2014-02-05 02:31:33 +02:00
Peter Dimov
d229ae870c Subsume zero-argument overload into the variadic one 2014-02-05 01:04:20 +02:00
Glen Fernandes
3ac6dbbf08 Make detail::as_allocator template C++11 friendly 2014-02-04 15:00:24 -08:00
Peter Dimov
af5141d492 Merge commit 2014-02-05 00:32:36 +02:00
Peter Dimov
975d04ac62 Merge Jamfile.v2 on git's insistence 2014-02-05 00:29:18 +02:00
Peter Dimov
90e74511f7 Add support and tests for C++11 minimal allocators 2014-02-05 00:17:34 +02:00
Glen Fernandes
f27b780724 Add unit test for allocate_shared construct case 2014-02-04 13:17:49 -08:00
Glen Fernandes
51ab46a07d Fix use of rebind_traits and rebind_alloc 2014-02-04 12:42:10 -08:00
Glen Fernandes
e8595a05af Fix use of rebind_traits and rebind_alloc 2014-02-04 08:43:36 -08:00
Glen Fernandes
154a274916 Update make_shared for arrays to address 2070
This updates make_shared and allocate_shared for arrays in accordance with
report 2070 which requires that allocator_traits<A2>::construct(a2, ptr,
...) is used for construction and allocator_traits<A2>::destroy(a2, ptr)
is used for destruction instead of placement new and destructor
invocation.
2014-02-04 04:46:03 -08:00
Glen Fernandes
2b033ce05d Improve documentation for make_shared for arrays 2014-02-03 16:42:57 -08:00
Glen Fernandes
63a05a3576 Refactor make_array_helper and array_deleter
Reduce the amount of code in allocate_array_helper, make_array_helper, and
array_deleter using the empty base class optimization technique.
2014-02-03 07:28:01 -08:00
Glen Fernandes
aede0039bf make_unique tests run only for C++11 compilers 2014-01-31 11:01:37 -08:00
Glen Fernandes
72e5fb6fd7 Add fourth form of make_unique for objects
To support initialization syntax that Args&&... cannot forward perfectly.
2014-01-29 17:16:01 -08:00
Glen Fernandes
f91e7e9ce7 Minor documentation corrections 2014-01-29 09:15:47 -08:00
Glen Fernandes
7fef3bb40b Add top-level make_unique.hpp and documentation 2014-01-29 07:25:30 -08:00
Glen Fernandes
ad658fa5ec Update make shared for arrays documentation 2014-01-29 05:49:07 -08:00
Glen Fernandes
83b3b703e0 Merge from branch 'develop' into 'master'
1. Update make_shared for arrays to conform to N3870

Merging 630e4f49f3^..87e5debdc2 from develop to master
2014-01-28 11:28:54 -08:00
Glen Fernandes
7806737b52 Add make_unique for arrays and objects 2014-01-28 03:58:51 -08:00
Glen Fernandes
87e5debdc2 Minor cosmetic changes in make_shared for arrays 2014-01-28 03:40:54 -08:00
Glen Fernandes
db78d9b2be Update make_shared for arrays documentation 2014-01-23 21:16:51 -08:00
Glen Fernandes
630e4f49f3 Update make_shared for arrays to conform to N3870
Update make_shared and allocate_shared for arrays to be confined to the
set of overloads specified in N3870.
2014-01-23 20:40:46 -08:00
Peter Dimov
a68db557e8 Deboldify, clean up intrusive_ptr.html. 2013-12-26 19:05:54 +02:00
Peter Dimov
4de3f36839 Add add_ref parameter to intrusive_ptr::reset, add tests for reset. 2013-12-26 18:47:05 +02:00
Peter Dimov
4e46cb0609 Add one more intrusive_ptr test case. 2013-12-26 18:05:52 +02:00
Avi Kivity
73153d5797 Add intrusive_ptr<>::detach()
This provides a way to escape from automatic reference counting, and taking
manual control of the reference.  Useful when interfacing to a C API that
expects a pointer with an elevated reference count.

Similar to std::unique_ptr<>::release().
2013-12-26 17:47:28 +02:00
Peter Dimov
d7fa365843 Remove obsolete _nmt headers. 2013-12-14 00:15:51 +02:00
Peter Dimov
6e0ee30543 Update atomic_count.hpp to match sp_counted_base.hpp. 2013-12-14 00:01:01 +02:00
Peter Dimov
fed15ad8c5 Add support for BOOST_SP_USE_STD_ATOMIC 2013-12-13 22:58:09 +02:00
Peter Dimov
bba3b446bd Check return values of pthread_* calls with BOOST_VERIFY, per #8898 2013-12-12 02:36:33 +02:00
Peter Dimov
4c8a558982 Check return values of pthread_* calls with BOOST_VERIFY, per #8904. 2013-12-12 01:42:16 +02:00
Peter Dimov
a41b81f1c8 Added shared_array constructor from nullptr, per #8894. 2013-12-12 01:22:51 +02:00
Peter Dimov
c103ace77a Merge branch 'master' into develop 2013-12-11 22:53:48 +02:00
Peter Dimov
04f456f86d Merge pull request #1 from RhysU/patch-1
Spelling: simultaneosly -> simultaneously
2013-12-11 11:01:56 -08:00
Rhys Ulerich
3a188af8d6 Spelling: simultaneosly -> simultaneously 2013-12-10 22:09:48 -06:00
Peter Dimov
b701ed0225 Merge branch 'develop' 2013-12-07 19:37:54 +02:00
Peter Dimov
5e9bb19688 Merge branch 'master' into develop 2013-12-07 19:26:28 +02:00
Peter Dimov
a4f853bfbc Revert "SmartPtr: Remove obsolete MSVC version checks."
This reverts commit 7d1c527ac0.
2013-12-07 19:25:05 +02:00
Peter Dimov
832ed079b9 Revert "Revert MSC_VER changes."
This reverts commit 382fb54a52.
2013-12-07 19:24:44 +02:00
Peter Dimov
d9b29beebe Revert "Remove obsolete MSVC check from pragma guard"
This reverts commit e4f24e4d3d.
2013-12-07 19:22:43 +02:00
Peter Dimov
182452e057 Revert "Remove use of obsolete BOOST_NO_TEMPLATED_STREAMS macro."
This reverts commit 14be9eb90f.
2013-12-07 19:21:31 +02:00
Peter Dimov
5f69684c8f Revert "SmartPointer: Remove obsolete GCC version checks."
This reverts commit 0e6ddb843e.
2013-12-07 19:21:06 +02:00
Peter Dimov
70ffd2921f Revert "Remove BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION"
This reverts commit 8767b9580e.
2013-12-07 19:20:36 +02:00
Peter Dimov
00aee2c7dc Revert "Simplify multi-component ifdefs containing BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION"
This reverts commit f5e6e4063e.
2013-12-07 19:20:12 +02:00
Peter Dimov
85d8056368 Revert "Remove remaining occurances of BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION"
This reverts commit 56b0853887.
2013-12-07 19:19:46 +02:00
Michel Morin
106832df66 Merge r86524 (Correct broken links to C++ standard papers); fixes #9212
[SVN r86673]
2013-11-13 03:22:55 +00:00
Michel Morin
2549b818c5 Correct broken links to C++ standard papers. Refs #9212.
[SVN r86524]
2013-10-30 12:51:24 +00:00
Peter Dimov
be06392771 Merged revision(s) 85995 from trunk: Remove #pragma intrinsic( _mm_pause ); not needed, not supported on Intel. Closes #6646, #7318.
[SVN r86417]
2013-10-24 14:05:26 +00:00
Stephen Kelly
56b0853887 Remove remaining occurances of BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
These evaded scripting.

[SVN r86249]
2013-10-11 23:22:36 +00:00
Stephen Kelly
f5e6e4063e Simplify multi-component ifdefs containing BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
[SVN r86248]
2013-10-11 23:20:59 +00:00
Stephen Kelly
8767b9580e Remove BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
Process #ifndef...#endif conditions.

[SVN r86244]
2013-10-11 23:15:00 +00:00
Stephen Kelly
0e6ddb843e SmartPointer: Remove obsolete GCC version checks.
[SVN r86063]
2013-09-30 15:57:14 +00:00
Stephen Kelly
14be9eb90f Remove use of obsolete BOOST_NO_TEMPLATED_STREAMS macro.
It was only defined for no-longer-supported-gcc.

[SVN r86062]
2013-09-30 15:56:52 +00:00
Peter Dimov
fa91b7d020 Remove #pragma intrinsic( _mm_pause ); not needed, not supported on Intel. Refs #6646, #7318.
[SVN r85995]
2013-09-29 11:31:17 +00:00
Peter Dimov
382fb54a52 Revert MSC_VER changes.
[SVN r85993]
2013-09-29 10:43:15 +00:00
Stephen Kelly
e4f24e4d3d Remove obsolete MSVC check from pragma guard
git grep -h -B1 "^#\s*pragma once" | grep -v pragma | sort | uniq

is now clean.

[SVN r85952]
2013-09-26 13:02:51 +00:00
Stephen Kelly
7d1c527ac0 SmartPtr: Remove obsolete MSVC version checks.
[SVN r85929]
2013-09-26 09:39:50 +00:00
Andrey Semashev
fc20a29c99 Merged changes from trunk: added intrusive_ref_counter.
[SVN r85609]
2013-09-08 17:17:18 +00:00
Andrey Semashev
0dc1faa6d3 Disabled bogus MSVC warning.
[SVN r85575]
2013-09-05 17:23:33 +00:00
Andrey Semashev
7b9354fcf3 Changed intrusive_ref_counter to follow CRTP design.
[SVN r85547]
2013-09-01 21:05:14 +00:00
Andrey Semashev
a7d96b4762 Extracted intrusive_ref_counter from Boost.Log. The extracted version supports customizing the reference counter nature, two policies provided: thread_unsafe_counter and thread_safe_counter.
[SVN r85535]
2013-08-31 19:54:11 +00:00
Peter Dimov
6eefc6bf81 Merge [84506] from trunk: Document that constructors initialize enable_shared_from_this. Fixes #8573.
[SVN r84507]
2013-05-26 13:39:04 +00:00
Peter Dimov
172afff6ca Document that constructors initialize enable_shared_from_this. Refs #8573.
[SVN r84506]
2013-05-26 13:34:40 +00:00
Peter Dimov
9355404d10 Merged revision(s) 83914 from trunk:
Fix new double(n) to new double[n].

[SVN r83915]
2013-04-15 15:13:20 +00:00
Peter Dimov
d61e675caf Fix new double(n) to new double[n].
[SVN r83914]
2013-04-15 15:11:29 +00:00
Glen Fernandes
240c66e633 Merge revision(s) 83829 from trunk:
More small cosmetic documentation changes.
........

[SVN r83830]
2013-04-10 05:17:32 +00:00
Glen Fernandes
6df3a0295e More small cosmetic documentation changes.
[SVN r83829]
2013-04-10 05:16:09 +00:00
Glen Fernandes
e497aec58a Merge revision(s) 83827 from trunk:
Small improvements to make_shared documentation.
........


[SVN r83828]
2013-04-10 05:03:45 +00:00
Glen Fernandes
2d56e85174 Small improvements to make_shared documentation.
[SVN r83827]
2013-04-10 05:00:52 +00:00
Peter Dimov
579b347267 Merged revision(s) 83198 from trunk: Avoid stack overflow in make_shared. Fixes #4256. Fixes #7965.
[SVN r83341]
2013-03-07 08:18:48 +00:00
Peter Dimov
82e178f043 Avoid stack overflow in make_shared. Refs #4256.
[SVN r83198]
2013-02-28 08:02:09 +00:00
Glen Fernandes
3178d38137 Merge revision 82971 from trunk:
Identifier renaming in allocate_array_helper, array_deleter, make_array_helper
function parameters to satisfy higher warning levels.
........


[SVN r82976]
2013-02-18 18:04:48 +00:00
Glen Fernandes
46d119c385 Identifier renaming in allocate_array_helper, array_deleter, make_array_helper
function parameters to satisfy higher warning levels.

[SVN r82971]
2013-02-18 09:33:18 +00:00
Peter Dimov
e39fcad839 Merged revision(s) 82927 from trunk: Check for BOOST_NO_CXX11_RVALUE_REFERENCES in addition to BOOST_NO_CXX11_SMART_PTR. Fixes #8055.
[SVN r82928]
2013-02-16 17:21:23 +00:00
Peter Dimov
e5950adc43 Check for BOOST_NO_CXX11_RVALUE_REFERENCES in addition to BOOST_NO_CXX11_SMART_PTR. Refs #8055.
[SVN r82927]
2013-02-16 17:18:17 +00:00
Glen Fernandes
de6dc3a26e Merge documentation fix from trunk
[SVN r82575]
2013-01-21 04:36:14 +00:00
Glen Fernandes
06c4dacaf2 Correct link in documentation
[SVN r82552]
2013-01-20 00:09:27 +00:00
Glen Fernandes
72095a4804 Merge revision 82408 from trunk:
Support BOOST_NO_EXCEPTIONS in detail/array_utility.hpp to allow use when exceptions are disabled
........


[SVN r82432]
2013-01-10 16:50:34 +00:00
Peter Dimov
dcc1713c59 Merged revision(s) 82351 from trunk: Replace std::nullptr_t with boost::detail::sp_nullptr_t.
[SVN r82427]
2013-01-09 23:41:31 +00:00
Glen Fernandes
32a28ec462 Support BOOST_NO_EXCEPTIONS in detail/array_utility.hpp to allow use when exceptions are disabled
[SVN r82408]
2013-01-08 21:39:54 +00:00
Peter Dimov
f6d5257597 Merged revision(s) 82349 from trunk: Update documentation for nullptr, owner_before, explicit operator bool.
[SVN r82357]
2013-01-04 18:44:47 +00:00
Peter Dimov
ef817e91d2 Replace std::nullptr_t with boost::detail::sp_nullptr_t.
[SVN r82351]
2013-01-04 15:41:13 +00:00
Peter Dimov
43b43aa83a Update documentation for nullptr, owner_before, explicit operator bool.
[SVN r82349]
2013-01-04 14:26:56 +00:00
Peter Dimov
d3a549e93a Merged revision(s) 82188 from trunk: Untabify.
[SVN r82189]
2012-12-23 16:07:27 +00:00
Peter Dimov
e8be24c003 Untabify.
[SVN r82188]
2012-12-23 16:05:00 +00:00
Glen Fernandes
c55ffa1cab Merge Jamfile.v2 from trunk
[SVN r82084]
2012-12-18 19:09:57 +00:00
Glen Fernandes
66f34142be Fix cxxflags in smart_ptr/test/Jamfile.v2
[SVN r82070]
2012-12-18 09:24:31 +00:00
Glen Fernandes
63834f7233 Specify gcc-4.6 instead of gcc-4.6.3 for toolset
[SVN r82038]
2012-12-16 23:03:30 +00:00
Peter Dimov
049d0698b7 Manually apply a change from [58306] that didn't get merged at the time.
[SVN r82026]
2012-12-16 16:20:03 +00:00
Peter Dimov
5ba3312519 Merged revision(s) 81900-81901 from trunk:
Replace use of BOOST_HAS_RVALUE_REFS with !BOOST_NO_CXX11_RVALUE_REFERENCES.
........
Replace use of BOOST_HAS_VARIADIC_TMPL with !BOOST_NO_CXX11_VARIADIC_TEMPLATES.
........


[SVN r81979]
2012-12-15 20:20:20 +00:00
Glen Fernandes
bb700870c0 Specify <cxxflags>-fno-deduce-init-list for gcc-4.6.3 only.
[SVN r81950]
2012-12-14 20:05:03 +00:00
Glen Fernandes
6a218a5ef2 Merged revision(s) 81886,81887,81894,81905 from trunk:
Use BOOST_NO_CXX11_RVALUE_REFERENCES and BOOST_NO_CXX11_VARIADIC_TEMPLATES instead of the legacy macros. Rename identifiers of detail utility functions.
........
Two detail utility functions identifier renaming reverted
........
Remove -fno-deduce-init-list for certain tests in Jamfile.v2
........
Correct call to init_list in make_shared and allocate_shared. Move g++ failing case into separate test to not mask other issues.
........


[SVN r81945]
2012-12-14 18:35:03 +00:00
Glen Fernandes
e36689bd5e Correct call to init_list in make_shared and allocate_shared. Move g++ failing case into separate test to not mask other issues.
[SVN r81905]
2012-12-13 18:02:25 +00:00
Peter Dimov
1c070b3a32 Replace use of BOOST_HAS_VARIADIC_TMPL with !BOOST_NO_CXX11_VARIADIC_TEMPLATES.
[SVN r81901]
2012-12-13 16:57:55 +00:00
Peter Dimov
647f67aabf Replace use of BOOST_HAS_RVALUE_REFS with !BOOST_NO_CXX11_RVALUE_REFERENCES.
[SVN r81900]
2012-12-13 16:48:57 +00:00
Peter Dimov
c14369aac9 Merged revision(s) 81860-81861 from trunk:
Change make_shared to use the new _internal_get_untyped_deleter. Fixes #6830.
........
Add allocate_shared_noinit.
........


[SVN r81899]
2012-12-13 14:57:12 +00:00
Peter Dimov
7ab4f6ce92 Merged revision(s) 72437 from trunk: Lock-free sp_counted_base for SNC/PS3, thanks Peter Dimov
[SVN r81898]
2012-12-13 14:53:09 +00:00
Glen Fernandes
bbf0245248 Remove -fno-deduce-init-list for certain tests in Jamfile.v2
[SVN r81894]
2012-12-13 12:21:44 +00:00
Glen Fernandes
619b168614 Two detail utility functions identifier renaming reverted
[SVN r81887]
2012-12-13 04:20:23 +00:00
Glen Fernandes
4ba8d879f1 Use BOOST_NO_CXX11_RVALUE_REFERENCES and BOOST_NO_CXX11_VARIADIC_TEMPLATES instead of the legacy macros. Rename identifiers of detail utility functions.
[SVN r81886]
2012-12-13 04:04:23 +00:00
Glen Fernandes
c28bef2e9b Merged revision(s) 81858,81859,81865,81867 from trunk:
Add overloads of allocate_shared_noinit to complement make_shared_noinit
........
Explicitly name detail array construct overloads for different parameter types.
........
Use _internal_get_untyped_deleter in allocate_shared_array and make_shared_array
........
Documentation corrections: make_shared_array.html
........


[SVN r81882]
2012-12-12 22:57:03 +00:00
Glen Fernandes
5f0155cca6 Documentation corrections: make_shared_array.html
[SVN r81867]
2012-12-11 22:44:57 +00:00
Glen Fernandes
db542de908 Use _internal_get_untyped_deleter in allocate_shared_array and make_shared_array
[SVN r81865]
2012-12-11 20:51:05 +00:00
Glen Fernandes
5fc6fe474b Merged revision(s) 81844 from trunk:
Correct link to  http://www.stroustrup.com/wrapper.pdf in sp_techniques.html
........


[SVN r81863]
2012-12-11 18:42:48 +00:00
Peter Dimov
d42ce87557 Merged revision(s) 81780 from trunk: Use explicit operator bool when available; add nullptr support to shared_ptr. Fixes #4116.
[SVN r81862]
2012-12-11 18:35:21 +00:00
Peter Dimov
67f5e9825e Add allocate_shared_noinit.
[SVN r81861]
2012-12-11 18:32:24 +00:00
Peter Dimov
fd52dbc411 Change make_shared to use the new _internal_get_untyped_deleter. Refs #6830.
[SVN r81860]
2012-12-11 18:21:29 +00:00
Glen Fernandes
6e269872df Explicitly name detail array construct overloads for different parameter types.
[SVN r81859]
2012-12-11 18:04:09 +00:00
Glen Fernandes
ecceb710de Add overloads of allocate_shared_noinit to complement make_shared_noinit
[SVN r81858]
2012-12-11 17:42:47 +00:00
Glen Fernandes
9863467152 Correct link to http://www.stroustrup.com/wrapper.pdf in sp_techniques.html
[SVN r81844]
2012-12-10 23:48:00 +00:00
Glen Fernandes
b306c9751f Merged revision(s) 81748-81750,81752,81759,81782 from trunk:
Refactoring in detail array_deleter before adding support for special-casing trivially default-constructible construction and trivially destroyable destruction.
........
Special case array construction for trivially default-constructible types and array destruction for trivially-destroyable types.
........
Optimization in initialization overload of array_construct for compilers to optimize it into the equivalent of a memset
........
Correctly use r-value reference semantics for Args and T in array utilities
........
Change ordering of overload definitions in array_utility.hpp
........
Convert function parameter for inner array size into template parameter and make identifiers in array_deleter consistent with those in array_utility 
........


[SVN r81800]
2012-12-08 18:30:27 +00:00
Glen Fernandes
6b0d96af96 Convert function parameter for inner array size into template parameter and make identifiers in array_deleter consistent with those in array_utility
[SVN r81782]
2012-12-08 05:25:50 +00:00
Peter Dimov
c03bfd0b4d Merged revision(s) 81730-81731, 81776 from trunk:
Fix get_pointer for the array case, add operator= for unique_ptr, update auto_ptr signatures to use rvalue reference when available.
........
Update shared_ptr.htm.
........
Add more unique_ptr tests.
........


[SVN r81781]
2012-12-08 00:57:04 +00:00
Peter Dimov
8093967da7 Use explicit operator bool when available; add nullptr support to shared_ptr. Refs #4116.
[SVN r81780]
2012-12-08 00:51:59 +00:00
Peter Dimov
7a4ad75f5d Add more unique_ptr tests.
[SVN r81776]
2012-12-07 22:42:56 +00:00
Glen Fernandes
f390d9e265 Change ordering of overload definitions in array_utility.hpp
[SVN r81759]
2012-12-07 16:40:20 +00:00
Glen Fernandes
ea22982865 Correctly use r-value reference semantics for Args and T in array utilities
[SVN r81752]
2012-12-07 07:42:42 +00:00
Glen Fernandes
09e77bc8df Optimization in initialization overload of array_construct for compilers to optimize it into the equivalent of a memset
[SVN r81750]
2012-12-07 06:45:26 +00:00
Glen Fernandes
b3f2ebedbc Special case array construction for trivially default-constructible types and array destruction for trivially-destroyable types.
[SVN r81749]
2012-12-07 03:10:22 +00:00
Glen Fernandes
1209531fe0 Refactoring in detail array_deleter before adding support for special-casing trivially default-constructible construction and trivially destroyable destruction.
[SVN r81748]
2012-12-07 01:53:35 +00:00
Peter Dimov
6c2ed927e4 Update shared_ptr.htm.
[SVN r81731]
2012-12-06 03:20:46 +00:00
Peter Dimov
7a733263da Fix get_pointer for the array case, add operator= for unique_ptr, update auto_ptr signatures to use rvalue reference when available.
[SVN r81730]
2012-12-06 03:18:54 +00:00
Glen Fernandes
08e5894510 Merged revisions 81700,81703 from trunk:
Add overloads of make_shared and allocate_shared for arrays for E&& where E is typename boost::detail::array_base<T>::type
........
Update documentation and remove unused code.
........


[SVN r81716]
2012-12-05 04:28:20 +00:00
Glen Fernandes
3551d17566 Merged revision 81463 from trunk:
Update shared_ptr casts.
........


[SVN r81715]
2012-12-05 04:13:51 +00:00
Peter Dimov
32fe0b8f26 Merged revision(s) 81488 from trunk: Apply patch from #7722. Fixes #7722.
[SVN r81714]
2012-12-05 03:44:40 +00:00
Glen Fernandes
2d3cc0db7d Update documentation and remove unused code.
[SVN r81703]
2012-12-04 11:21:24 +00:00
Glen Fernandes
188602581d Add overloads of make_shared and allocate_shared for arrays for E&& where E is typename boost::detail::array_base<T>::type
[SVN r81700]
2012-12-04 06:06:23 +00:00
Glen Fernandes
88c2baa20b Merged revision(s) 81684-81685 from trunk:
For fixed size arrays upon constructor exception thrown destroy correctly.
........
Minor cosmetic change in detail array_deleter
........


[SVN r81695]
2012-12-03 15:42:15 +00:00
Glen Fernandes
1adf546ddb Minor cosmetic change in detail array_deleter
[SVN r81685]
2012-12-03 05:56:17 +00:00
Glen Fernandes
5e5ff387fa For fixed size arrays upon constructor exception thrown destroy correctly.
[SVN r81684]
2012-12-03 05:41:34 +00:00
Glen Fernandes
ea55019260 Merged revision(s) 81641-81643,81658,81669,81681 from trunk:
Use const T (&)[N] for fixed size arrays instead of std::initializer<T> in overloads of make_shared and allocate_shared for arrays.
........
Use BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX instead for certain overloads of make_shared and allocate_shared
........
Code consistency: Use the same style of #if conditional compilation checks in allocate_shared_array.hpp and make_shared_array.hpp.
........
Change make_shared and allocate_shared array form overload for size and inner array initialization list to use const T(&)[N] instead of std::initializer_list<T>.
........
Move two tests for allocate_shared and make_shared within check for BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX
........
Make specializations of detail array_deleter consistent.
........


[SVN r81682]
2012-12-02 23:15:55 +00:00
Glen Fernandes
500913db6d Make specializations of detail array_deleter consistent.
[SVN r81681]
2012-12-02 22:05:31 +00:00
Glen Fernandes
19283a3548 Move two tests for allocate_shared and make_shared within check for BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX
[SVN r81669]
2012-12-02 10:17:05 +00:00
Glen Fernandes
cfd4152291 Change make_shared and allocate_shared array form overload for size and inner array initialization list to use const T(&)[N] instead of std::initializer_list<T>.
[SVN r81658]
2012-12-01 22:43:57 +00:00
Glen Fernandes
f5adfb0963 Code consistency: Use the same style of #if conditional compilation checks in allocate_shared_array.hpp and make_shared_array.hpp.
[SVN r81643]
2012-12-01 05:40:06 +00:00
Glen Fernandes
8597433028 Use BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX instead for certain overloads of make_shared and allocate_shared
[SVN r81642]
2012-12-01 05:23:37 +00:00
Glen Fernandes
4da0e2b7fc Use const T (&)[N] for fixed size arrays instead of std::initializer<T> in overloads of make_shared and allocate_shared for arrays.
[SVN r81641]
2012-12-01 04:36:41 +00:00
Glen Fernandes
2346941b15 Merged revision(s) 81608-81610 from trunk:
Optimization: Add specializations of make_array_helper, allocate_array_helper, and array_deleter for fixed size arrays to avoid storing size.
........
Consistent formatting across overloads of make_shared and allocate_shared (array forms).
........
More consistency in type parameters in helper details of allocate_shared and make_shared.
........


[SVN r81635]
2012-11-30 17:29:36 +00:00
Glen Fernandes
39ff002d2e More consistency in type parameters in helper details of allocate_shared and make_shared.
[SVN r81610]
2012-11-28 07:32:30 +00:00
Glen Fernandes
fceea2e584 Consistent formatting across overloads of make_shared and allocate_shared (array forms).
[SVN r81609]
2012-11-28 06:26:50 +00:00
Glen Fernandes
b17205ded7 Optimization: Add specializations of make_array_helper, allocate_array_helper, and array_deleter for fixed size arrays to avoid storing size.
[SVN r81608]
2012-11-28 06:07:45 +00:00
Peter Dimov
d74c09dd5a Apply patch from #7722. Refs #7722.
[SVN r81488]
2012-11-22 17:39:27 +00:00
Peter Dimov
97d32745aa Update shared_ptr casts.
[SVN r81463]
2012-11-21 17:43:48 +00:00
Peter Dimov
c7b6e56b30 Merged revision(s) 81368, 81399, 81407-81409, 81419, 81430-81431, 81437 from trunk:
Apply BOOST_NOEXCEPT patch. Refs #7523.
........
Replace std::forward with detail::sp_forward.
........
Cosmetic changes in make_shared_array.hpp and allocate_shared_array.hpp
........
Documentation of make_shared_array: Minor corrections
........
Make make_shared_array.hpp and allocate_shared_array.hpp consistent with namespace qualification in rest of smart_ptr.
........
Update smart_ptr.htm with link to make_shared_array.htm which lists the many overloads of make_shared and allocate_shared for arrays.
........
Update documentation for make_shared and allocate_shared array forms.
........
Minor corrections in make_shared_array.html documentation.
........
Borland fixes.
........


[SVN r81457]
2012-11-21 15:38:06 +00:00
Peter Dimov
7835914d83 Borland fixes.
[SVN r81437]
2012-11-20 15:22:19 +00:00
Glen Fernandes
98b92fa83a Minor corrections in make_shared_array.html documentation.
[SVN r81431]
2012-11-20 04:07:58 +00:00
Glen Fernandes
392885a56a Update documentation for make_shared and allocate_shared array forms.
[SVN r81430]
2012-11-20 03:00:02 +00:00
Glen Fernandes
b4594eab3b Update smart_ptr.htm with link to make_shared_array.htm which lists the many overloads of make_shared and allocate_shared for arrays.
[SVN r81419]
2012-11-19 08:08:27 +00:00
Glen Fernandes
ddfcc5f417 Make make_shared_array.hpp and allocate_shared_array.hpp consistent with namespace qualification in rest of smart_ptr.
[SVN r81409]
2012-11-18 02:51:06 +00:00
Glen Fernandes
3f458c68f4 Documentation of make_shared_array: Minor corrections
[SVN r81408]
2012-11-18 01:51:46 +00:00
Glen Fernandes
79b229adcd Cosmetic changes in make_shared_array.hpp and allocate_shared_array.hpp
[SVN r81407]
2012-11-17 22:20:32 +00:00
Peter Dimov
94b6487ca1 Replace std::forward with detail::sp_forward.
[SVN r81399]
2012-11-17 16:21:41 +00:00
Peter Dimov
cf769b94a7 Apply BOOST_NOEXCEPT patch. Refs #7523.
[SVN r81368]
2012-11-16 15:05:25 +00:00
Peter Dimov
215771c83d Merged [81348] from trunk. Fixes #7693.
[SVN r81367]
2012-11-16 14:11:25 +00:00
Peter Dimov
2805ae9362 Merged revision(s) 81341-81342 from trunk:
Add additional overload for allocate_shared and make_shared array forms that take initializer list of T for the array types T[M][N]
........
Minor style change: Fix indentation in allocate_shared_array.hpp and make_shared_array.hpp
........


[SVN r81366]
2012-11-16 14:09:18 +00:00
Peter Dimov
7adb1cc1ec Reorder HP aCC and g++ #ifdefs. Refs #7693.
[SVN r81348]
2012-11-14 18:24:05 +00:00
Glen Fernandes
da9524d637 Minor style change: Fix indentation in allocate_shared_array.hpp and make_shared_array.hpp
[SVN r81342]
2012-11-14 15:33:30 +00:00
Glen Fernandes
6b2556edfb Add additional overload for allocate_shared and make_shared array forms that take initializer list of T for the array types T[M][N]
[SVN r81341]
2012-11-14 15:18:50 +00:00
Peter Dimov
cb0797acf0 Merged revision(s) 81149, 81159, 81171, 81174, 81219-81220, 81222-81224, 81226, 81229-81239, 81242, 81253, 81257-81262, 81265-81268, 81271-81272, 81275-81277, 81299-81300 from trunk:
Implement shared_ptr<X[]>, weak_ptr<X[]>. Refs #1113.
........
Fix shared_ptr<T[]> EDG issues.
........
Disable make_shared<T> overloads when T is Q[].
........
Add catch(...) clauses to sp_array_test.cpp.
........
Add allocate_shared and make_shared for shared_ptr arrays of runtime size. Fulfills need for allocate_shared_array and make_shared_array. 
........
Update Jamfile.v2 to run make_shared array tests and allocate_shared array tests.
........
Fix g++ issues.
........
Add specialization of sp_if_not_array<T[N]>.
........
Rename make_shared.hpp to make_shared_object.hpp, include from make_shared.hpp.
........
Add make_shared_array_args_test.cpp.
........
Add support for make_shared of array of arrays. Correctly destroy elements and construct elements for the variadic template constructor variants.
........
Fix sp_convertible<T const[], T const[]>.
........
Update smart_ptr/detail/array_helper to have create and create_noinit for non-array case.
........
Rename sp_convertible_test.cpp to shared_ptr_convertible_test.cpp.
........
Don't treat array_helper create and create_noinit for array types as a special case.
........
Add sp_convertible_test.cpp.
........
Fix array_helper (create_noinit and use of args...).
........
Update allocate_shared and make_shared to treat multidimensional array as single dimension. Remove detail array_helper. Add detail array traits. Update tests. 
........
Simplify array_deleter interface
........
Add missing semicolon.
........
Fix typo.
........
Add tests for variadic template constructors overload of array forms of make_shared and allocate_shared for multidimensional arrays and up to 9 constructor arguments.
........
Add support for shared_ptr<X[N>.
........
Add C++11 initializer list support for make_shared and allocate_shared array forms.

........
Clean up code in allocate_shared_array.hpp and make_shared_array.hpp
........
Change make_shared and allocate_shared array form semantics with initializer lists overload that takes no size.
........
Disable make_shared for arrays when the compiler doesn't support partial specialization or SFINAE.
........
For allocate_shared and make_shared: Separate test case that g++ does support yet. Remove macros testing for no partial specialization in traits. Add additional traits.
........
Actually remove test cases from make_shared_array_create_test.cpp and allocate_shared_array_create_test.cpp that g++ does not handle.
........
Add overloads to support fixed size arrays, T[N], to allocate_shared (variadic) and make_shared (variadic) and make_shared_noinit.
........
Add additional overload for make_shared and allocate_shared for arrays for fixed size arrays and initializer lists.
........
Add assertion to overload of make_shared and allocate_shared for T[N] with initializer lists. Rename detail type to be more intuitive.
........
Add allocate_shared_array_args_test.cpp.
........
Keep old definition of sp_assert_convertible when BOOST_SP_NO_SP_CONVERTIBLE is set.
........
Updated shared_array to match shared_ptr. Refs #1113.
........
Add final overload of make_shared and allocate_shared (array forms) for T[][N] with C++11 initializer lists.
........
Change traits for initializer list for g++
........
Tidy long line formatting in allocate_shared_array.hpp and make_shared_array.hpp
........
Update tests for make_shared and allocate_shared array forms, for normal case, initializer lists, variadic template arguments, for arrays and fixed size arrays.
........
Update Jamfile.v2 with two new smart_ptr tests for allocate_shared and make_shared
........


[SVN r81339]
2012-11-14 13:52:11 +00:00
Peter Dimov
e8103f9774 Merge from 57197, 57206, 57423, 57518 did not apply to 'libs' for some reason; update.
[SVN r81338]
2012-11-14 13:36:44 +00:00
Peter Dimov
71eb435412 Merged revision(s) 57197, 57206, 57423, 57518 from trunk:
Renamed enable_shared_from_this2 to enable_shared_from_raw and
added shared_from_raw free function.  These changes fix the pointer 
value in shared_ptr which were obtained before an external shared_ptr has
taken ownership of the object (for example when a shared_ptr to
this is obtained in an object's constructor).


........
Brought back code which fixes get_deleter when it is called on a deleter 
which has been wrapped inside a deleter_wrapper by "shared_from_raw() in 
constructors" support.

........
Added weak_from_raw(), for use in conjunction with
enable_shared_from_raw base class.


........
Fixed access to enable_shared_from_raw::weak_this_ when 
BOOST_NO_MEMBER_TEMPLATE_FRIENDS is defined.


........


[SVN r81337]
2012-11-14 13:26:30 +00:00
Peter Dimov
4a2dad1574 Merged [81134] from trunk. Fixes #6308. Refs #6667.
[SVN r81336]
2012-11-14 12:09:30 +00:00
Peter Dimov
babc72757d Merged [81131] from trunk. Fixes #6625.
[SVN r81335]
2012-11-14 12:04:48 +00:00
Peter Dimov
c19cbc1892 Merged [81128] from trunk. Fixes #7141.
[SVN r81334]
2012-11-14 11:57:58 +00:00
Peter Dimov
d065e4d971 Merged [81127] from trunk. Fixes #6901.
[SVN r81333]
2012-11-14 11:55:10 +00:00
Peter Dimov
777b86a661 Merged [81126] from trunk. Fixes #6996.
[SVN r81332]
2012-11-14 11:53:05 +00:00
Peter Dimov
aae5440854 Merged [80988] from trunk.
[SVN r81331]
2012-11-14 11:51:00 +00:00
Peter Dimov
227d2e3255 Manually apply [69019] from trunk.
[SVN r81330]
2012-11-14 11:43:17 +00:00
Peter Dimov
8bf183b373 Merged [81125] from trunk. Fixes #4185.
[SVN r81329]
2012-11-14 11:20:29 +00:00
Peter Dimov
5017da2514 Merged [81119] from trunk. Fixes #7599.
[SVN r81328]
2012-11-14 11:17:48 +00:00
Glen Fernandes
3b0b10d06d Update Jamfile.v2 with two new smart_ptr tests for allocate_shared and make_shared
[SVN r81300]
2012-11-11 19:21:18 +00:00
Glen Fernandes
25e11b20d3 Update tests for make_shared and allocate_shared array forms, for normal case, initializer lists, variadic template arguments, for arrays and fixed size arrays.
[SVN r81299]
2012-11-11 19:14:50 +00:00
Glen Fernandes
fa513340d7 Tidy long line formatting in allocate_shared_array.hpp and make_shared_array.hpp
[SVN r81277]
2012-11-10 02:33:48 +00:00
Glen Fernandes
0e90213746 Change traits for initializer list for g++
[SVN r81276]
2012-11-10 02:17:02 +00:00
Glen Fernandes
980070e63f Add final overload of make_shared and allocate_shared (array forms) for T[][N] with C++11 initializer lists.
[SVN r81275]
2012-11-10 01:33:29 +00:00
Peter Dimov
5bdde37414 Updated shared_array to match shared_ptr. Refs #1113.
[SVN r81272]
2012-11-10 00:04:49 +00:00
Peter Dimov
2aaa913b11 Keep old definition of sp_assert_convertible when BOOST_SP_NO_SP_CONVERTIBLE is set.
[SVN r81271]
2012-11-09 23:27:02 +00:00
Peter Dimov
58a46f4e55 Add allocate_shared_array_args_test.cpp.
[SVN r81268]
2012-11-09 18:26:40 +00:00
Glen Fernandes
8cc50a5ce9 Add assertion to overload of make_shared and allocate_shared for T[N] with initializer lists. Rename detail type to be more intuitive.
[SVN r81267]
2012-11-09 18:01:39 +00:00
Glen Fernandes
2731957b5b Add additional overload for make_shared and allocate_shared for arrays for fixed size arrays and initializer lists.
[SVN r81266]
2012-11-09 17:30:07 +00:00
Glen Fernandes
fe06c120b9 Add overloads to support fixed size arrays, T[N], to allocate_shared (variadic) and make_shared (variadic) and make_shared_noinit.
[SVN r81265]
2012-11-09 17:12:56 +00:00
Glen Fernandes
c1f41aa925 Actually remove test cases from make_shared_array_create_test.cpp and allocate_shared_array_create_test.cpp that g++ does not handle.
[SVN r81262]
2012-11-09 16:35:18 +00:00
Glen Fernandes
ffa3327817 For allocate_shared and make_shared: Separate test case that g++ does support yet. Remove macros testing for no partial specialization in traits. Add additional traits.
[SVN r81261]
2012-11-09 16:06:48 +00:00
Peter Dimov
999c284109 Disable make_shared for arrays when the compiler doesn't support partial specialization or SFINAE.
[SVN r81260]
2012-11-09 12:37:03 +00:00
Glen Fernandes
d512eaaa0f Change make_shared and allocate_shared array form semantics with initializer lists overload that takes no size.
[SVN r81259]
2012-11-09 10:14:55 +00:00
Glen Fernandes
730980f3ee Clean up code in allocate_shared_array.hpp and make_shared_array.hpp
[SVN r81258]
2012-11-09 09:14:23 +00:00
Glen Fernandes
3d50db11b9 Add C++11 initializer list support for make_shared and allocate_shared array forms.
[SVN r81257]
2012-11-09 06:17:05 +00:00
Peter Dimov
aa7562c3e5 Add support for shared_ptr<X[N>.
[SVN r81253]
2012-11-08 18:07:49 +00:00
Glen Fernandes
c57245d710 Add tests for variadic template constructors overload of array forms of make_shared and allocate_shared for multidimensional arrays and up to 9 constructor arguments.
[SVN r81242]
2012-11-08 05:33:52 +00:00
Peter Dimov
945c013a12 Fix typo.
[SVN r81239]
2012-11-07 23:45:31 +00:00
Peter Dimov
df544871d7 Add missing semicolon.
[SVN r81238]
2012-11-07 23:41:52 +00:00
Glen Fernandes
89190ca17e Simplify array_deleter interface
[SVN r81237]
2012-11-07 18:58:41 +00:00
Glen Fernandes
5d9312239c Update allocate_shared and make_shared to treat multidimensional array as single dimension. Remove detail array_helper. Add detail array traits. Update tests.
[SVN r81236]
2012-11-07 18:37:17 +00:00
Glen Fernandes
93b5cace12 Fix array_helper (create_noinit and use of args...).
[SVN r81235]
2012-11-07 15:36:15 +00:00
Peter Dimov
e50c849ab3 Add sp_convertible_test.cpp.
[SVN r81234]
2012-11-07 15:33:44 +00:00
Glen Fernandes
dbea328b8b Don't treat array_helper create and create_noinit for array types as a special case.
[SVN r81233]
2012-11-07 15:25:55 +00:00
Peter Dimov
c06ba497a3 Rename sp_convertible_test.cpp to shared_ptr_convertible_test.cpp.
[SVN r81232]
2012-11-07 15:07:08 +00:00
Glen Fernandes
734b5d1354 Update smart_ptr/detail/array_helper to have create and create_noinit for non-array case.
[SVN r81231]
2012-11-07 15:04:04 +00:00
Peter Dimov
0467af1b83 Fix sp_convertible<T const[], T const[]>.
[SVN r81230]
2012-11-07 15:00:24 +00:00
Glen Fernandes
dc5406aa5a Add support for make_shared of array of arrays. Correctly destroy elements and construct elements for the variadic template constructor variants.
[SVN r81229]
2012-11-07 14:42:10 +00:00
Peter Dimov
6e873de0fa Add make_shared_array_args_test.cpp.
[SVN r81226]
2012-11-06 17:31:15 +00:00
Peter Dimov
322bcd7efa Rename make_shared.hpp to make_shared_object.hpp, include from make_shared.hpp.
[SVN r81224]
2012-11-06 16:29:56 +00:00
Peter Dimov
bb72e0a092 Add specialization of sp_if_not_array<T[N]>.
[SVN r81223]
2012-11-06 16:23:09 +00:00
Peter Dimov
d8eb2fc105 Fix g++ issues.
[SVN r81222]
2012-11-06 15:10:32 +00:00
Glen Fernandes
e7d3987cfb Update Jamfile.v2 to run make_shared array tests and allocate_shared array tests.
[SVN r81220]
2012-11-06 14:35:40 +00:00
Glen Fernandes
6662ae7242 Add allocate_shared and make_shared for shared_ptr arrays of runtime size. Fulfills need for allocate_shared_array and make_shared_array.
[SVN r81219]
2012-11-06 14:17:32 +00:00
Peter Dimov
2ba7b6b99b Add catch(...) clauses to sp_array_test.cpp.
[SVN r81174]
2012-11-04 18:30:03 +00:00
Peter Dimov
a30e291022 Disable make_shared<T> overloads when T is Q[].
[SVN r81171]
2012-11-04 14:53:51 +00:00
Peter Dimov
0b6cab9f2f Fix shared_ptr<T[]> EDG issues.
[SVN r81159]
2012-11-03 14:49:45 +00:00
Peter Dimov
8c15401ea7 Implement shared_ptr<X[]>, weak_ptr<X[]>. Refs #1113.
[SVN r81149]
2012-11-02 17:41:33 +00:00
Peter Dimov
03ae5cdbc6 Add back _AIX-specific #ifdef that was mistakenly removed. Refs #6308. Refs #6667.
[SVN r81134]
2012-11-01 17:50:41 +00:00
Peter Dimov
0c22e55f3e Add shared_ptr constructor taking std::unique_ptr. Refs #6625.
[SVN r81131]
2012-10-31 22:16:20 +00:00
Peter Dimov
10dcb8db7c Define BOOST_SP_HAS_SYNC when __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 is set. Refs #7141.
[SVN r81128]
2012-10-31 20:37:21 +00:00
Peter Dimov
f2d4b67a48 Enable __sync primitives on VACPP. Refs #6901.
[SVN r81127]
2012-10-31 20:30:27 +00:00
Peter Dimov
16084637a6 Do not use sp_counted_base_gcc_ppc on AIX. Refs #6996.
[SVN r81126]
2012-10-31 20:16:56 +00:00
Peter Dimov
3e447c919c Add get_pointer overloads for std::unique_ptr, std::shared_ptr. Refs #4185.
[SVN r81125]
2012-10-31 20:04:14 +00:00
Peter Dimov
b0f72d7b3d Add check for __ARM_ARCH_7S__. Refs #7599.
[SVN r81119]
2012-10-31 16:04:03 +00:00
Bryce Adelstein-Lelbach
4c98df7c57 Update smart_ptr for the latest version of the PathScale compiler.
[SVN r80988]
2012-10-14 23:06:12 +00:00
Peter Dimov
c2048732d8 Merge [77316] to release. Closes #6667.
[SVN r77318]
2012-03-12 17:40:02 +00:00
Peter Dimov
5979c1d4bd Merge [77315] to release. Closes #5331.
[SVN r77317]
2012-03-12 17:37:51 +00:00
Peter Dimov
1029ae0ea5 Apply patches from #6667. Refs #6667.
[SVN r77316]
2012-03-12 17:33:50 +00:00
Peter Dimov
27a312228c Apply patch from #5331. Refs #5331.
[SVN r77315]
2012-03-12 17:31:21 +00:00
Peter Dimov
3090f6f4af Merge [76219] to release. Fixes #6332.
[SVN r76221]
2011-12-29 22:43:02 +00:00
Peter Dimov
2c29f1e5a9 Warning 4284 is obsolete. Refs #6332. See also #4433.
[SVN r76219]
2011-12-29 22:27:37 +00:00
Peter Dimov
40073ef64f Merge [76125], [76126] to release.
[SVN r76164]
2011-12-26 00:25:42 +00:00
Peter Dimov
b9970eda45 Merge [76111] to release. Fixes #2603.
[SVN r76163]
2011-12-26 00:23:00 +00:00
Peter Dimov
df364f37f2 std::move is in <utility>.
[SVN r76125]
2011-12-23 23:54:41 +00:00
Peter Dimov
9147489b4c Merge [76123] to release. Refs #6308.
[SVN r76124]
2011-12-23 23:12:50 +00:00
Peter Dimov
33ba2c4722 sp_counted_base_aix.hpp: switch to lwsync and builtins. Refs #6308.
[SVN r76123]
2011-12-23 23:10:37 +00:00
Peter Dimov
d1348ea05e Merge [76119] to release. Refs #6308.
[SVN r76120]
2011-12-23 15:10:51 +00:00
Peter Dimov
faf212f4aa Add memory barriers to sp_counted_base_aix.hpp. Refs #6308.
[SVN r76119]
2011-12-23 15:03:39 +00:00
Peter Dimov
57a5441ebf Creatively apply patch from #2603. Refs #2603.
[SVN r76111]
2011-12-23 03:00:05 +00:00
Peter Dimov
90db9a6435 Merge [76086] to release. Fixes #6308.
[SVN r76087]
2011-12-21 00:43:56 +00:00
Peter Dimov
017ab7e2ee Apply AIX patch from #6308. Refs #6308.
[SVN r76086]
2011-12-21 00:36:55 +00:00
Peter Dimov
1c208ad3ea Merge [75392] to release. Fixes #6087.
[SVN r75756]
2011-11-30 18:01:02 +00:00
Peter Dimov
5fc9bf5bc5 Merge [75390] to release. Fixes #4493.
[SVN r75754]
2011-11-30 17:51:43 +00:00
Peter Dimov
c846d230f0 Merge [75389] to release. Fixes #5372.
[SVN r75753]
2011-11-30 17:49:43 +00:00
Peter Dimov
e4cb5e131f Add hash_value for intrusive_ptr. Refs #6087.
[SVN r75392]
2011-11-07 18:46:46 +00:00
Peter Dimov
fbe4ddf4a2 Add get_deleter for shared_array. Refs #4493.
[SVN r75390]
2011-11-07 18:19:24 +00:00
Peter Dimov
288fb7efcf Add ARM memory barriers. Refs #5372.
[SVN r75389]
2011-11-07 17:50:31 +00:00
Peter Dimov
7b097467d6 Merge [75385] to release. Fixes #6099.
[SVN r75386]
2011-11-07 15:05:43 +00:00
Peter Dimov
9d9e6350f2 Apply patch from #6099. Refs #6099.
[SVN r75385]
2011-11-07 15:03:44 +00:00
Peter Dimov
7cb040edb0 Merge [70452] to release. Fixes #5327.
[SVN r75381]
2011-11-07 14:25:23 +00:00
Peter Dimov
d6ac116b71 Merge [73202] to release.
[SVN r73542]
2011-08-05 08:58:31 +00:00
Peter Dimov
7e9664396a Add copy constructor/assignment - in C++0x, move disables implicit copy.
[SVN r73202]
2011-07-17 20:35:44 +00:00
Emil Dotchevski
b4b415553c Lock-free sp_counted_base for SNC/PS3, thanks Peter Dimov
[SVN r72437]
2011-06-06 18:56:07 +00:00
Peter Dimov
f76a8d95d8 Apply suggested patch. Refs #5327.
[SVN r70452]
2011-03-23 00:29:22 +00:00
Peter Dimov
8abc8889d1 Merge [69262] to release. Fixes #5018.
[SVN r70447]
2011-03-23 00:13:54 +00:00
Peter Dimov
c5b47e2136 Merge [69261] to release. Fixes #5019.
[SVN r70441]
2011-03-22 23:55:05 +00:00
Peter Dimov
7c0815c567 Merge [69260] to release. Fixes #5216.
[SVN r70440]
2011-03-22 23:51:10 +00:00
Peter Dimov
210288f02e Merge [69251] to release. Fixes #4127.
[SVN r70439]
2011-03-22 23:45:59 +00:00
Peter Dimov
cf7b6904e8 Merge [69250] to release. Fixes #4256. Fixes #3875.
[SVN r70436]
2011-03-22 23:38:12 +00:00
Peter Dimov
b978919dd1 Merge [69246] to release. Fixes #4478.
[SVN r70435]
2011-03-22 23:29:35 +00:00
Peter Dimov
1086aff971 Merge [69245] to release. Fixes #4433.
[SVN r70434]
2011-03-22 23:23:44 +00:00
Peter Dimov
445e8d1728 Merge [69244] to release. Fixes #4892.
[SVN r70433]
2011-03-22 23:17:51 +00:00
Peter Dimov
545745d649 Merge [69242] to release. Fixes #4288. Fixes #5189.
[SVN r70432]
2011-03-22 23:05:48 +00:00
Peter Dimov
634866c28a Honor BOOST_SP_USE_PTHREADS. Refs #5018.
[SVN r69262]
2011-02-24 23:35:22 +00:00
Peter Dimov
b18b47770d Add support for BOOST_SP_NO_SYNC. Refs #5019.
[SVN r69261]
2011-02-24 23:30:22 +00:00
Peter Dimov
69aa01ec00 Add hash_value for shared_ptr; prevents hash_value( bool ) from being used. Refs #5216.
[SVN r69260]
2011-02-24 23:24:54 +00:00
Peter Dimov
e3d2f2ee6b Apply suggested fix. Refs #4127.
[SVN r69251]
2011-02-24 22:05:04 +00:00
Peter Dimov
593093e46d Fix make_shared to not copy the deleter. Refs #4256. Refs #3875.
[SVN r69250]
2011-02-24 21:51:21 +00:00
Peter Dimov
9196247dea Apply patch. Refs #4478.
[SVN r69246]
2011-02-24 20:53:46 +00:00
Peter Dimov
53d5d086ea Warning 4284 is obsolete. Refs #4433.
[SVN r69245]
2011-02-24 20:48:17 +00:00
Peter Dimov
1426b0bbdd Apply patch to allow perfect forwarding without variadics. Refs #4892.
[SVN r69244]
2011-02-24 20:41:29 +00:00
Peter Dimov
4fabf9b352 Add include guards, make_shared.hpp to smart_ptr.hpp. Refs #4288. Refs #5189.
[SVN r69242]
2011-02-24 20:29:38 +00:00
Bryce Adelstein-Lelbach
a2fc6e12da Intel 11.0 doesn't provide __sync intrinsics - this is added in Intel 11.1.
[SVN r69019]
2011-02-19 01:33:46 +00:00
Bryce Adelstein-Lelbach
c3b51e201b Pathscale-4.0 configuration code/workarounds.
[SVN r68142]
2011-01-14 02:59:34 +00:00
Hartmut Kaiser
d71cc6ab08 Merging from trunk
[SVN r66166]
2010-10-24 22:24:54 +00:00
Hartmut Kaiser
825786d59a Re-added sunpro specific initialization
[SVN r66091]
2010-10-19 13:33:00 +00:00
Hartmut Kaiser
37f10d500d Fixing sp_typeinfo for clang and gcc 4.5.1
[SVN r66031]
2010-10-17 02:24:40 +00:00
Peter Dimov
0d77fd0678 Merge [62248] to release. Fixes #3856.
[SVN r63827]
2010-07-10 21:17:40 +00:00
Peter Dimov
6ca6d3ce6f Merge [62246] to release. Fixes #4217.
[SVN r63826]
2010-07-10 21:07:05 +00:00
Peter Dimov
cfc82854d3 Merge [62245] to release. Fixes #4199.
[SVN r63825]
2010-07-10 20:46:53 +00:00
Peter Dimov
3c84388186 Resolve the ambiguity between the zero argument make_shared and the variadic one. Refs #3856.
[SVN r62248]
2010-05-26 18:18:10 +00:00
Peter Dimov
a46d405778 DWORD is unsigned long, not unsigned int. Refs #4217.
[SVN r62246]
2010-05-26 17:49:37 +00:00
Peter Dimov
2e53b1eb38 Applied patch for Sun C++. Refs #4199.
[SVN r62245]
2010-05-26 17:43:58 +00:00
Peter Dimov
b9d77d877e Merge [61344] to release. Fixes #4108.
[SVN r62244]
2010-05-26 17:34:01 +00:00
Peter Dimov
1f50e3abe4 Merge [61574], [61575], [61579] to release.
[SVN r62243]
2010-05-26 17:25:06 +00:00
Peter Dimov
37c9a235a5 Add BOOST_HAS_VARIADIC_TMPL as a test condition.
[SVN r61579]
2010-04-26 16:39:45 +00:00
Peter Dimov
7083e76666 Remove duplicate using declarations.
[SVN r61575]
2010-04-26 12:20:44 +00:00
Peter Dimov
7aac2f3263 Fix detail::forward to work with rvalue references v2.
[SVN r61574]
2010-04-26 12:16:55 +00:00
Steven Watanabe
458dffdab9 Work around over-eager ADL with msvc-10.0. Refs #4108
[SVN r61344]
2010-04-17 20:13:27 +00:00
Peter Dimov
697f338510 Merge [61074]. Fixes #4067.
[SVN r61078]
2010-04-05 19:37:32 +00:00
Peter Dimov
f7919f0b9f Borland 6.21 still needs the workaround. Refs #4067.
[SVN r61074]
2010-04-05 18:53:58 +00:00
Peter Dimov
f4386409d9 Merge [58275], [58306] to release.
[SVN r58380]
2009-12-14 17:44:19 +00:00
Peter Dimov
ae34be773f Qualify detail:: references. Detabify sp_typeinfo_test.cpp.
[SVN r58306]
2009-12-11 22:36:35 +00:00
Peter Dimov
1b91c1dbea Avoid static destruction order issues with quick_allocator.
[SVN r58275]
2009-12-10 20:34:46 +00:00
Peter Dimov
ba349679f3 Merge [58123], [58127], [58128] to release. Fixes #3666.
[SVN r58195]
2009-12-06 17:50:28 +00:00
Peter Dimov
577528812a Fix sp_typeinfo to match the interface of std::type_info.
[SVN r58127]
2009-12-03 20:31:01 +00:00
Peter Dimov
e78efdbb96 Fix smart_ptr tests to not require RTTI.
[SVN r58123]
2009-12-03 18:10:37 +00:00
Peter Dimov
a3b84f8586 Merge [58094] to release.
[SVN r58122]
2009-12-03 17:50:37 +00:00
Peter Dimov
3824a6b156 Add memory_order_consume.
[SVN r58094]
2009-12-02 11:47:58 +00:00
Peter Dimov
b0fd8a6b08 Merge [57957] to release. Fixes #3570.
[SVN r58067]
2009-11-30 20:34:39 +00:00
Peter Dimov
4f5062004a Merge [57954], [57955] to release.
[SVN r58066]
2009-11-30 20:30:22 +00:00
Peter Dimov
f040bed751 Merge [57953] to release. Fixes #2681.
[SVN r58065]
2009-11-30 20:25:01 +00:00
Peter Dimov
2f8945a885 Merge [57951] to release. Fixes #3351.
[SVN r58064]
2009-11-30 20:20:52 +00:00
Peter Dimov
2bd0778778 Merge [57949] to release. Fixes #3678. Fixes #3341.
[SVN r58063]
2009-11-30 20:17:14 +00:00
Peter Dimov
eec640bfd7 Merge [57520] to release. Fixes #2962.
[SVN r57960]
2009-11-26 22:10:30 +00:00
Peter Dimov
754fd941ee Merge [57950], [57952] to release. Fixes #3404. Fixes #3456.
[SVN r57959]
2009-11-26 21:58:16 +00:00
Peter Dimov
b691be0af9 Remove std::move references. Refs #3570.
[SVN r57957]
2009-11-26 21:20:47 +00:00
Peter Dimov
fa597b877e Extend Borland workaround to 6.2.
[SVN r57955]
2009-11-26 21:04:36 +00:00
Peter Dimov
d0a9d76494 Add error checking to lwm_pthreads.hpp. Refs #2681.
[SVN r57953]
2009-11-26 20:55:05 +00:00
Peter Dimov
979e76b7e0 Enable __sync use on Intel 11.0 or later. Refs #3351.
[SVN r57951]
2009-11-26 20:17:55 +00:00
Peter Dimov
c97eebabf7 Fix enable_shared_from_this example. Refs #3404.
[SVN r57950]
2009-11-26 20:11:05 +00:00
Peter Dimov
030a848c5f Fix SPARC asm operand failure. Refs #3678. Refs #3341.
[SVN r57949]
2009-11-26 18:21:21 +00:00
Frank Mori Hess
18bfaea996 Fixed perfect forwarding for make_shared() in trunk, and added
corresponding test.  Refs #2962.



[SVN r57520]
2009-11-09 18:12:35 +00:00
Frank Mori Hess
502de325ee Fixed access to enable_shared_from_raw::weak_this_ when
BOOST_NO_MEMBER_TEMPLATE_FRIENDS is defined.



[SVN r57518]
2009-11-09 16:33:35 +00:00
Frank Mori Hess
9f49538b37 Added weak_from_raw(), for use in conjunction with
enable_shared_from_raw base class.



[SVN r57423]
2009-11-05 21:41:38 +00:00
Frank Mori Hess
2ee5eb70f3 Brought back code which fixes get_deleter when it is called on a deleter
which has been wrapped inside a deleter_wrapper by "shared_from_raw() in 
constructors" support.


[SVN r57206]
2009-10-28 22:42:21 +00:00
Frank Mori Hess
32eb028e13 Renamed enable_shared_from_this2 to enable_shared_from_raw and
added shared_from_raw free function.  These changes fix the pointer 
value in shared_ptr which were obtained before an external shared_ptr has
taken ownership of the object (for example when a shared_ptr to
this is obtained in an object's constructor).



[SVN r57197]
2009-10-28 19:10:47 +00:00
Troy D. Straszheim
e824e23ec2 rm cmake from trunk. I'm not entirely sure this is necessary to satisfy the inspect script, but I'm not taking any chances, and it is easy to put back
[SVN r56942]
2009-10-17 02:07:38 +00:00
Troy D. Straszheim
f5cc79f58d Copyrights on CMakeLists.txt to keep them from clogging up the inspect
reports.  This is essentially the same commit as r55095 on the release
branch.



[SVN r55159]
2009-07-26 00:49:56 +00:00
Gennadiy Rozental
28d7e348c1 avoid C style casts
[SVN r53672]
2009-06-06 09:44:36 +00:00
Timothy Zachary Laine
fc12543814 Merged in smart_ptr changes from the sandbox/boost0x branch created for
BoostCon '09.  This adds move semantics to weak_ptr and intrusive_ptr.


[SVN r52937]
2009-05-12 16:18:15 +00:00
Peter Dimov
4b4a62513f Make ++a, where a is an atomic_count, return the new value.
[SVN r52456]
2009-04-17 20:24:01 +00:00
Peter Dimov
0368a37fde Bring back "explicit" on the auto_ptr rvalue constructor. Refs #2951.
[SVN r52454]
2009-04-17 19:51:18 +00:00
David Deakins
3dacec8e1d Have config/select_stdlib_config.hpp and config/stdlib/stlport.hpp use <cstddef> instead of <utility> to determine which standard library is in use. For std lib implementations that rely on Boost components like TypeTraits, Bind, Function, or SmartPtr, this helps to avoid circular header dependency issues, since <cstddef> is much less likely to pull in Boost libraries than <utility>.
In get_pointer.hpp, switched to using <boost/config/no_tr1/memory.hpp> instead of using <memory> directly.  As above, this helps avoid circular header dependency issues in Boost-supplemented std libs (specifically it avoids issues when <memory> pulls in pieces of Boost.SmartPtr).

These two changes were made in response to testing done with STLport 5.2.1 using the _STLP_USE_BOOST_SUPPORT option.

[SVN r52104]
2009-04-01 14:42:11 +00:00
Peter Dimov
5758e51948 Fix sp_typeinfo.hpp include. Refs #2885.
[SVN r51985]
2009-03-26 12:47:24 +00:00
Peter Dimov
287d329276 Added g++/MIPS support submitted by David Joyner. Refs #2885.
[SVN r51978]
2009-03-26 00:17:57 +00:00
Peter Dimov
d34d638998 Bring back the constructor-enabled enable_shared_from_this as enable_shared_from_this2.
[SVN r51912]
2009-03-22 21:11:17 +00:00
Peter Dimov
6f2bdddfa0 Delete enable_shared_from_this2.hpp from boost/.
[SVN r51910]
2009-03-22 20:14:13 +00:00
Peter Dimov
9227371881 Move enable_shared_from_this2.hpp to boost/smart_ptr.
[SVN r51909]
2009-03-22 20:13:16 +00:00
Peter Dimov
e88dd9fc77 Bring back the new enable_shared_from_this.
[SVN r51908]
2009-03-22 20:08:39 +00:00
Frank Mori Hess
fa3c56747d Added missing semicolon at end of &uuml
[SVN r51700]
2009-03-11 13:55:29 +00:00
Frank Mori Hess
fbc6919eae Adding documentation for make_shared and allocate_shared to smart_ptr docs.
It is adopted from n2351 "Improving shared_ptr for C++0x, Revision 2". 
Also includes some minor corrections.
Refs #1897



[SVN r51699]
2009-03-11 13:48:51 +00:00
Peter Dimov
dc3ffc5f4b Attempt to fix como link failure.
[SVN r51686]
2009-03-10 18:07:13 +00:00
Peter Dimov
0610947c4a De-optimize assignment into this_type(r).swap(*this) - turns out that they were not equivalent, leading to leaks in contrived cases. Refs #2813.
[SVN r51643]
2009-03-07 22:21:56 +00:00
Peter Dimov
9c55fbc6c2 Fix enable_shared_from_this-related tickets in trunk. Refs #2126. Refs #2584.
[SVN r51581]
2009-03-03 19:25:26 +00:00
Peter Dimov
68c939ec5a Fix #includes in spinlock_test.cpp, spinlock_try_test.cpp, yield_k_test.cpp.
[SVN r51519]
2009-03-01 18:54:51 +00:00
Peter Dimov
a378c8c278 Refs #2814 (fixed in trunk.)
[SVN r51518]
2009-03-01 18:42:44 +00:00
Peter Dimov
905a3711db Refs #2525 (fixed in trunk.)
[SVN r51517]
2009-03-01 18:01:19 +00:00
Peter Dimov
ed32efcc51 Refs #2662 (applied to trunk.)
[SVN r51516]
2009-03-01 17:27:35 +00:00
Peter Dimov
eb0ff40d62 Refs #2675 (fixed in trunk.)
[SVN r51515]
2009-03-01 17:18:17 +00:00
Peter Dimov
ad1b344405 Refs #2394 (fixed in trunk.)
[SVN r51514]
2009-03-01 17:10:49 +00:00
204 changed files with 14655 additions and 3776 deletions

View File

@@ -1,88 +1,88 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html> <html>
<head> <head>
<title>Smart Pointer Changes</title> <title>Smart Pointer Changes</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head> </head>
<body bgcolor="#ffffff" text="#000000"> <body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
<h1><A href="../../index.htm"><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="277" height="86" <h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
border="0"></A>Smart Pointer Changes</h1> width="277" align="middle" border="0">Smart Pointer Changes</h1>
<p>The February 2002 change to the Boost smart pointers introduced a number of <p>The February 2002 change to the Boost smart pointers introduced a number of
changes. Since the previous version of the smart pointers was in use for a long changes. Since the previous version of the smart pointers was in use for a long
time, it's useful to have a detailed list of what changed from a library user's time, it's useful to have a detailed list of what changed from a library user's
point of view.</p> point of view.</p>
<p>Note that for compilers that don't support member templates well enough, a <p>Note that for compilers that don't support member templates well enough, a
separate implementation is used that lacks many of the new features and is more separate implementation is used that lacks many of the new features and is more
like the old version.</p> like the old version.</p>
<h2>Features Requiring Code Changes to Take Advantage</h2> <h2>Features Requiring Code Changes to Take Advantage</h2>
<ul> <ul>
<li> <li>
The smart pointer class templates now each have their own header file. For The smart pointer class templates now each have their own header file. For
compatibility, the <a href="../../boost/smart_ptr.hpp">&lt;boost/smart_ptr.hpp&gt;</a> compatibility, the <a href="../../boost/smart_ptr.hpp">&lt;boost/smart_ptr.hpp&gt;</a>
header now includes the headers for the four classic smart pointer class header now includes the headers for the four classic smart pointer class
templates. templates.
<li> <li>
The <b>weak_ptr</b> The <b>weak_ptr</b>
template was added. template was added.
<li> <li>
The new <b>shared_ptr</b> and <b>shared_array</b> relax the requirement that The new <b>shared_ptr</b> and <b>shared_array</b> relax the requirement that
the pointed-to object's destructor must be visible when instantiating the <b>shared_ptr</b> the pointed-to object's destructor must be visible when instantiating the <b>shared_ptr</b>
destructor. This makes it easier to have shared_ptr members in classes without destructor. This makes it easier to have shared_ptr members in classes without
explicit destructors. explicit destructors.
<li> <li>
A custom deallocator can be passed in when creating a <b>shared_ptr</b> or <b>shared_array</b>. A custom deallocator can be passed in when creating a <b>shared_ptr</b> or <b>shared_array</b>.
<li> <li>
<b>shared_static_cast</b> and <b>shared_dynamic_cast</b> function templates are <b>shared_static_cast</b> and <b>shared_dynamic_cast</b> function templates are
provided which work for <b>shared_ptr</b> and <b>weak_ptr</b> as <b>static_cast</b> provided which work for <b>shared_ptr</b> and <b>weak_ptr</b> as <b>static_cast</b>
and <b>dynamic_cast</b> and <b>dynamic_cast</b>
do for pointers. do for pointers.
<li> <li>
The self-assignment misfeature has been removed from <b>shared_ptr::reset</b>, The self-assignment misfeature has been removed from <b>shared_ptr::reset</b>,
although it is still present in <b>scoped_ptr</b>, and in <b>std::auto_ptr</b>. although it is still present in <b>scoped_ptr</b>, and in <b>std::auto_ptr</b>.
Calling <b>reset</b> with a pointer to the object that's already owned by the <b>shared_ptr</b> Calling <b>reset</b> with a pointer to the object that's already owned by the <b>shared_ptr</b>
results in undefined behavior (an assertion, or eventually a double-delete if results in undefined behavior (an assertion, or eventually a double-delete if
assertions are off). assertions are off).
<li> <li>
The <b>BOOST_SMART_PTR_CONVERSION</b> The <b>BOOST_SMART_PTR_CONVERSION</b>
feature has been removed. feature has been removed.
<li> <li>
<b>shared_ptr&lt;void&gt;</b> is now allowed.</li> <b>shared_ptr&lt;void&gt;</b> is now allowed.</li>
</ul> </ul>
<h2>Features That Improve Robustness</h2> <h2>Features That Improve Robustness</h2>
<ul> <ul>
<li> <li>
The manipulation of use counts is now <a name="threadsafe">thread safe</a> on The manipulation of use counts is now <a name="threadsafe">thread safe</a> on
Windows, Linux, and platforms that support pthreads. See the <a href="../../boost/detail/atomic_count.hpp"> Windows, Linux, and platforms that support pthreads. See the <a href="../../boost/detail/atomic_count.hpp">
&lt;boost/detail/atomic_count.hpp&gt;</a> &lt;boost/detail/atomic_count.hpp&gt;</a>
file for details file for details
<li> <li>
The new shared_ptr will always delete the object using the pointer it was The new shared_ptr will always delete the object using the pointer it was
originally constructed with. This prevents subtle problems that could happen if originally constructed with. This prevents subtle problems that could happen if
the last <b>shared_ptr</b> was a pointer to a sub-object of a class that did the last <b>shared_ptr</b> was a pointer to a sub-object of a class that did
not have a virtual destructor.</li> not have a virtual destructor.</li>
</ul> </ul>
<h2>Implementation Details</h2> <h2>Implementation Details</h2>
<ul> <ul>
<li> <li>
Some bugs in the assignment operator implementations and in <b>reset</b> Some bugs in the assignment operator implementations and in <b>reset</b>
have been fixed by using the "copy and swap" idiom. have been fixed by using the "copy and swap" idiom.
<li> <li>
Assertions have been added to check preconditions of various functions; Assertions have been added to check preconditions of various functions;
however, since these use the new <a href="../../boost/assert.hpp">&lt;boost/assert.hpp&gt;</a> however, since these use the new <a href="../../boost/assert.hpp">&lt;boost/assert.hpp&gt;</a>
header, the assertions are disabled by default. header, the assertions are disabled by default.
<li> <li>
The partial specialization of <b>std::less</b> has been replaced by <b>operator&lt;</b> The partial specialization of <b>std::less</b> has been replaced by <b>operator&lt;</b>
overloads which accomplish the same thing without relying on undefined overloads which accomplish the same thing without relying on undefined
behavior. behavior.
<li> <li>
The incorrect overload of <b>std::swap</b> has been replaced by <b>boost::swap</b>, The incorrect overload of <b>std::swap</b> has been replaced by <b>boost::swap</b>,
which has many of the same advantages for generic programming but does not which has many of the same advantages for generic programming but does not
violate the C++ standard.</li> violate the C++ standard.</li>
</ul> </ul>
<hr> <hr>
<p>Revised 1 February 2002</p> <p>$Date$</p>
<p><small>Copyright 2002 Darin Adler. Distributed under the Boost Software License, Version <p><small>Copyright 2002 Darin Adler. Distributed under the Boost Software License, Version
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or 1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or
copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p> copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
</body> </body>
</html> </html>

View File

@@ -1,54 +1,48 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html> <html>
<head> <head>
<title>Boost: enable_shared_from_this.hpp documentation</title> <title>enable_shared_from_this</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head> </head>
<body bgcolor="white" style="MARGIN-LEFT: 5%; MARGIN-RIGHT: 5%"> <body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
<table border="0" width="100%"> <h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
<tr> width="277" align="middle" border="0">enable_shared_from_this</h1>
<td width="277"><A href="../../index.htm"> <img src="../../boost.png" alt="boost.png (6897 bytes)" width="277" height="86" border="0"></A> <h2><a name="Purpose">Purpose</a></h2>
</td> <p>
<td align="center"> The header <STRONG>&lt;boost/enable_shared_from_this.hpp&gt;</STRONG> defines
<h1>enable_shared_from_this.hpp</h1> the class template <STRONG>enable_shared_from_this</STRONG>. It is used as a
</td> base class that allows a <A href="shared_ptr.htm">shared_ptr</A> to the current
</tr> object to be obtained from within a member function.
<tr> </p>
<td colspan="2" height="64">&nbsp;</td> <P><STRONG>enable_shared_from_this&lt;T&gt;</STRONG> defines two member functions
</tr> called <STRONG>shared_from_this</STRONG> that return a <STRONG>shared_ptr&lt;T&gt;</STRONG>
</table> and <STRONG>shared_ptr&lt;T const&gt;</STRONG>, depending on constness, to <STRONG>this</STRONG>.</P>
<h3><a name="Purpose">Purpose</a></h3> <h2><a name="Example">Example</a></h2>
<p> <pre>
The header <STRONG>&lt;boost/enable_shared_from_this.hpp&gt;</STRONG> defines #include &lt;boost/enable_shared_from_this.hpp&gt;
the class template <STRONG>enable_shared_from_this</STRONG>. It is used as a #include &lt;boost/shared_ptr.hpp&gt;
base class that allows a <A href="shared_ptr.htm">shared_ptr</A> to the current #include &lt;cassert&gt;
object to be obtained from within a member function.
</p> class Y: public boost::enable_shared_from_this&lt;Y&gt;
<P><STRONG>enable_shared_from_this&lt;T&gt;</STRONG> defines two member functions
called <STRONG>shared_from_this</STRONG> that return a <STRONG>shared_ptr&lt;T&gt;</STRONG>
and <STRONG>shared_ptr&lt;T const&gt;</STRONG>, depending on constness, to <STRONG>this</STRONG>.</P>
<h3><a name="Example">Example</a></h3>
<pre>
class Y: public enable_shared_from_this&lt;Y&gt;
{ {
public: public:
shared_ptr&lt;Y&gt; f() boost::shared_ptr&lt;Y&gt; f()
{ {
return shared_from_this(); return shared_from_this();
} }
} };
int main() int main()
{ {
shared_ptr&lt;Y&gt; p(new Y); boost::shared_ptr&lt;Y&gt; p(new Y);
shared_ptr&lt;Y&gt; q = p-&gt;f(); boost::shared_ptr&lt;Y&gt; q = p-&gt;f();
assert(p == q); assert(p == q);
assert(!(p &lt; q || q &lt; p)); // p and q must share ownership assert(!(p &lt; q || q &lt; p)); // p and q must share ownership
} }
</pre> </pre>
<h3><a name="Synopsis">Synopsis</a></h3> <h3><a name="Synopsis">Synopsis</a></h3>
<pre> <pre>
namespace boost namespace boost
{ {
@@ -62,30 +56,30 @@ public:
} }
</pre> </pre>
<h4>template&lt;class T&gt; shared_ptr&lt;T&gt; <h4>template&lt;class T&gt; shared_ptr&lt;T&gt;
enable_shared_from_this&lt;T&gt;::shared_from_this();</h4> enable_shared_from_this&lt;T&gt;::shared_from_this();</h4>
<h4>template&lt;class T&gt; shared_ptr&lt;T const&gt; <h4>template&lt;class T&gt; shared_ptr&lt;T const&gt;
enable_shared_from_this&lt;T&gt;::shared_from_this() const;</h4> enable_shared_from_this&lt;T&gt;::shared_from_this() const;</h4>
<blockquote> <blockquote>
<p> <p>
<b>Requires:</b> <STRONG>enable_shared_from_this&lt;T&gt;</STRONG> must be an <b>Requires:</b> <STRONG>enable_shared_from_this&lt;T&gt;</STRONG> must be an
accessible base class of <b>T</b>. <STRONG>*this</STRONG> must be a subobject accessible base class of <b>T</b>. <STRONG>*this</STRONG> must be a subobject
of an instance <STRONG>t</STRONG> of type <STRONG>T</STRONG> . There must exist of an instance <STRONG>t</STRONG> of type <STRONG>T</STRONG> . There must exist
at least one <STRONG>shared_ptr</STRONG> instance <STRONG>p</STRONG> that <EM>owns</EM> at least one <STRONG>shared_ptr</STRONG> instance <STRONG>p</STRONG> that <EM>owns</EM>
<STRONG>t</STRONG>. <STRONG>t</STRONG>.
</p> </p>
<p> <p>
<b>Returns:</b> A <b>shared_ptr&lt;T&gt;</b> instance <b>r</b> that shares <b>Returns:</b> A <b>shared_ptr&lt;T&gt;</b> instance <b>r</b> that shares
ownership with <b>p</b>. ownership with <b>p</b>.
</p> </p>
<p> <p>
<b>Postconditions:</b> <tt>r.get() == this</tt>. <b>Postconditions:</b> <tt>r.get() == this</tt>.
</p> </p>
</blockquote> </blockquote>
<p> <p>$Date$</p>
<br> <p>
<small>Copyright <EFBFBD> 2002, 2003 by Peter Dimov. Distributed under the Boost Software License, Version <small>Copyright &copy; 2002, 2003 by Peter Dimov. Distributed under the Boost Software License, Version
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or 1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or
copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p> copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
</body> </body>
</html> </html>

View 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

View 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

View File

@@ -1,83 +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 )
namespace boost
{
namespace detail
{
typedef void* sp_typeinfo;
template<class T> struct sp_typeid_
{
static char v_;
};
template<class T> char sp_typeid_< T >::v_;
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>::v_)
#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

View File

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

View File

@@ -0,0 +1,14 @@
/*
* Copyright (c) 2014 Glen Joseph Fernandes
* glenfe at live dot com
*
* Distributed under the Boost Software License,
* Version 1.0. (See accompanying file LICENSE_1_0.txt
* or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_MAKE_UNIQUE_HPP_INCLUDED
#define BOOST_MAKE_UNIQUE_HPP_INCLUDED
#include <boost/smart_ptr/make_unique.hpp>
#endif

View File

@@ -1,35 +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 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 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
};
} // namespace boost
#endif // #ifndef BOOST_MEMORY_ORDER_HPP_INCLUDED

View File

@@ -1,3 +1,6 @@
#ifndef BOOST_SMART_PTR_HPP_INCLUDED
#define BOOST_SMART_PTR_HPP_INCLUDED
// //
// smart_ptr.hpp // smart_ptr.hpp
// //
@@ -22,4 +25,7 @@
# include <boost/weak_ptr.hpp> # include <boost/weak_ptr.hpp>
# include <boost/intrusive_ptr.hpp> # include <boost/intrusive_ptr.hpp>
# include <boost/enable_shared_from_this.hpp> # include <boost/enable_shared_from_this.hpp>
# include <boost/make_shared.hpp>
#endif #endif
#endif // #ifndef BOOST_SMART_PTR_HPP_INCLUDED

View File

@@ -0,0 +1,181 @@
/*
* Copyright (c) 2012-2014 Glen Joseph Fernandes
* glenfe at live dot com
*
* Distributed under the Boost Software License,
* Version 1.0. (See accompanying file LICENSE_1_0.txt
* or copy at http://boost.org/LICENSE_1_0.txt)
*/
#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

View 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

View 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

View 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

View 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

View File

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

View File

@@ -0,0 +1,59 @@
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_NT_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_NT_HPP_INCLUDED
//
// boost/detail/atomic_count_nt.hpp
//
// Trivial atomic_count for the single-threaded case
//
// http://gcc.gnu.org/onlinedocs/porting/Thread-safety.html
//
// Copyright 2013 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
namespace boost
{
namespace detail
{
class atomic_count
{
public:
explicit atomic_count( long v ): value_( v )
{
}
long operator++()
{
return ++value_;
}
long operator--()
{
return --value_;
}
operator long() const
{
return value_;
}
private:
atomic_count(atomic_count const &);
atomic_count & operator=(atomic_count const &);
long value_;
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_NT_HPP_INCLUDED

View File

@@ -11,6 +11,7 @@
// http://www.boost.org/LICENSE_1_0.txt) // http://www.boost.org/LICENSE_1_0.txt)
// //
#include <boost/assert.hpp>
#include <pthread.h> #include <pthread.h>
// //
@@ -37,12 +38,12 @@ private:
scoped_lock(pthread_mutex_t & m): m_(m) scoped_lock(pthread_mutex_t & m): m_(m)
{ {
pthread_mutex_lock(&m_); BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
} }
~scoped_lock() ~scoped_lock()
{ {
pthread_mutex_unlock(&m_); BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
} }
private: private:
@@ -54,12 +55,12 @@ public:
explicit atomic_count(long v): value_(v) explicit atomic_count(long v): value_(v)
{ {
pthread_mutex_init(&mutex_, 0); BOOST_VERIFY( pthread_mutex_init( &mutex_, 0 ) == 0 );
} }
~atomic_count() ~atomic_count()
{ {
pthread_mutex_destroy(&mutex_); BOOST_VERIFY( pthread_mutex_destroy( &mutex_ ) == 0 );
} }
long operator++() long operator++()

View File

@@ -0,0 +1,62 @@
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SPIN_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SPIN_HPP_INCLUDED
//
// boost/detail/atomic_count_spin.hpp
//
// Copyright (c) 2013 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
#include <boost/smart_ptr/detail/spinlock_pool.hpp>
namespace boost
{
namespace detail
{
class atomic_count
{
private:
public:
explicit atomic_count( long v ): value_( v )
{
}
long operator++()
{
spinlock_pool<0>::scoped_lock lock( &value_ );
return ++value_;
}
long operator--()
{
spinlock_pool<0>::scoped_lock lock( &value_ );
return --value_;
}
operator long() const
{
spinlock_pool<0>::scoped_lock lock( &value_ );
return value_;
}
private:
atomic_count(atomic_count const &);
atomic_count & operator=(atomic_count const &);
long value_;
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SPIN_HPP_INCLUDED

View File

@@ -0,0 +1,60 @@
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_STD_ATOMIC_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_STD_ATOMIC_HPP_INCLUDED
//
// boost/detail/atomic_count_std_atomic.hpp
//
// atomic_count for std::atomic
//
// Copyright 2013 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
#include <atomic>
#include <cstdint>
namespace boost
{
namespace detail
{
class atomic_count
{
public:
explicit atomic_count( long v ): value_( v )
{
}
long operator++()
{
return value_.fetch_add( 1, std::memory_order_acq_rel ) + 1;
}
long operator--()
{
return value_.fetch_sub( 1, std::memory_order_acq_rel ) - 1;
}
operator long() const
{
return value_.load( std::memory_order_acquire );
}
private:
atomic_count(atomic_count const &);
atomic_count & operator=(atomic_count const &);
std::atomic_int_least32_t value_;
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_STD_ATOMIC_HPP_INCLUDED

View File

@@ -17,7 +17,7 @@
// http://www.boost.org/LICENSE_1_0.txt) // http://www.boost.org/LICENSE_1_0.txt)
// //
#include <boost/detail/interlocked.hpp> #include <boost/smart_ptr/detail/sp_interlocked.hpp>
namespace boost namespace boost
{ {
@@ -35,12 +35,12 @@ public:
long operator++() long operator++()
{ {
return BOOST_INTERLOCKED_INCREMENT( &value_ ); return BOOST_SP_INTERLOCKED_INCREMENT( &value_ );
} }
long operator--() long operator--()
{ {
return BOOST_INTERLOCKED_DECREMENT( &value_ ); return BOOST_SP_INTERLOCKED_DECREMENT( &value_ );
} }
operator long() const operator long() const

View File

@@ -17,6 +17,7 @@
// http://www.boost.org/LICENSE_1_0.txt) // http://www.boost.org/LICENSE_1_0.txt)
// //
#include <boost/assert.hpp>
#include <pthread.h> #include <pthread.h>
namespace boost namespace boost
@@ -42,15 +43,15 @@ public:
// HPUX 10.20 / DCE has a nonstandard pthread_mutex_init // HPUX 10.20 / DCE has a nonstandard pthread_mutex_init
#if defined(__hpux) && defined(_DECTHREADS_) #if defined(__hpux) && defined(_DECTHREADS_)
pthread_mutex_init(&m_, pthread_mutexattr_default); BOOST_VERIFY( pthread_mutex_init( &m_, pthread_mutexattr_default ) == 0 );
#else #else
pthread_mutex_init(&m_, 0); BOOST_VERIFY( pthread_mutex_init( &m_, 0 ) == 0 );
#endif #endif
} }
~lightweight_mutex() ~lightweight_mutex()
{ {
pthread_mutex_destroy(&m_); BOOST_VERIFY( pthread_mutex_destroy( &m_ ) == 0 );
} }
class scoped_lock; class scoped_lock;
@@ -69,12 +70,12 @@ public:
scoped_lock(lightweight_mutex & m): m_(m.m_) scoped_lock(lightweight_mutex & m): m_(m.m_)
{ {
pthread_mutex_lock(&m_); BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
} }
~scoped_lock() ~scoped_lock()
{ {
pthread_mutex_unlock(&m_); BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
} }
}; };
}; };

View File

@@ -11,12 +11,15 @@
// boost/detail/lwm_win32_cs.hpp // boost/detail/lwm_win32_cs.hpp
// //
// Copyright (c) 2002, 2003 Peter Dimov // Copyright (c) 2002, 2003 Peter Dimov
// Copyright (c) Microsoft Corporation 2014
// //
// Distributed under the Boost Software License, Version 1.0. (See // Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at // accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt) // http://www.boost.org/LICENSE_1_0.txt)
// //
#include <boost/predef.h>
#ifdef BOOST_USE_WINDOWS_H #ifdef BOOST_USE_WINDOWS_H
# include <windows.h> # include <windows.h>
#endif #endif
@@ -43,7 +46,11 @@ struct critical_section
#endif #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 *); 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 EnterCriticalSection(critical_section *);
extern "C" __declspec(dllimport) void __stdcall LeaveCriticalSection(critical_section *); extern "C" __declspec(dllimport) void __stdcall LeaveCriticalSection(critical_section *);
extern "C" __declspec(dllimport) void __stdcall DeleteCriticalSection(critical_section *); extern "C" __declspec(dllimport) void __stdcall DeleteCriticalSection(critical_section *);
@@ -67,7 +74,11 @@ public:
lightweight_mutex() lightweight_mutex()
{ {
#if BOOST_PLAT_WINDOWS_RUNTIME
InitializeCriticalSectionEx(&cs_, 4000, 0);
#else
InitializeCriticalSection(&cs_); InitializeCriticalSection(&cs_);
#endif
} }
~lightweight_mutex() ~lightweight_mutex()

View File

@@ -1,14 +1,21 @@
// This header intentionally has no include guards. // 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. // Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at // See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt // http://www.boost.org/LICENSE_1_0.txt
#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; return px != 0;
} }
@@ -21,7 +28,7 @@
typedef void (*unspecified_bool_type)( this_type*** ); 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; return px == 0? 0: unspecified_bool;
} }
@@ -31,18 +38,18 @@
( defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 304) ) || \ ( defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 304) ) || \
( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x590) ) ( 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; return px == 0? 0: &this_type::get;
} }
#else #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; return px == 0? 0: &this_type::px;
} }
@@ -50,7 +57,7 @@
#endif #endif
// operator! is redundant, but some compilers need it // operator! is redundant, but some compilers need it
bool operator! () const // never throws bool operator! () const BOOST_NOEXCEPT
{ {
return px == 0; return px == 0;
} }

View File

@@ -74,8 +74,9 @@ template<unsigned size, unsigned align_> struct allocator_impl
static lightweight_mutex & mutex() static lightweight_mutex & mutex()
{ {
static lightweight_mutex m; static freeblock< sizeof( lightweight_mutex ), boost::alignment_of< lightweight_mutex >::value > fbm;
return m; static lightweight_mutex * pm = new( &fbm ) lightweight_mutex;
return *pm;
} }
static lightweight_mutex * mutex_init; static lightweight_mutex * mutex_init;

View File

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

View File

@@ -35,7 +35,14 @@
// rather than including <memory> directly: // rather than including <memory> directly:
#include <boost/config/no_tr1/memory.hpp> // std::auto_ptr #include <boost/config/no_tr1/memory.hpp> // std::auto_ptr
#include <functional> // std::less #include <functional> // std::less
#include <new> // std::bad_alloc
#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 namespace boost
{ {
@@ -52,6 +59,42 @@ int const weak_count_id = 0x298C38A4;
struct sp_nothrow_tag {}; struct sp_nothrow_tag {};
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 weak_count;
class shared_count class shared_count
@@ -142,22 +185,75 @@ public:
#endif #endif
} }
#if !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
template< class P, class D > shared_count( P p, sp_inplace_tag<D> ): pi_( 0 )
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#endif
{
#ifndef BOOST_NO_EXCEPTIONS
try
{
pi_ = new sp_counted_impl_pd< P, D >( p );
}
catch( ... )
{
D::operator_fn( p ); // delete p
throw;
}
#else
pi_ = new sp_counted_impl_pd< P, D >( p );
if( pi_ == 0 )
{
D::operator_fn( p ); // delete p
boost::throw_exception( std::bad_alloc() );
}
#endif // #ifndef BOOST_NO_EXCEPTIONS
}
#endif // !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
template<class P, class D, class A> shared_count( P p, D d, A a ): pi_( 0 ) template<class P, class D, class A> shared_count( P p, D d, A a ): pi_( 0 )
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id) , id_(shared_count_id)
#endif #endif
{ {
typedef sp_counted_impl_pda<P, D, A> impl_type; typedef sp_counted_impl_pda<P, D, A> impl_type;
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
typedef typename std::allocator_traits<A>::template rebind_alloc< impl_type > A2;
#else
typedef typename A::template rebind< impl_type >::other A2; typedef typename A::template rebind< impl_type >::other A2;
#endif
A2 a2( a ); A2 a2( a );
#ifndef BOOST_NO_EXCEPTIONS #ifndef BOOST_NO_EXCEPTIONS
try try
{ {
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
impl_type * pi = std::allocator_traits<A2>::allocate( a2, 1 );
pi_ = pi;
std::allocator_traits<A2>::construct( a2, pi, p, d, a );
#else
pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) ); pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
new( static_cast< void* >( pi_ ) ) impl_type( p, d, a ); ::new( static_cast< void* >( pi_ ) ) impl_type( p, d, a );
#endif
} }
catch(...) catch(...)
{ {
@@ -171,13 +267,30 @@ public:
throw; throw;
} }
#else
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
impl_type * pi = std::allocator_traits<A2>::allocate( a2, 1 );
pi_ = pi;
#else #else
pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) ); pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
#endif
if( pi_ != 0 ) if( pi_ != 0 )
{ {
new( static_cast< void* >( pi_ ) ) impl_type( p, d, a ); #if !defined( BOOST_NO_CXX11_ALLOCATOR )
std::allocator_traits<A2>::construct( a2, pi, p, d, a );
#else
::new( static_cast< void* >( pi_ ) ) impl_type( p, d, a );
#endif
} }
else else
{ {
@@ -188,6 +301,92 @@ public:
#endif #endif
} }
#if !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
template< class P, class D, class A > shared_count( P p, sp_inplace_tag< D >, A a ): pi_( 0 )
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#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 );
#endif
}
catch(...)
{
D::operator_fn( p );
if( pi_ != 0 )
{
a2.deallocate( static_cast< impl_type* >( pi_ ), 1 );
}
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 )
{
#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::operator_fn( p );
boost::throw_exception( std::bad_alloc() );
}
#endif // #ifndef BOOST_NO_EXCEPTIONS
}
#endif // !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
#ifndef BOOST_NO_AUTO_PTR #ifndef BOOST_NO_AUTO_PTR
// auto_ptr<Y> is special cased to provide the strong guarantee // auto_ptr<Y> is special cased to provide the strong guarantee
@@ -212,6 +411,33 @@ public:
#endif #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 ~shared_count() // nothrow
{ {
if( pi_ != 0 ) pi_->release(); if( pi_ != 0 ) pi_->release();
@@ -228,7 +454,7 @@ public:
if( pi_ != 0 ) pi_->add_ref_copy(); 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 shared_count(shared_count && r): pi_(r.pi_) // nothrow
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
@@ -293,6 +519,11 @@ public:
{ {
return pi_? pi_->get_deleter( ti ): 0; return pi_? pi_->get_deleter( ti ): 0;
} }
void * get_untyped_deleter() const
{
return pi_? pi_->get_untyped_deleter(): 0;
}
}; };
@@ -335,7 +566,7 @@ public:
// Move support // Move support
#if defined( BOOST_HAS_RVALUE_REFS ) #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
weak_count(weak_count && r): pi_(r.pi_) // nothrow weak_count(weak_count && r): pi_(r.pi_) // nothrow
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)

View File

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

View File

@@ -25,7 +25,7 @@
# define BOOST_SP_NO_SP_CONVERTIBLE # define BOOST_SP_NO_SP_CONVERTIBLE
#endif #endif
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( __BORLANDC__ ) && ( __BORLANDC__ <= 0x610 ) #if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( __BORLANDC__ ) && ( __BORLANDC__ < 0x630 )
# define BOOST_SP_NO_SP_CONVERTIBLE # define BOOST_SP_NO_SP_CONVERTIBLE
#endif #endif
@@ -45,7 +45,22 @@ template< class Y, class T > struct sp_convertible
static yes f( T* ); static yes f( T* );
static no f( ... ); static no f( ... );
enum _vt { value = sizeof( f( static_cast<Y*>(0) ) ) == sizeof(yes) }; 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 struct sp_empty

View File

@@ -10,7 +10,7 @@
// //
// detail/sp_counted_base.hpp // detail/sp_counted_base.hpp
// //
// Copyright 2005, 2006 Peter Dimov // Copyright 2005-2013 Peter Dimov
// //
// Distributed under the Boost Software License, Version 1.0. (See // Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at // accompanying file LICENSE_1_0.txt or copy at
@@ -23,6 +23,9 @@
#if defined( BOOST_SP_DISABLE_THREADS ) #if defined( BOOST_SP_DISABLE_THREADS )
# include <boost/smart_ptr/detail/sp_counted_base_nt.hpp> # include <boost/smart_ptr/detail/sp_counted_base_nt.hpp>
#elif defined( BOOST_SP_USE_STD_ATOMIC )
# include <boost/smart_ptr/detail/sp_counted_base_std_atomic.hpp>
#elif defined( BOOST_SP_USE_SPINLOCK ) #elif defined( BOOST_SP_USE_SPINLOCK )
# include <boost/smart_ptr/detail/sp_counted_base_spin.hpp> # include <boost/smart_ptr/detail/sp_counted_base_spin.hpp>
@@ -32,22 +35,28 @@
#elif defined( BOOST_DISABLE_THREADS ) && !defined( BOOST_SP_ENABLE_THREADS ) && !defined( BOOST_DISABLE_WIN32 ) #elif defined( BOOST_DISABLE_THREADS ) && !defined( BOOST_SP_ENABLE_THREADS ) && !defined( BOOST_DISABLE_WIN32 )
# include <boost/smart_ptr/detail/sp_counted_base_nt.hpp> # include <boost/smart_ptr/detail/sp_counted_base_nt.hpp>
#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) #elif defined( __SNC__ )
# include <boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp> # include <boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp>
#elif defined( __GNUC__ ) && defined( __ia64__ ) && !defined( __INTEL_COMPILER ) #elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) && !defined(__PATHSCALE__)
# include <boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp> # include <boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp>
#elif defined(__HP_aCC) && defined(__ia64) #elif defined(__HP_aCC) && defined(__ia64)
# include <boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp> # 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__ ) #elif defined( __MWERKS__ ) && defined( __POWERPC__ )
# include <boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp> # 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> # 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> # include <boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp>
#elif defined( BOOST_SP_HAS_SYNC ) #elif defined( BOOST_SP_HAS_SYNC )
@@ -59,6 +68,9 @@
#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined(__CYGWIN__) #elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined(__CYGWIN__)
# include <boost/smart_ptr/detail/sp_counted_base_w32.hpp> # include <boost/smart_ptr/detail/sp_counted_base_w32.hpp>
#elif defined( _AIX )
# include <boost/smart_ptr/detail/sp_counted_base_aix.hpp>
#elif !defined( BOOST_HAS_THREADS ) #elif !defined( BOOST_HAS_THREADS )
# include <boost/smart_ptr/detail/sp_counted_base_nt.hpp> # include <boost/smart_ptr/detail/sp_counted_base_nt.hpp>

View File

@@ -104,6 +104,7 @@ public:
} }
virtual void * get_deleter( sp_typeinfo const & ti ) = 0; virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy() void add_ref_copy()
{ {

View File

@@ -0,0 +1,143 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_AIX_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_AIX_HPP_INCLUDED
//
// detail/sp_counted_base_aix.hpp
// 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
//
// 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>
#include <builtins.h>
#include <sys/atomic_op.h>
namespace boost
{
namespace detail
{
inline void atomic_increment( int32_t* pw )
{
// ++*pw;
fetch_and_add( pw, 1 );
}
inline int32_t atomic_decrement( int32_t * pw )
{
// return --*pw;
int32_t originalValue;
__lwsync();
originalValue = fetch_and_add( pw, -1 );
__isync();
return (originalValue - 1);
}
inline int32_t atomic_conditional_increment( int32_t * pw )
{
// if( *pw != 0 ) ++*pw;
// return *pw;
int32_t tmp = fetch_and_add( pw, 0 );
for( ;; )
{
if( tmp == 0 ) return 0;
if( compare_and_swap( pw, &tmp, tmp + 1 ) ) return (tmp + 1);
}
}
class sp_counted_base
{
private:
sp_counted_base( sp_counted_base const & );
sp_counted_base & operator= ( sp_counted_base const & );
int32_t use_count_; // #shared
int32_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_ ) == 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 fetch_and_add( const_cast<int32_t*>(&use_count_), 0 );
}
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_AIX_HPP_INCLUDED

View File

@@ -124,6 +124,7 @@ public:
} }
virtual void * get_deleter( sp_typeinfo const & ti ) = 0; virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy() void add_ref_copy()
{ {

View File

@@ -112,6 +112,7 @@ public:
} }
virtual void * get_deleter( sp_typeinfo const & ti ) = 0; virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy() void add_ref_copy()
{ {

View File

@@ -111,6 +111,7 @@ public:
} }
virtual void * get_deleter( sp_typeinfo const & ti ) = 0; virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy() void add_ref_copy()
{ {

View File

@@ -37,9 +37,12 @@ inline void atomic_increment( int * pw )
__asm__ __volatile__ __asm__ __volatile__
( (
"0:\n\t" "0:\n\t"
".set push\n\t"
".set mips2\n\t"
"ll %0, %1\n\t" "ll %0, %1\n\t"
"addiu %0, 1\n\t" "addiu %0, 1\n\t"
"sc %0, %1\n\t" "sc %0, %1\n\t"
".set pop\n\t"
"beqz %0, 0b": "beqz %0, 0b":
"=&r"( tmp ), "=m"( *pw ): "=&r"( tmp ), "=m"( *pw ):
"m"( *pw ) "m"( *pw )
@@ -55,9 +58,12 @@ inline int atomic_decrement( int * pw )
__asm__ __volatile__ __asm__ __volatile__
( (
"0:\n\t" "0:\n\t"
".set push\n\t"
".set mips2\n\t"
"ll %1, %2\n\t" "ll %1, %2\n\t"
"addiu %0, %1, -1\n\t" "addiu %0, %1, -1\n\t"
"sc %0, %2\n\t" "sc %0, %2\n\t"
".set pop\n\t"
"beqz %0, 0b\n\t" "beqz %0, 0b\n\t"
"addiu %0, %1, -1": "addiu %0, %1, -1":
"=&r"( rv ), "=&r"( tmp ), "=m"( *pw ): "=&r"( rv ), "=&r"( tmp ), "=m"( *pw ):
@@ -78,10 +84,13 @@ inline int atomic_conditional_increment( int * pw )
__asm__ __volatile__ __asm__ __volatile__
( (
"0:\n\t" "0:\n\t"
".set push\n\t"
".set mips2\n\t"
"ll %0, %2\n\t" "ll %0, %2\n\t"
"beqz %0, 1f\n\t" "beqz %0, 1f\n\t"
"addiu %1, %0, 1\n\t" "addiu %1, %0, 1\n\t"
"sc %1, %2\n\t" "sc %1, %2\n\t"
".set pop\n\t"
"beqz %1, 0b\n\t" "beqz %1, 0b\n\t"
"addiu %0, %0, 1\n\t" "addiu %0, %0, 1\n\t"
"1:": "1:":
@@ -126,6 +135,7 @@ public:
} }
virtual void * get_deleter( sp_typeinfo const & ti ) = 0; virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy() void add_ref_copy()
{ {

View File

@@ -135,6 +135,7 @@ public:
} }
virtual void * get_deleter( sp_typeinfo const & ti ) = 0; virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy() void add_ref_copy()
{ {

View File

@@ -30,9 +30,9 @@ namespace detail
inline int32_t compare_and_swap( int32_t * dest_, int32_t compare_, int32_t swap_ ) inline int32_t compare_and_swap( int32_t * dest_, int32_t compare_, int32_t swap_ )
{ {
__asm__ __volatile__( "cas %0, %2, %1" __asm__ __volatile__( "cas [%1], %2, %0"
: "+m" (*dest_), "+r" (swap_) : "+r" (swap_)
: "r" (compare_) : "r" (dest_), "r" (compare_)
: "memory" ); : "memory" );
return swap_; return swap_;
@@ -120,6 +120,7 @@ public:
} }
virtual void * get_deleter( sp_typeinfo const & ti ) = 0; virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy() void add_ref_copy()
{ {

View File

@@ -127,6 +127,7 @@ public:
} }
virtual void * get_deleter( sp_typeinfo const & ti ) = 0; virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy() void add_ref_copy()
{ {

View File

@@ -59,6 +59,7 @@ public:
} }
virtual void * get_deleter( sp_typeinfo const & ti ) = 0; virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy() void add_ref_copy()
{ {

View File

@@ -19,6 +19,7 @@
// //
#include <boost/detail/sp_typeinfo.hpp> #include <boost/detail/sp_typeinfo.hpp>
#include <boost/assert.hpp>
#include <pthread.h> #include <pthread.h>
namespace boost namespace boost
@@ -46,15 +47,15 @@ public:
// HPUX 10.20 / DCE has a nonstandard pthread_mutex_init // HPUX 10.20 / DCE has a nonstandard pthread_mutex_init
#if defined(__hpux) && defined(_DECTHREADS_) #if defined(__hpux) && defined(_DECTHREADS_)
pthread_mutex_init( &m_, pthread_mutexattr_default ); BOOST_VERIFY( pthread_mutex_init( &m_, pthread_mutexattr_default ) == 0 );
#else #else
pthread_mutex_init( &m_, 0 ); BOOST_VERIFY( pthread_mutex_init( &m_, 0 ) == 0 );
#endif #endif
} }
virtual ~sp_counted_base() // nothrow virtual ~sp_counted_base() // nothrow
{ {
pthread_mutex_destroy( &m_ ); BOOST_VERIFY( pthread_mutex_destroy( &m_ ) == 0 );
} }
// dispose() is called when use_count_ drops to zero, to release // dispose() is called when use_count_ drops to zero, to release
@@ -70,27 +71,28 @@ public:
} }
virtual void * get_deleter( sp_typeinfo const & ti ) = 0; virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy() void add_ref_copy()
{ {
pthread_mutex_lock( &m_ ); BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
++use_count_; ++use_count_;
pthread_mutex_unlock( &m_ ); BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
} }
bool add_ref_lock() // true on success bool add_ref_lock() // true on success
{ {
pthread_mutex_lock( &m_ ); BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
bool r = use_count_ == 0? false: ( ++use_count_, true ); bool r = use_count_ == 0? false: ( ++use_count_, true );
pthread_mutex_unlock( &m_ ); BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
return r; return r;
} }
void release() // nothrow void release() // nothrow
{ {
pthread_mutex_lock( &m_ ); BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
long new_use_count = --use_count_; long new_use_count = --use_count_;
pthread_mutex_unlock( &m_ ); BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
if( new_use_count == 0 ) if( new_use_count == 0 )
{ {
@@ -101,16 +103,16 @@ public:
void weak_add_ref() // nothrow void weak_add_ref() // nothrow
{ {
pthread_mutex_lock( &m_ ); BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
++weak_count_; ++weak_count_;
pthread_mutex_unlock( &m_ ); BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
} }
void weak_release() // nothrow void weak_release() // nothrow
{ {
pthread_mutex_lock( &m_ ); BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
long new_weak_count = --weak_count_; long new_weak_count = --weak_count_;
pthread_mutex_unlock( &m_ ); BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
if( new_weak_count == 0 ) if( new_weak_count == 0 )
{ {
@@ -120,9 +122,9 @@ public:
long use_count() const // nothrow long use_count() const // nothrow
{ {
pthread_mutex_lock( &m_ ); BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
long r = use_count_; long r = use_count_;
pthread_mutex_unlock( &m_ ); BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
return r; return r;
} }

View File

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

View File

@@ -62,6 +62,7 @@ public:
} }
virtual void * get_deleter( sp_typeinfo const & ti ) = 0; virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy() void add_ref_copy()
{ {

View File

@@ -84,6 +84,7 @@ public:
} }
virtual void * get_deleter( sp_typeinfo const & ti ) = 0; virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy() void add_ref_copy()
{ {

View File

@@ -0,0 +1,137 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_STD_ATOMIC_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_STD_ATOMIC_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
// detail/sp_counted_base_std_atomic.hpp - C++11 std::atomic
//
// Copyright (c) 2007, 2013 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/detail/sp_typeinfo.hpp>
#include <atomic>
#include <cstdint>
namespace boost
{
namespace detail
{
inline void atomic_increment( std::atomic_int_least32_t * pw )
{
pw->fetch_add( 1, std::memory_order_relaxed );
}
inline std::int_least32_t atomic_decrement( std::atomic_int_least32_t * pw )
{
return pw->fetch_sub( 1, std::memory_order_acq_rel );
}
inline std::int_least32_t atomic_conditional_increment( std::atomic_int_least32_t * pw )
{
// long r = *pw;
// if( r != 0 ) ++*pw;
// return r;
std::int_least32_t r = pw->load( std::memory_order_relaxed );
for( ;; )
{
if( r == 0 )
{
return r;
}
if( pw->compare_exchange_weak( r, r + 1, std::memory_order_relaxed, std::memory_order_relaxed ) )
{
return r;
}
}
}
class sp_counted_base
{
private:
sp_counted_base( sp_counted_base const & );
sp_counted_base & operator= ( sp_counted_base const & );
std::atomic_int_least32_t use_count_; // #shared
std::atomic_int_least32_t weak_count_; // #weak + (#shared != 0)
public:
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
{
}
virtual ~sp_counted_base() // nothrow
{
}
// dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this.
virtual void dispose() = 0; // nothrow
// destroy() is called when weak_count_ drops to zero.
virtual void destroy() // nothrow
{
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy()
{
atomic_increment( &use_count_ );
}
bool add_ref_lock() // true on success
{
return atomic_conditional_increment( &use_count_ ) != 0;
}
void release() // nothrow
{
if( atomic_decrement( &use_count_ ) == 1 )
{
dispose();
weak_release();
}
}
void weak_add_ref() // nothrow
{
atomic_increment( &weak_count_ );
}
void weak_release() // nothrow
{
if( atomic_decrement( &weak_count_ ) == 1 )
{
destroy();
}
}
long use_count() const // nothrow
{
return use_count_.load( std::memory_order_acquire );
}
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_STD_ATOMIC_HPP_INCLUDED

View File

@@ -109,6 +109,7 @@ public:
} }
virtual void * get_deleter( sp_typeinfo const & ti ) = 0; virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy() void add_ref_copy()
{ {

View 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

View File

@@ -24,7 +24,7 @@
// formulation // formulation
// //
#include <boost/detail/interlocked.hpp> #include <boost/smart_ptr/detail/sp_interlocked.hpp>
#include <boost/detail/workaround.hpp> #include <boost/detail/workaround.hpp>
#include <boost/detail/sp_typeinfo.hpp> #include <boost/detail/sp_typeinfo.hpp>
@@ -67,10 +67,11 @@ public:
} }
virtual void * get_deleter( sp_typeinfo const & ti ) = 0; virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy() void add_ref_copy()
{ {
BOOST_INTERLOCKED_INCREMENT( &use_count_ ); BOOST_SP_INTERLOCKED_INCREMENT( &use_count_ );
} }
bool add_ref_lock() // true on success bool add_ref_lock() // true on success
@@ -85,11 +86,11 @@ public:
// work around a code generation bug // work around a code generation bug
long tmp2 = tmp + 1; 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 #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 #endif
} }
@@ -97,7 +98,7 @@ public:
void release() // nothrow void release() // nothrow
{ {
if( BOOST_INTERLOCKED_DECREMENT( &use_count_ ) == 0 ) if( BOOST_SP_INTERLOCKED_DECREMENT( &use_count_ ) == 0 )
{ {
dispose(); dispose();
weak_release(); weak_release();
@@ -106,12 +107,12 @@ public:
void weak_add_ref() // nothrow void weak_add_ref() // nothrow
{ {
BOOST_INTERLOCKED_INCREMENT( &weak_count_ ); BOOST_SP_INTERLOCKED_INCREMENT( &weak_count_ );
} }
void weak_release() // nothrow void weak_release() // nothrow
{ {
if( BOOST_INTERLOCKED_DECREMENT( &weak_count_ ) == 0 ) if( BOOST_SP_INTERLOCKED_DECREMENT( &weak_count_ ) == 0 )
{ {
destroy(); destroy();
} }

View File

@@ -83,6 +83,11 @@ public:
return 0; return 0;
} }
virtual void * get_untyped_deleter()
{
return 0;
}
#if defined(BOOST_SP_USE_STD_ALLOCATOR) #if defined(BOOST_SP_USE_STD_ALLOCATOR)
void * operator new( std::size_t ) void * operator new( std::size_t )
@@ -135,7 +140,11 @@ public:
// pre: d(p) must not throw // pre: d(p) must not throw
sp_counted_impl_pd( P p, D d ): ptr(p), del(d) sp_counted_impl_pd( P p, D & d ): ptr( p ), del( d )
{
}
sp_counted_impl_pd( P p ): ptr( p ), del()
{ {
} }
@@ -149,6 +158,11 @@ public:
return ti == BOOST_SP_TYPEID(D)? &reinterpret_cast<char&>( del ): 0; 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) #if defined(BOOST_SP_USE_STD_ALLOCATOR)
void * operator new( std::size_t ) void * operator new( std::size_t )
@@ -195,7 +209,11 @@ public:
// pre: d( p ) must not throw // pre: d( p ) must not throw
sp_counted_impl_pda( P p, D d, A a ): p_( p ), d_( d ), a_( a ) sp_counted_impl_pda( P p, D & d, A a ): p_( p ), d_( d ), a_( a )
{
}
sp_counted_impl_pda( P p, A a ): p_( p ), d_( a ), a_( a )
{ {
} }
@@ -206,11 +224,28 @@ public:
virtual void destroy() // nothrow virtual void destroy() // nothrow
{ {
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
typedef typename std::allocator_traits<A>::template rebind_alloc< this_type > A2;
#else
typedef typename A::template rebind< this_type >::other A2; typedef typename A::template rebind< this_type >::other A2;
#endif
A2 a2( a_ ); A2 a2( a_ );
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
std::allocator_traits<A2>::destroy( a2, this );
#else
this->~this_type(); this->~this_type();
#endif
a2.deallocate( this, 1 ); a2.deallocate( this, 1 );
} }
@@ -218,6 +253,11 @@ public:
{ {
return ti == BOOST_SP_TYPEID( D )? &reinterpret_cast<char&>( d_ ): 0; return ti == BOOST_SP_TYPEID( D )? &reinterpret_cast<char&>( d_ ): 0;
} }
virtual void * get_untyped_deleter()
{
return &reinterpret_cast<char&>( d_ );
}
}; };
#ifdef __CODEGUARD__ #ifdef __CODEGUARD__

View 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

View File

@@ -20,7 +20,17 @@
// are available. // are available.
// //
#if defined(__GNUC__) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 ) #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 #define BOOST_SP_HAS_SYNC
@@ -36,14 +46,24 @@
#undef BOOST_SP_HAS_SYNC #undef BOOST_SP_HAS_SYNC
#endif #endif
#if defined( __sh__ )
#undef BOOST_SP_HAS_SYNC
#endif
#if defined( __sparc__ ) #if defined( __sparc__ )
#undef BOOST_SP_HAS_SYNC #undef BOOST_SP_HAS_SYNC
#endif #endif
#if defined( __INTEL_COMPILER ) && !defined( __ia64__ ) #if defined( __INTEL_COMPILER ) && !defined( __ia64__ ) && ( __INTEL_COMPILER < 1110 )
#undef BOOST_SP_HAS_SYNC #undef BOOST_SP_HAS_SYNC
#endif #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 #endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_HPP_INCLUDED

View 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

View 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

View 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

View File

@@ -31,7 +31,19 @@
#include <boost/config.hpp> #include <boost/config.hpp>
#include <boost/smart_ptr/detail/sp_has_sync.hpp> #include <boost/smart_ptr/detail/sp_has_sync.hpp>
#if defined(__GNUC__) && defined( __arm__ ) && !defined( __thumb__ ) #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__ )
# include <boost/smart_ptr/detail/spinlock_gcc_arm.hpp> # include <boost/smart_ptr/detail/spinlock_gcc_arm.hpp>
#elif defined( BOOST_SP_HAS_SYNC ) #elif defined( BOOST_SP_HAS_SYNC )

View File

@@ -2,7 +2,7 @@
#define BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED #define BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED
// //
// Copyright (c) 2008 Peter Dimov // Copyright (c) 2008, 2011 Peter Dimov
// //
// Distributed under the Boost Software License, Version 1.0. // Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at // See accompanying file LICENSE_1_0.txt or copy at
@@ -11,6 +11,22 @@
#include <boost/smart_ptr/detail/yield_k.hpp> #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__) || 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
# define BOOST_SP_ARM_BARRIER ""
#endif
namespace boost namespace boost
{ {
@@ -29,12 +45,28 @@ public:
{ {
int r; int r;
#ifdef BOOST_SP_ARM_HAS_LDREX
__asm__ __volatile__( __asm__ __volatile__(
"swp %0, %1, [%2]": "ldrex %0, [%2]; \n"
"cmp %0, %1; \n"
"strexne %0, %1, [%2]; \n"
BOOST_SP_ARM_BARRIER :
"=&r"( r ): // outputs "=&r"( r ): // outputs
"r"( 1 ), "r"( &v_ ): // inputs "r"( 1 ), "r"( &v_ ): // inputs
"memory", "cc" ); "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; return r == 0;
} }
@@ -48,7 +80,7 @@ public:
void unlock() void unlock()
{ {
__asm__ __volatile__( "" ::: "memory" ); __asm__ __volatile__( BOOST_SP_ARM_BARRIER ::: "memory" );
*const_cast< int volatile* >( &v_ ) = 0; *const_cast< int volatile* >( &v_ ) = 0;
} }
@@ -82,4 +114,7 @@ public:
#define BOOST_DETAIL_SPINLOCK_INIT {0} #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 #endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED

View File

@@ -41,7 +41,11 @@ public:
static spinlock & spinlock_for( void const * pv ) static spinlock & spinlock_for( void const * pv )
{ {
#if defined(__VMS) && __INITIAL_POINTER_SIZE == 64
std::size_t i = reinterpret_cast< unsigned long long >( pv ) % 41;
#else
std::size_t i = reinterpret_cast< std::size_t >( pv ) % 41; std::size_t i = reinterpret_cast< std::size_t >( pv ) % 41;
#endif
return pool_[ i ]; return pool_[ i ];
} }

View 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

View File

@@ -15,7 +15,7 @@
// http://www.boost.org/LICENSE_1_0.txt) // 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> #include <boost/smart_ptr/detail/yield_k.hpp>
// BOOST_COMPILER_FENCE // BOOST_COMPILER_FENCE
@@ -59,7 +59,7 @@ public:
bool try_lock() bool try_lock()
{ {
long r = BOOST_INTERLOCKED_EXCHANGE( &v_, 1 ); long r = BOOST_SP_INTERLOCKED_EXCHANGE( &v_, 1 );
BOOST_COMPILER_FENCE BOOST_COMPILER_FENCE

View File

@@ -0,0 +1,26 @@
/*
* Copyright (c) 2014 Glen Joseph Fernandes
* glenfe at live dot com
*
* Distributed under the Boost Software License,
* Version 1.0. (See accompanying file LICENSE_1_0.txt
* or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_SMART_PTR_DETAIL_UP_IF_ARRAY_HPP
#define BOOST_SMART_PTR_DETAIL_UP_IF_ARRAY_HPP
#include <memory>
namespace boost {
namespace detail {
template<class T>
struct up_if_array;
template<class T>
struct up_if_array<T[]> {
typedef std::unique_ptr<T[]> type;
};
}
}
#endif

View File

@@ -0,0 +1,31 @@
/*
* Copyright (c) 2014 Glen Joseph Fernandes
* glenfe at live dot com
*
* Distributed under the Boost Software License,
* Version 1.0. (See accompanying file LICENSE_1_0.txt
* or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_SMART_PTR_DETAIL_UP_IF_NOT_ARRAY_HPP
#define BOOST_SMART_PTR_DETAIL_UP_IF_NOT_ARRAY_HPP
#include <memory>
namespace boost {
namespace detail {
template<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

View File

@@ -11,6 +11,7 @@
// yield_k.hpp // yield_k.hpp
// //
// Copyright (c) 2008 Peter Dimov // Copyright (c) 2008 Peter Dimov
// Copyright (c) Microsoft Corporation 2014
// //
// void yield( unsigned k ); // void yield( unsigned k );
// //
@@ -24,13 +25,17 @@
// //
#include <boost/config.hpp> #include <boost/config.hpp>
#include <boost/predef.h>
#if BOOST_PLAT_WINDOWS_RUNTIME
#include <thread>
#endif
// BOOST_SMT_PAUSE // BOOST_SMT_PAUSE
#if defined(_MSC_VER) && _MSC_VER >= 1310 && ( defined(_M_IX86) || defined(_M_X64) ) #if defined(_MSC_VER) && _MSC_VER >= 1310 && ( defined(_M_IX86) || defined(_M_X64) )
extern "C" void _mm_pause(); extern "C" void _mm_pause();
#pragma intrinsic( _mm_pause )
#define BOOST_SMT_PAUSE _mm_pause(); #define BOOST_SMT_PAUSE _mm_pause();
@@ -54,8 +59,8 @@ namespace boost
namespace detail namespace detail
{ {
#if !defined( BOOST_USE_WINDOWS_H ) #if !defined( BOOST_USE_WINDOWS_H ) && !BOOST_PLAT_WINDOWS_RUNTIME
extern "C" void __stdcall Sleep( unsigned ms ); extern "C" void __stdcall Sleep( unsigned long ms );
#endif #endif
inline void yield( unsigned k ) inline void yield( unsigned k )
@@ -69,6 +74,7 @@ inline void yield( unsigned k )
BOOST_SMT_PAUSE BOOST_SMT_PAUSE
} }
#endif #endif
#if !BOOST_PLAT_WINDOWS_RUNTIME
else if( k < 32 ) else if( k < 32 )
{ {
Sleep( 0 ); Sleep( 0 );
@@ -77,6 +83,13 @@ inline void yield( unsigned k )
{ {
Sleep( 1 ); Sleep( 1 );
} }
#else
else
{
// Sleep isn't supported on the Windows Runtime.
std::this_thread::yield();
}
#endif
} }
} // namespace detail } // namespace detail

View 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

View File

@@ -25,20 +25,20 @@ template<class T> class enable_shared_from_this
{ {
protected: 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; return *this;
} }
~enable_shared_from_this() ~enable_shared_from_this() BOOST_NOEXCEPT // ~weak_ptr<T> newer throws, so this call also must not throw
{ {
} }

View File

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

View File

@@ -15,14 +15,10 @@
#include <boost/config.hpp> #include <boost/config.hpp>
#ifdef BOOST_MSVC // moved here to work around VC++ compiler crash
# pragma warning(push)
# pragma warning(disable:4284) // odd return type for operator->
#endif
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/detail/workaround.hpp> #include <boost/detail/workaround.hpp>
#include <boost/smart_ptr/detail/sp_convertible.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 #include <boost/config/no_tr1/functional.hpp> // for std::less
@@ -63,7 +59,7 @@ public:
typedef T element_type; typedef T element_type;
intrusive_ptr(): px( 0 ) intrusive_ptr() BOOST_NOEXCEPT : px( 0 )
{ {
} }
@@ -77,7 +73,7 @@ public:
template<class U> template<class U>
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) #if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
intrusive_ptr( intrusive_ptr<U> const & rhs, typename detail::sp_enable_if_convertible<U,T>::type = detail::sp_empty() ) intrusive_ptr( intrusive_ptr<U> const & rhs, typename boost::detail::sp_enable_if_convertible<U,T>::type = boost::detail::sp_empty() )
#else #else
@@ -113,16 +109,16 @@ public:
// Move support // 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; rhs.px = 0;
} }
intrusive_ptr & operator=(intrusive_ptr && rhs) intrusive_ptr & operator=(intrusive_ptr && rhs) BOOST_NOEXCEPT
{ {
this_type(std::move(rhs)).swap(*this); this_type( static_cast< intrusive_ptr && >( rhs ) ).swap(*this);
return *this; return *this;
} }
@@ -140,7 +136,7 @@ public:
return *this; return *this;
} }
void reset() void reset() BOOST_NOEXCEPT
{ {
this_type().swap( *this ); this_type().swap( *this );
} }
@@ -150,11 +146,23 @@ public:
this_type( rhs ).swap( *this ); 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; return px;
} }
T * detach() BOOST_NOEXCEPT
{
T * ret = px;
px = 0;
return ret;
}
T & operator*() const T & operator*() const
{ {
BOOST_ASSERT( px != 0 ); BOOST_ASSERT( px != 0 );
@@ -170,7 +178,7 @@ public:
// implicit conversion to "bool" // implicit conversion to "bool"
#include <boost/smart_ptr/detail/operator_bool.hpp> #include <boost/smart_ptr/detail/operator_bool.hpp>
void swap(intrusive_ptr & rhs) void swap(intrusive_ptr & rhs) BOOST_NOEXCEPT
{ {
T * tmp = px; T * tmp = px;
px = rhs.px; px = rhs.px;
@@ -223,6 +231,30 @@ template<class T> inline bool operator!=(intrusive_ptr<T> const & a, intrusive_p
#endif #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) template<class T> inline bool operator<(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b)
{ {
return std::less<T *>()(a.get(), b.get()); return std::less<T *>()(a.get(), b.get());
@@ -290,10 +322,15 @@ template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::
#endif // !defined(BOOST_NO_IOSTREAM) #endif // !defined(BOOST_NO_IOSTREAM)
// hash_value
template< class T > struct hash;
template< class T > std::size_t hash_value( boost::intrusive_ptr<T> const & p )
{
return boost::hash< T* >()( p.get() );
}
} // namespace boost } // namespace boost
#ifdef BOOST_MSVC
# pragma warning(pop)
#endif
#endif // #ifndef BOOST_SMART_PTR_INTRUSIVE_PTR_HPP_INCLUDED #endif // #ifndef BOOST_SMART_PTR_INTRUSIVE_PTR_HPP_INCLUDED

View 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_

View File

@@ -3,7 +3,7 @@
// make_shared.hpp // 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. // Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at // See accompanying file LICENSE_1_0.txt or copy at
@@ -12,493 +12,11 @@
// See http://www.boost.org/libs/smart_ptr/make_shared.html // See http://www.boost.org/libs/smart_ptr/make_shared.html
// for documentation. // for documentation.
#include <boost/config.hpp> #include <boost/smart_ptr/make_shared_object.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_ )
{
reinterpret_cast< T* >( storage_.data_ )->~T();
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;
}
};
template< class T > T forward( T t )
{
return t;
}
} // namespace detail
// 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 ), detail::sp_ms_deleter< T >() );
detail::sp_ms_deleter< T > * pd = boost::get_deleter< 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 ), detail::sp_ms_deleter< T >(), a );
detail::sp_ms_deleter< T > * pd = boost::get_deleter< 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... Args > boost::shared_ptr< T > make_shared( Args && ... args )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
void * pv = pd->address();
::new( pv ) T( detail::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... Args > boost::shared_ptr< T > allocate_shared( A const & a, Args && ... args )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
void * pv = pd->address();
::new( pv ) T( detail::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 );
}
#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 ), detail::sp_ms_deleter< T >() );
detail::sp_ms_deleter< T > * pd = boost::get_deleter< 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 ), detail::sp_ms_deleter< T >(), a );
detail::sp_ms_deleter< T > * pd = boost::get_deleter< 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 ), detail::sp_ms_deleter< T >() );
detail::sp_ms_deleter< T > * pd = boost::get_deleter< 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 ), detail::sp_ms_deleter< T >(), a );
detail::sp_ms_deleter< T > * pd = boost::get_deleter< 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 ), detail::sp_ms_deleter< T >() );
detail::sp_ms_deleter< T > * pd = boost::get_deleter< 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 ), detail::sp_ms_deleter< T >(), a );
detail::sp_ms_deleter< T > * pd = boost::get_deleter< 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 ), detail::sp_ms_deleter< T >() );
detail::sp_ms_deleter< T > * pd = boost::get_deleter< 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 ), detail::sp_ms_deleter< T >(), a );
detail::sp_ms_deleter< T > * pd = boost::get_deleter< 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 ), detail::sp_ms_deleter< T >() );
detail::sp_ms_deleter< T > * pd = boost::get_deleter< 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 ), detail::sp_ms_deleter< T >(), a );
detail::sp_ms_deleter< T > * pd = boost::get_deleter< 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 ), detail::sp_ms_deleter< T >() );
detail::sp_ms_deleter< T > * pd = boost::get_deleter< 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 ), detail::sp_ms_deleter< T >(), a );
detail::sp_ms_deleter< T > * pd = boost::get_deleter< 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 ), detail::sp_ms_deleter< T >() );
detail::sp_ms_deleter< T > * pd = boost::get_deleter< 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 ), detail::sp_ms_deleter< T >(), a );
detail::sp_ms_deleter< T > * pd = boost::get_deleter< 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 ), detail::sp_ms_deleter< T >() );
detail::sp_ms_deleter< T > * pd = boost::get_deleter< 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 ), detail::sp_ms_deleter< T >(), a );
detail::sp_ms_deleter< T > * pd = boost::get_deleter< 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 ), detail::sp_ms_deleter< T >() );
detail::sp_ms_deleter< T > * pd = boost::get_deleter< 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 ), detail::sp_ms_deleter< T >(), a );
detail::sp_ms_deleter< T > * pd = boost::get_deleter< 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 );
}
#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 #endif
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_MAKE_SHARED_HPP_INCLUDED #endif // #ifndef BOOST_SMART_PTR_MAKE_SHARED_HPP_INCLUDED

View 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

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,15 @@
/*
* Copyright (c) 2014 Glen Joseph Fernandes
* glenfe at live dot com
*
* Distributed under the Boost Software License,
* Version 1.0. (See accompanying file LICENSE_1_0.txt
* or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_SMART_PTR_MAKE_UNIQUE_HPP
#define BOOST_SMART_PTR_MAKE_UNIQUE_HPP
#include <boost/smart_ptr/make_unique_array.hpp>
#include <boost/smart_ptr/make_unique_object.hpp>
#endif

View File

@@ -0,0 +1,31 @@
/*
* Copyright (c) 2014 Glen Joseph Fernandes
* glenfe at live dot com
*
* Distributed under the Boost Software License,
* Version 1.0. (See accompanying file LICENSE_1_0.txt
* or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_SMART_PTR_MAKE_UNIQUE_ARRAY_HPP
#define BOOST_SMART_PTR_MAKE_UNIQUE_ARRAY_HPP
#include <boost/smart_ptr/detail/up_if_array.hpp>
#include <boost/smart_ptr/detail/array_traits.hpp>
namespace boost {
template<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

View 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

View File

@@ -0,0 +1,57 @@
#ifndef BOOST_SMART_PTR_OWNER_LESS_HPP_INCLUDED
#define BOOST_SMART_PTR_OWNER_LESS_HPP_INCLUDED
//
// owner_less.hpp
//
// Copyright (c) 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)
//
// See http://www.boost.org/libs/smart_ptr/smart_ptr.htm for documentation.
//
#include <functional>
namespace boost
{
template<typename T> class shared_ptr;
template<typename T> class weak_ptr;
namespace detail
{
template<typename T, typename U>
struct generic_owner_less : public std::binary_function<T, T, bool>
{
bool operator()(const T &lhs, const T &rhs) const
{
return lhs.owner_before(rhs);
}
bool operator()(const T &lhs, const U &rhs) const
{
return lhs.owner_before(rhs);
}
bool operator()(const U &lhs, const T &rhs) const
{
return lhs.owner_before(rhs);
}
};
} // namespace detail
template<typename T> struct owner_less;
template<typename T>
struct owner_less<shared_ptr<T> >:
public detail::generic_owner_less<shared_ptr<T>, weak_ptr<T> >
{};
template<typename T>
struct owner_less<weak_ptr<T> >:
public detail::generic_owner_less<weak_ptr<T>, shared_ptr<T> >
{};
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_OWNER_LESS_HPP_INCLUDED

View File

@@ -11,9 +11,10 @@
// http://www.boost.org/libs/smart_ptr/scoped_array.htm // http://www.boost.org/libs/smart_ptr/scoped_array.htm
// //
#include <boost/config.hpp>
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/checked_delete.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> #include <boost/detail/workaround.hpp>
@@ -53,7 +54,7 @@ public:
typedef T element_type; 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) #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
boost::sp_array_constructor_hook( px ); boost::sp_array_constructor_hook( px );
@@ -68,20 +69,20 @@ public:
boost::checked_array_delete( px ); 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 BOOST_ASSERT( p == 0 || p != px ); // catch self-reset errors
this_type(p).swap(*this); 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( px != 0 );
BOOST_ASSERT( i >= 0 ); BOOST_ASSERT( i >= 0 );
return px[i]; return px[i];
} }
T * get() const // never throws T * get() const BOOST_NOEXCEPT
{ {
return px; return px;
} }
@@ -89,7 +90,7 @@ public:
// implicit conversion to "bool" // implicit conversion to "bool"
#include <boost/smart_ptr/detail/operator_bool.hpp> #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; T * tmp = b.px;
b.px = 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); a.swap(b);
} }

View File

@@ -11,8 +11,10 @@
// http://www.boost.org/libs/smart_ptr/scoped_ptr.htm // http://www.boost.org/libs/smart_ptr/scoped_ptr.htm
// //
#include <boost/config.hpp>
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/checked_delete.hpp> #include <boost/checked_delete.hpp>
#include <boost/smart_ptr/detail/sp_nullptr_t.hpp>
#include <boost/detail/workaround.hpp> #include <boost/detail/workaround.hpp>
#ifndef BOOST_NO_AUTO_PTR #ifndef BOOST_NO_AUTO_PTR
@@ -63,7 +65,7 @@ public:
#ifndef BOOST_NO_AUTO_PTR #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) #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
boost::sp_scalar_constructor_hook( px ); boost::sp_scalar_constructor_hook( px );
@@ -98,7 +100,7 @@ public:
return px; return px;
} }
T * get() const // never throws T * get() const BOOST_NOEXCEPT
{ {
return px; return px;
} }
@@ -106,7 +108,7 @@ public:
// implicit conversion to "bool" // implicit conversion to "bool"
#include <boost/smart_ptr/detail/operator_bool.hpp> #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; T * tmp = b.px;
b.px = 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); a.swap(b);
} }
// get_pointer(p) is a generic way to say p.get() // 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(); return p.get();
} }

View File

@@ -5,7 +5,7 @@
// shared_array.hpp // shared_array.hpp
// //
// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999. // (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 // Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at // accompanying file LICENSE_1_0.txt or copy at
@@ -16,16 +16,14 @@
#include <boost/config.hpp> // for broken compiler workarounds #include <boost/config.hpp> // for broken compiler workarounds
#if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
#include <boost/smart_ptr/detail/shared_array_nmt.hpp>
#else
#include <memory> // TR1 cyclic inclusion fix #include <memory> // TR1 cyclic inclusion fix
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/checked_delete.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/shared_count.hpp>
#include <boost/smart_ptr/detail/sp_nullptr_t.hpp>
#include <boost/detail/workaround.hpp> #include <boost/detail/workaround.hpp>
#include <cstddef> // for std::ptrdiff_t #include <cstddef> // for std::ptrdiff_t
@@ -55,41 +53,154 @@ public:
typedef T element_type; 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 // Requirements: D's copy constructor must not throw
// //
// shared_array will release p by calling d(p) // 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_NO_CXX11_RVALUE_REFERENCES )
// ... except in C++0x, move disables the implicit copy
shared_array( shared_array const & r ) BOOST_NOEXCEPT : px( r.px ), pn( r.pn )
{ {
} }
// generated copy constructor, assignment, destructor are fine shared_array( shared_array && r ) BOOST_NOEXCEPT : px( r.px ), pn()
void reset(T * p = 0)
{ {
BOOST_ASSERT(p == 0 || p != px); pn.swap( r.pn );
this_type(p).swap(*this); r.px = 0;
} }
template <class D> void reset(T * p, D d) #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
{ {
this_type(p, d).swap(*this); boost::detail::sp_assert_convertible< Y[], T[] >();
} }
T & operator[] (std::ptrdiff_t i) const // never throws // 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 ) BOOST_NOEXCEPT
{
this_type( r ).swap( *this );
return *this;
}
#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1400)
template<class Y>
shared_array & operator=( shared_array<Y> const & r ) BOOST_NOEXCEPT
{
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 Y, class D> void reset( Y * p, D d )
{
this_type( p, d ).swap( *this );
}
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(px != 0);
BOOST_ASSERT(i >= 0); BOOST_ASSERT(i >= 0);
return px[i]; return px[i];
} }
T * get() const // never throws T * get() const BOOST_NOEXCEPT
{ {
return px; return px;
} }
@@ -97,51 +208,85 @@ public:
// implicit conversion to "bool" // implicit conversion to "bool"
#include <boost/smart_ptr/detail/operator_bool.hpp> #include <boost/smart_ptr/detail/operator_bool.hpp>
bool unique() const // never throws bool unique() const BOOST_NOEXCEPT
{ {
return pn.unique(); return pn.unique();
} }
long use_count() const // never throws long use_count() const BOOST_NOEXCEPT
{ {
return pn.use_count(); 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); std::swap(px, other.px);
pn.swap(other.pn); pn.swap(other.pn);
} }
void * _internal_get_deleter( boost::detail::sp_typeinfo const & ti ) const
{
return pn.get_deleter( ti );
}
private: private:
template<class Y> friend class shared_array;
T * px; // contained pointer T * px; // contained pointer
detail::shared_count pn; // reference counter detail::shared_count pn; // reference counter
}; // shared_array }; // 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(); 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(); 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()); 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); a.swap(b);
} }
template< class D, class T > D * get_deleter( shared_array<T> const & p )
{
return static_cast< D * >( p._internal_get_deleter( BOOST_SP_TYPEID(D) ) );
}
} // namespace boost } // namespace boost
#endif // #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
#endif // #ifndef BOOST_SMART_PTR_SHARED_ARRAY_HPP_INCLUDED #endif // #ifndef BOOST_SMART_PTR_SHARED_ARRAY_HPP_INCLUDED

File diff suppressed because it is too large Load Diff

View File

@@ -17,11 +17,6 @@
#include <boost/smart_ptr/detail/shared_count.hpp> #include <boost/smart_ptr/detail/shared_count.hpp>
#include <boost/smart_ptr/shared_ptr.hpp> #include <boost/smart_ptr/shared_ptr.hpp>
#ifdef BOOST_MSVC // moved here to work around VC++ compiler crash
# pragma warning(push)
# pragma warning(disable:4284) // odd return type for operator->
#endif
namespace boost namespace boost
{ {
@@ -34,14 +29,30 @@ private:
public: 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 // generated copy constructor, assignment, destructor are fine...
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
// ... except in C++0x, move disables the implicit copy
weak_ptr( weak_ptr const & r ) BOOST_NOEXCEPT : px( r.px ), pn( r.pn )
{
}
weak_ptr & operator=( weak_ptr const & r ) BOOST_NOEXCEPT
{
px = r.px;
pn = r.pn;
return *this;
}
#endif
// //
// The "obvious" converting constructor implementation: // The "obvious" converting constructor implementation:
@@ -63,44 +74,47 @@ public:
template<class Y> template<class Y>
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) #if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
weak_ptr( weak_ptr<Y> const & r, typename detail::sp_enable_if_convertible<Y,T>::type = detail::sp_empty() ) weak_ptr( weak_ptr<Y> const & r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() )
#else #else
weak_ptr( weak_ptr<Y> const & r ) weak_ptr( weak_ptr<Y> const & r )
#endif #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> template<class Y>
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) #if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
weak_ptr( weak_ptr<Y> && r, typename detail::sp_enable_if_convertible<Y,T>::type = detail::sp_empty() ) weak_ptr( weak_ptr<Y> && r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() )
#else #else
weak_ptr( weak_ptr<Y> && r ) weak_ptr( weak_ptr<Y> && r )
#endif #endif
: px(r.lock().get()), pn(std::move(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; r.px = 0;
} }
// for better efficiency in the T == Y case // for better efficiency in the T == Y case
weak_ptr( weak_ptr && r ): px( r.px ), pn(std::move(r.pn)) // never throws weak_ptr & operator=( weak_ptr && r ) BOOST_NOEXCEPT
{ {
r.px = 0; this_type( static_cast< weak_ptr && >( r ) ).swap( *this );
}
// for better efficiency in the T == Y case
weak_ptr & operator=( weak_ptr && r ) // never throws
{
this_type( std::move( r ) ).swap( *this );
return *this; return *this;
} }
@@ -110,59 +124,66 @@ public:
template<class Y> template<class Y>
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) #if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
weak_ptr( shared_ptr<Y> const & r, typename detail::sp_enable_if_convertible<Y,T>::type = detail::sp_empty() ) weak_ptr( shared_ptr<Y> const & r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() )
#else #else
weak_ptr( shared_ptr<Y> const & r ) weak_ptr( shared_ptr<Y> const & r )
#endif #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) #if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300)
template<class Y> 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(); px = r.lock().get();
pn = r.pn; pn = r.pn;
return *this; return *this;
} }
#if defined( BOOST_HAS_RVALUE_REFS ) #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
template<class Y> template<class Y>
weak_ptr & operator=(weak_ptr<Y> && r) weak_ptr & operator=( weak_ptr<Y> && r ) BOOST_NOEXCEPT
{ {
this_type( std::move( r ) ).swap( *this ); this_type( static_cast< weak_ptr<Y> && >( r ) ).swap( *this );
return *this; return *this;
} }
#endif #endif
template<class Y> 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; px = r.px;
pn = r.pn; pn = r.pn;
return *this; return *this;
} }
#endif #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(); return pn.use_count();
} }
bool expired() const // never throws bool expired() const BOOST_NOEXCEPT
{ {
return pn.use_count() == 0; return pn.use_count() == 0;
} }
@@ -172,24 +193,30 @@ public:
return pn.empty(); return pn.empty();
} }
void reset() // never throws in 1.30+ void reset() BOOST_NOEXCEPT // never throws in 1.30+
{ {
this_type().swap(*this); this_type().swap(*this);
} }
void swap(this_type & other) // never throws void swap(this_type & other) BOOST_NOEXCEPT
{ {
std::swap(px, other.px); std::swap(px, other.px);
pn.swap(other.pn); 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; px = px2;
pn = pn2; pn = r.pn;
} }
template<class Y> bool _internal_less(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 BOOST_NOEXCEPT
{ {
return pn < rhs.pn; return pn < rhs.pn;
} }
@@ -206,25 +233,21 @@ private:
#endif #endif
T * px; // contained pointer element_type * px; // contained pointer
boost::detail::weak_count pn; // reference counter boost::detail::weak_count pn; // reference counter
}; // weak_ptr }; // 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._internal_less(b); 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); a.swap(b);
} }
} // namespace boost } // namespace boost
#ifdef BOOST_MSVC
# pragma warning(pop)
#endif
#endif // #ifndef BOOST_SMART_PTR_WEAK_PTR_HPP_INCLUDED #endif // #ifndef BOOST_SMART_PTR_WEAK_PTR_HPP_INCLUDED

View File

@@ -1,15 +1,18 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html> <html>
<head> <head>
<title>Smart Pointers</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="refresh" content="0; URL=smart_ptr.htm"> <meta http-equiv="refresh" content="0; URL=smart_ptr.htm">
</head> </head>
<body> <body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
Automatic redirection failed, please go to Automatic redirection failed, please go to
<a href="smart_ptr.htm">smart_ptr.htm</a>. <a href="smart_ptr.htm">smart_ptr.htm</a>.
</body> </body>
</html> </html>
<!-- <!--
<09> Copyright Beman Dawes, 2001 (C) Copyright Beman Dawes, 2001
Distributed under the Boost Software License, Version 1.0. Distributed under the Boost Software License, Version 1.0.
See accompanying file LICENSE_1_0.txt or copy at See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt http://www.boost.org/LICENSE_1_0.txt
--> -->

View File

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

View 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&lt;class DerivedT, class CounterPolicyT = thread_safe_counter&gt;
class intrusive_ref_counter
{
public:
<A href="#constructors" >intrusive_ref_counter</A>() = noexcept;
<A href="#constructors" >intrusive_ref_counter</A>(intrusive_ref_counter const &amp; r) = noexcept;
intrusive_ref_counter &amp; <A href="#assignment" >operator=</A>(intrusive_ref_counter const &amp; 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 &amp;);</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 &amp; operator=(intrusive_ref_counter const &amp; 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 &copy; 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>

View File

@@ -1,37 +1,38 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html> <html>
<head> <head>
<title>make_shared and allocate_shared</title> <title>make_shared and allocate_shared</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head> </head>
<body text="#000000" bgColor="#ffffff"> <body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
<h1><A href="../../index.htm"><IMG height="86" alt="boost.png (6897 bytes)" src="../../boost.png" width="277" align="middle" <h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
border="0"></A>make_shared and allocate_shared function templates</h1> width="277" align="middle" border="0">make_shared and allocate_shared
<p><A href="#Introduction">Introduction</A><br> function templates</h1>
<A href="#Synopsis">Synopsis</A><br> <p><A href="#Introduction">Introduction</A><br>
<A href="#functions">Free Functions</A><br> <A href="#Synopsis">Synopsis</A><br>
<A href="#example">Example</A><br> <A href="#functions">Free Functions</A><br>
<h2><a name="Introduction">Introduction</a></h2> <A href="#example">Example</A><br>
<p>Consistent use of <a href="shared_ptr.htm"><code>shared_ptr</code></a> <h2><a name="Introduction">Introduction</a></h2>
can eliminate the need to use an explicit <code>delete</code>, <p>Consistent use of <a href="shared_ptr.htm"><code>shared_ptr</code></a>
but alone it provides no support in avoiding explicit <code>new</code>. can eliminate the need to use an explicit <code>delete</code>,
There have been repeated requests from users for a factory function that creates but alone it provides no support in avoiding explicit <code>new</code>.
an object of a given type and returns a <code>shared_ptr</code> to it. There have been repeated requests from users for a factory function that creates
Besides convenience and style, such a function is also exception safe and an object of a given type and returns a <code>shared_ptr</code> to it.
considerably faster because it can use a single allocation for both the object Besides convenience and style, such a function is also exception safe and
and its corresponding control block, eliminating a significant portion of considerably faster because it can use a single allocation for both the object
<code>shared_ptr</code>'s construction overhead. and its corresponding control block, eliminating a significant portion of
This eliminates one of the major efficiency complaints about <code>shared_ptr</code>. <code>shared_ptr</code>'s construction overhead.
</p> This eliminates one of the major efficiency complaints about <code>shared_ptr</code>.
<p>The header file &lt;boost/make_shared.hpp&gt; provides a family of overloaded function templates, </p>
<code>make_shared</code> and <code>allocate_shared</code>, to address this need. <p>The header file &lt;boost/make_shared.hpp&gt; provides a family of overloaded function templates,
<code>make_shared</code> uses the global operator <code>new</code> to allocate memory, <code>make_shared</code> and <code>allocate_shared</code>, to address this need.
whereas <code>allocate_shared</code> uses an user-supplied allocator, allowing finer control.</p> <code>make_shared</code> uses the global operator <code>new</code> to allocate memory,
<p> whereas <code>allocate_shared</code> uses an user-supplied allocator, allowing finer control.</p>
The rationale for choosing the name <code>make_shared</code> is that the expression <p>
<code>make_shared&lt;Widget&gt;()</code> can be read aloud and conveys the intended meaning.</p> The rationale for choosing the name <code>make_shared</code> is that the expression
<h2><a name="Synopsis">Synopsis</a></h2> <code>make_shared&lt;Widget&gt;()</code> can be read aloud and conveys the intended meaning.</p>
<pre>namespace boost { <h2><a name="Synopsis">Synopsis</a></h2>
<pre>namespace boost {
template&lt;typename T&gt; class shared_ptr; template&lt;typename T&gt; class shared_ptr;
@@ -41,7 +42,7 @@
template&lt;typename T, typename A&gt; template&lt;typename T, typename A&gt;
shared_ptr&lt;T&gt; <a href="#functions">allocate_shared</a>( A const &amp; ); shared_ptr&lt;T&gt; <a href="#functions">allocate_shared</a>( A const &amp; );
#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&lt;typename T, typename... Args&gt; template&lt;typename T, typename... Args&gt;
shared_ptr&lt;T&gt; <a href="#functions">make_shared</a>( Args &amp;&amp; ... args ); shared_ptr&lt;T&gt; <a href="#functions">make_shared</a>( Args &amp;&amp; ... args );
@@ -69,51 +70,50 @@
#endif #endif
}</pre> }</pre>
<h2><a name="functions">Free Functions</a></h2> <h2><a name="functions">Free Functions</a></h2>
<pre>template&lt;class T, class... Args&gt; <pre>template&lt;class T, class... Args&gt;
shared_ptr&lt;T&gt; make_shared( Args &amp;&amp; ... args ); shared_ptr&lt;T&gt; make_shared( Args &amp;&amp; ... args );
template&lt;class T, class A, class... Args&gt; template&lt;class T, class A, class... Args&gt;
shared_ptr&lt;T&gt; allocate_shared( A const &amp; a, Args &amp;&amp; ... args );</pre> shared_ptr&lt;T&gt; allocate_shared( A const &amp; a, Args &amp;&amp; ... args );</pre>
<blockquote> <blockquote>
<p><b>Requires:</b> The expression <code>new( pv ) T( std::forward&lt;Args&gt;(args)... )</code>, <p><b>Requires:</b> The expression <code>new( pv ) T( std::forward&lt;Args&gt;(args)... )</code>,
where <code>pv</code> is a <code>void*</code> pointing to storage suitable where <code>pv</code> is a <code>void*</code> pointing to storage suitable
to hold an object of type <code>T</code>, to hold an object of type <code>T</code>,
shall be well-formed. <code>A</code> shall be an <em>Allocator</em>, shall be well-formed. <code>A</code> shall be an <em>Allocator</em>,
as described in section 20.1.5 (<stong>Allocator requirements</strong>) of the C++ Standard. as described in section 20.1.5 (<strong>Allocator requirements</strong>) of the C++ Standard.
The copy constructor and destructor of <code>A</code> shall not throw.</p> The copy constructor and destructor of <code>A</code> shall not throw.</p>
<p><b>Effects:</b> Allocates memory suitable for an object of type <code>T</code> <p><b>Effects:</b> Allocates memory suitable for an object of type <code>T</code>
and constructs an object in it via the placement new expression <code>new( pv ) T()</code> and constructs an object in it via the placement new expression <code>new( pv ) T()</code>
or <code>new( pv ) T( std::forward&lt;Args&gt;(args)... )</code>. or <code>new( pv ) T( std::forward&lt;Args&gt;(args)... )</code>.
<code>allocate_shared</code> uses a copy of <code>a</code> to allocate memory. <code>allocate_shared</code> uses a copy of <code>a</code> to allocate memory.
If an exception is thrown, has no effect.</p> If an exception is thrown, has no effect.</p>
<p><b>Returns:</b> A <code>shared_ptr</code> instance that stores and owns the address <p><b>Returns:</b> A <code>shared_ptr</code> instance that stores and owns the address
of the newly constructed object of type <code>T</code>.</p> of the newly constructed object of type <code>T</code>.</p>
<p><b>Postconditions:</b> <code>get() != 0 &amp;&amp; use_count() == 1</code>.</p> <p><b>Postconditions:</b> <code>get() != 0 &amp;&amp; use_count() == 1</code>.</p>
<p><b>Throws:</b> <code>bad_alloc</code>, or an exception thrown from <code>A::allocate</code> <p><b>Throws:</b> <code>bad_alloc</code>, or an exception thrown from <code>A::allocate</code>
or the constructor of <code>T</code>.</p> or the constructor of <code>T</code>.</p>
<p><b>Notes:</b> This implementation allocates the memory required for the <p><b>Notes:</b> This implementation allocates the memory required for the
returned <code>shared_ptr</code> and an object of type <code>T</code> in a single returned <code>shared_ptr</code> and an object of type <code>T</code> in a single
allocation. This provides efficiency equivalent to an intrusive smart pointer.</p> allocation. This provides efficiency equivalent to an intrusive smart pointer.</p>
<p>The prototypes shown above are used if your compiler supports rvalue references <p>The prototypes shown above are used if your compiler supports rvalue references
and variadic templates. They perfectly forward the <code>args</code> parameters to and variadic templates. They perfectly forward the <code>args</code> parameters to
the constructors of <code>T</code>.</p> the constructors of <code>T</code>.</p>
<p>Otherwise, the implementation will fall back on <p>Otherwise, the implementation will fall back on
forwarding the arguments to the constructors of <code>T</code> as const references. forwarding the arguments to the constructors of <code>T</code> as const references.
If you need to pass a non-const reference to a constructor of <code>T</code>, If you need to pass a non-const reference to a constructor of <code>T</code>,
you may do so by wrapping the parameter in a call to <code>boost::ref</code>. you may do so by wrapping the parameter in a call to <code>boost::ref</code>.
In addition, you will be In addition, you will be
limited to a maximum of 9 arguments (not counting the allocator argument of limited to a maximum of 9 arguments (not counting the allocator argument of
allocate_shared).</p> allocate_shared).</p>
</blockquote> </blockquote>
<h2><a name="example">Example</a></h2> <h2><a name="example">Example</a></h2>
<pre>boost::shared_ptr&lt;std::string&gt; x = boost::make_shared&lt;std::string&gt;("hello, world!"); <pre>boost::shared_ptr&lt;std::string&gt; x = boost::make_shared&lt;std::string&gt;("hello, world!");
std::cout << *x;</pre> std::cout << *x;</pre>
<hr> <hr>
<p> <p>$Date$</p>
$Date: 2008-05-19 15:42:39 -0400 (Mon, 19 May 2008) $</p> <p><small>Copyright 2008 Peter Dimov. Copyright 2008 Frank Mori Hess.
<p><small>Copyright 2008 Peter Dimov. Copyright 2008 Frank Mori Hess. Distributed under the Boost Software License,
Distributed under the Boost Software License, Version 1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A>
Version 1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
or copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p> </body>
</body>
</html> </html>

273
make_shared_array.html Normal file
View 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 &lt;boost/smart_ptr/make_shared_array.hpp&gt; and
&lt;boost/smart_ptr/allocate_shared_array.hpp&gt; 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&lt;class U&gt; // U is T[]
shared_ptr&lt;U&gt; <a href="#functions">make_shared</a>(size_t size);
template&lt;class U, class A&gt; // U is T[]
shared_ptr&lt;U&gt; <a href="#functions">allocate_shared</a>(const A&amp; allocator, size_t size);
template&lt;class U&gt; // U is T[N]
shared_ptr&lt;U&gt; <a href="#functions">make_shared</a>();
template&lt;class U, class A&gt; // U is T[N]
shared_ptr&lt;U&gt; <a href="#functions">allocate_shared</a>(const A&amp; allocator);
template&lt;class U&gt; // U is T[]
shared_ptr&lt;U&gt; <a href="#functions">make_shared</a>(size_t size, const T&amp; value);
template&lt;class U, class A&gt; // U is T[]
shared_ptr&lt;U&gt; <a href="#functions">allocate_shared</a>(const A&amp; allocator, size_t size, const T&amp; value);
template&lt;class U&gt; // U is T[N]
shared_ptr&lt;U&gt; <a href="#functions">make_shared</a>(const T&amp; value);
template&lt;class U, class A&gt; // U is T[N]
shared_ptr&lt;U&gt; <a href="#functions">allocate_shared</a>(const A&amp; allocator, const T&amp; value);
template&lt;class U&gt; // U is T[]
shared_ptr&lt;U&gt; <a href="#functions">make_shared_noinit</a>(size_t size);
template&lt;class U, class A&gt; // U is T[]
shared_ptr&lt;U&gt; <a href="#functions">allocate_shared_noinit</a>(const A&amp; allocator, size_t size);
template&lt;class U&gt; // U is T[N]
shared_ptr&lt;U&gt; <a href="#functions">make_shared_noinit</a>();
template&lt;class U, class A&gt; // U is T[N]
shared_ptr&lt;U&gt; <a href="#functions">allocate_shared_noinit</a>(const A&amp; allocator);
}</pre>
<h2><a name="common">Common Requirements</a></h2>
<pre>template&lt;class U&gt;
shared_ptr&lt;U&gt; make_shared(<em>args</em>);
template&lt;class U, class A&gt;
shared_ptr&lt;U&gt; allocate_shared(const A&amp; allocator, <em>args</em>);
template&lt;class U&gt;
shared_ptr&lt;U&gt; make_shared_noinit(<em>args</em>);
template&lt;class U, class A&gt;
shared_ptr&lt;U&gt; allocate_shared_noinit(const A&amp; 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 &amp;&amp;
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&lt;A2&gt;::construct(a2, ptr,
value)</code>, where <code>ptr</code> points to storage suitable to
hold an object of type <code>T</code> and <code>a2</code> of type A2
is a rebound copy of the allocator <code>allocator</code> passed to
<code>allocate_shared</code> such that its <code>value_type</code>
is <code>T</code>.</p>
<p>When a subobject of non-array type <code>T</code> is specified to
be value-initialized, <code>make_shared</code> shall perform this
initialization via the expression <code>::new(ptr) T()</code>, where
<code>ptr</code> has type <code>void*</code> and points to storage
suitable to hold an object of type <code>T</code>.</p>
<p>When a subobject of non-array type <code>T</code> is specified to
be value-initialized, <code>allocate_shared</code> shall perform
this initialization via the expression
<code>allocator_traits&lt;A2&gt;::construct(a2, ptr)</code>, where
<code>ptr</code> points to storage suitable to hold an object
of type <code>T</code> and <code>a2</code> of type A2 is a rebound
copy of the allocator <code>allocator</code> passed to
<code>allocate_shared</code> such that its <code>value_type</code>
is <code>T</code>.</p>
<p>When a subobject of non-array type <code>T</code> is specified to
be default-initialized, <code>make_shared_noinit</code> and
<code>allocate_shared_noinit</code> shall perform this
initialization via the expression <code>::new(ptr) T</code>, where
<code>ptr</code> has type <code>void*</code> and points to storage
suitable to hold an object of type <code>T</code>.</p>
<p>When the lifetime of the object managed by the return value ends,
or when the initialization of an array element throws an exception,
the initialized elements should be destroyed in the reverse order
of their construction.</p>
</blockquote>
<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&lt;class U&gt;
shared_ptr&lt;U&gt; make_shared(size_t size);
template&lt;class U, class A&gt;
shared_ptr&lt;U&gt; allocate_shared(const A&amp; 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&lt;int[]&gt; a1 = boost::make_shared&lt;int[]&gt;(size);
boost::shared_ptr&lt;int[][2]&gt; a2 = boost::make_shared&lt;int[][2]&gt;(size);</pre>
</blockquote>
</blockquote>
<pre>template&lt;class U&gt;
shared_ptr&lt;U&gt; make_shared();
template&lt;class U, class A&gt;
shared_ptr&lt;U&gt; allocate_shared(const A&amp; 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&lt;int[8]&gt; a1 = boost::make_shared&lt;int[8]&gt;();
boost::shared_ptr&lt;int[4][2]&gt; a2 = boost::make_shared&lt;int[4][2]&gt;();</pre>
</blockquote>
</blockquote>
<pre>template&lt;class U&gt;
shared_ptr&lt;U&gt; make_shared(size_t size, const T&amp; value);
template&lt;class U, class A&gt;
shared_ptr&lt;U&gt; allocate_shared(const A&amp; allocator, size_t size, const T&amp; value);</pre>
<blockquote>
<p><b>Returns:</b> A <code>shared_ptr</code> to an object of type
<code>T[size]</code>, where each array element of type <code>T</code>
is initialized to <code>value</code>.</p>
<p><b>Remarks:</b> These overloads shall only participate in overload
resolution when <code>U</code> is of the form <code>T[]</code>.</p>
<p><b>Examples:</b></p>
<blockquote>
<pre>boost::shared_ptr&lt;int[]&gt; a1 = boost::make_shared&lt;int[]&gt;(size, 1);
boost::shared_ptr&lt;int[][2]&gt; a2 = boost::make_shared&lt;int[][2]&gt;(size, {1, 2});</pre>
</blockquote>
</blockquote>
<pre>template&lt;class U&gt;
shared_ptr&lt;U&gt; make_shared(const T&amp; value);
template&lt;class U, class A&gt;
shared_ptr&lt;U&gt; allocate_shared(const A&amp; allocator, const T&amp; value);</pre>
<blockquote>
<p><b>Returns:</b> A <code>shared_ptr</code> to an object of type
<code>T[N]</code>, where each array element of type <code>T</code> is
initialized to <code>value</code>.</p>
<p><b>Remarks:</b> These overloads shall only participate in overload
resolution when <code>U</code> is of the form <code>T[N]</code>.</p>
<p><b>Examples:</b></p>
<blockquote>
<pre>boost::shared_ptr&lt;int[8]&gt; a1 = boost::make_shared&lt;int[8]&gt;(1);
boost::shared_ptr&lt;int[4][2]&gt; a2 = boost::make_shared&lt;int[4][2]&gt;({1, 2});</pre>
</blockquote>
</blockquote>
<pre>template&lt;class U&gt;
shared_ptr&lt;U&gt; make_shared_noinit(size_t size);
template&lt;class U, class A&gt;
shared_ptr&lt;U&gt; allocate_shared_noinit(const A&amp; allocator, size_t size);</pre>
<blockquote>
<p><b>Returns:</b> A <code>shared_ptr</code> to a default-initialized
object of type <code>T[size]</code>.</p>
<p><b>Remarks:</b> These overloads shall only participate in overload
resolution when <code>U</code> is of the form <code>T[]</code>.</p>
<p><b>Examples:</b></p>
<blockquote>
<pre>boost::shared_ptr&lt;int[]&gt; a1 = boost::make_shared_noinit&lt;int[]&gt;(size);
boost::shared_ptr&lt;int[][2]&gt; a2 = boost::make_shared_noinit&lt;int[][2]&gt;(size);</pre>
</blockquote>
</blockquote>
<pre>template&lt;class U&gt;
shared_ptr&lt;U&gt; make_shared_noinit();
template&lt;class U, class A&gt;
shared_ptr&lt;U&gt; allocate_shared_noinit(const A&amp; allocator);</pre>
<blockquote>
<p><b>Returns:</b> A <code>shared_ptr</code> to a default-initialized
object of type <code>T[N]</code>.</p>
<p><b>Remarks:</b> These overloads shall only participate in overload
resolution when <code>U</code> is of the form <code>T[N]</code>.</p>
<p><b>Examples:</b></p>
<blockquote>
<pre>boost::shared_ptr&lt;int[8]&gt; a1 = boost::make_shared_noinit&lt;int[8]&gt;();
boost::shared_ptr&lt;int[4][2]&gt; a2 = boost::make_shared_noinit&lt;int[4][2]&gt;();</pre>
</blockquote>
</blockquote>
<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
&amp; 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
View File

@@ -0,0 +1,152 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>make_unique</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
<h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
width="277" align="middle" border="0">make_unique</h1>
<p><a href="#introduction">Introduction</a><br>
<a href="#synopsis">Synopsis</a><br>
<a href="#common">Common Requirements</a><br>
<a href="#functions">Free Functions</a><br>
<a href="#history">History</a></p>
<h2><a name="introduction">Introduction</a></h2>
<p>The header file &lt;boost/make_unique.hpp&gt; provides overloaded
function template <code>make_unique</code> for convenient creation of
<code>unique_ptr</code> objects.</p>
<h2><a name="synopsis">Synopsis</a></h2>
<pre>namespace boost {
template&lt;class U&gt; // U is not array
unique_ptr&lt;U&gt; <a href="#functions">make_unique</a>();
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template&lt;class U, class... Args&gt; // U is not array
unique_ptr&lt;U&gt; <a href="#functions">make_unique</a>(Args&amp;&amp;... args);
#endif
template&lt;class U&gt; // U is not array
unique_ptr&lt;U&gt; <a href="#functions">make_unique</a>(U&amp;&amp; value);
template&lt;class U&gt; // U is T[]
unique_ptr&lt;U&gt; <a href="#functions">make_unique</a>(size_t size);
template&lt;class U&gt; // U is not array
unique_ptr&lt;U&gt; <a href="#functions">make_unique_noinit</a>();
template&lt;class U&gt; // U is T[]
unique_ptr&lt;U&gt; <a href="#functions">make_unique_noinit</a>(size_t size);
}</pre>
<h2><a name="common">Common Requirements</a></h2>
<pre>template&lt;class U&gt;
unique_ptr&lt;U&gt; make_unique(<em>args</em>);
template&lt;class U&gt;
unique_ptr&lt;U&gt; make_unique_noinit(<em>args</em>);</pre>
<blockquote>
<p><b>Effects:</b> Allocates memory for an object of type <code>U</code>
(or <code>T[size]</code> when <code>U</code> is <code>T[]</code>,
where <code>size</code> is determined from <code>args</code> as
specified by the concrete overload). The object is initialized from
<code>args</code> as specified by the concrete overload. If an
exception is thrown, the functions have no effect.</p>
<p><b>Returns:</b> A <code>unique_ptr</code> instance that stores and
owns the address of the newly constructed object.</p>
<p><b>Postconditions:</b> <code>r.get() != 0</code>, where
<code>r</code> is the return value.</p>
<p><b>Throws:</b> <code>bad_alloc</code>, or an exception thrown from
the initialization of the object.</p>
<p><b>Remarks:</b></p>
<blockquote>
<p>When an object of a non-array type <code>T</code> is specified to
be initialized to a value <code>value</code>, or to
<code>T(list...)</code>, where <code>list...</code> is a list of
constructor arguments, <code>make_unique</code> shall perform this
initialization via the expression <code>new T(value)</code> or
<code>new T(list...)</code> respectively.</p>
<p>When an object of type <code>T</code> is specified to be
value-initialized, <code>make_unique</code> shall perform this
initialization via the expression <code>new T()</code>.</p>
<p>When an object of type <code>T</code> is specified to be
default-initialized, <code>make_unique_noinit</code> shall perform
this initialization via the expression <code>new T</code>.</p>
</blockquote>
</blockquote>
<h2><a name="functions">Free Functions</a></h2>
<pre>template&lt;class U, class... Args&gt;
unique_ptr&lt;U&gt; make_unique(Args&amp;&amp;... args);</pre>
<blockquote>
<p><b>Returns:</b> A unique_ptr to an object of type <code>U</code>,
initialized to <code>U(forward&lt;Args&gt;(args)...)</code>.</p>
<p><b>Remarks:</b> This overload shall only participate in overload
resolution when <code>U</code> is not an array type.</p>
<p><b>Examples:</b></p>
<blockquote>
<pre>unique_ptr&lt;float&gt; p1 = boost::make_unique&lt;float&gt;();
unique_ptr&lt;point&gt; p2 = boost::make_unique&lt;point&gt;(x, y);</pre>
</blockquote>
</blockquote>
<pre>template&lt;class U&gt;
unique_ptr&lt;U&gt; make_unique(U&amp;&amp; value);</pre>
<blockquote>
<p><b>Returns:</b> A unique_ptr to an object of type <code>U</code>,
initialized to <code>move(value)</code>.</p>
<p><b>Remarks:</b> This overload shall only participate in overload
resolution when <code>U</code> is not an array type.</p>
<p><b>Examples:</b></p>
<blockquote>
<pre>unique_ptr&lt;string&gt; p1 = boost::make_unique&lt;string&gt;({'a', 'b'});
unique_ptr&lt;point&gt; p2 = boost::make_unique&lt;point&gt;({-10, 25});</pre>
</blockquote>
</blockquote>
<pre>template&lt;class U&gt;
unique_ptr&lt;U&gt; make_unique(size_t size);</pre>
<blockquote>
<p><b>Returns:</b> A unique_ptr to a value-initialized object of type
<code>T[size]</code>.</p>
<p><b>Remarks:</b> This overload shall only participate in overload
resolution when <code>U</code> is of the form <code>T[]</code>.</p>
<p><b>Examples:</b></p>
<blockquote>
<pre>unique_ptr&lt;double[]&gt; p1 = boost::make_unique&lt;double[]&gt;(4);
unique_ptr&lt;int[][2]&gt; p2 = boost::make_unique&lt;int[][2]&gt;(2);</pre>
</blockquote>
</blockquote>
<pre>template&lt;class U&gt;
unique_ptr&lt;U&gt; make_unique_noinit();</pre>
<blockquote>
<p><b>Returns:</b> A unique_ptr to a default-initialized object of
type <code>U</code>.</p>
<p><b>Remarks:</b> This overload shall only participate in overload
resolution when <code>U</code> is not an array type.</p>
<p><b>Examples:</b></p>
<blockquote>
<pre>unique_ptr&lt;float&gt; p1 = boost::make_unique_noinit&lt;float&gt;();
unique_ptr&lt;point&gt; p2 = boost::make_unique_noinit&lt;point&gt;();</pre>
</blockquote>
</blockquote>
<pre>template&lt;class U&gt;
unique_ptr&lt;U&gt; make_unique_noinit(size_t size);</pre>
<blockquote>
<p><b>Returns:</b> A unique_ptr to a default-initialized object of
type <code>T[size]</code>.</p>
<p><b>Remarks:</b> This overload shall only participate in overload
resolution when <code>U</code> is of the form <code>T[]</code>.</p>
<p><b>Examples:</b></p>
<blockquote>
<pre>unique_ptr&lt;double[]&gt; p1 = boost::make_unique_noinit&lt;double[]&gt;(4);
unique_ptr&lt;int[][2]&gt; p2 = boost::make_unique_noinit&lt;int[][2]&gt;(2);</pre>
</blockquote>
</blockquote>
<h2><a name="history">History</a></h2>
<p>January 2014. Glen Fernandes contributed implementations of
make_unique for objects and arrays.</p>
<hr>
<p>$Date$</p>
<p><small>Copyright 2012-2014 Glen Fernandes. Distributed under the
Boost Software License, Version 1.0. See accompanying file
<a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy at
<a href="http://www.boost.org/LICENSE_1_0.txt">
http://www.boost.org/LICENSE_1_0.txt</a>.</small></p>
</body>
</html>

View File

@@ -1,33 +1,34 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html> <html>
<head> <head>
<title>pointer_cast.hpp</title> <title>pointer_cast</title>
</head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<body> </head>
<h1><IMG height="86" alt="C++ Boost" src="../../boost.png" width="277" align="middle" border="0">Pointer <body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
cast functions</h1> <h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
<p>The pointer cast functions (<code>boost::static_pointer_cast</code> <code>boost::dynamic_pointer_cast</code> width="277" align="middle" border="0">pointer_cast</h1>
<code>boost::reinterpret_pointer_cast</code> <code>boost::const_pointer_cast</code>) <p>The pointer cast functions (<code>boost::static_pointer_cast</code> <code>boost::dynamic_pointer_cast</code>
provide a way to write generic pointer castings for raw pointers. The functions <code>boost::reinterpret_pointer_cast</code> <code>boost::const_pointer_cast</code>)
are defined in <CITE><A href="../../boost/pointer_cast.hpp">boost/pointer_cast.hpp</A>.</CITE></p> provide a way to write generic pointer castings for raw pointers. The functions
<P>There is test/example code in <CITE><A href="test/pointer_cast_test.cpp">pointer_cast_test.cpp</A></CITE>.</p> are defined in <CITE><A href="../../boost/pointer_cast.hpp">boost/pointer_cast.hpp</A>.</CITE></p>
<h2><a name="rationale">Rationale</a></h2> <P>There is test/example code in <CITE><A href="test/pointer_cast_test.cpp">pointer_cast_test.cpp</A></CITE>.</p>
<P>Boost smart pointers usually overload those functions to provide a mechanism to <h2><a name="rationale">Rationale</a></h2>
emulate pointers casts. For example, <code>boost::shared_ptr&lt;...&gt;</code> implements <P>Boost smart pointers usually overload those functions to provide a mechanism to
a static pointer cast this way:</P> emulate pointers casts. For example, <code>boost::shared_ptr&lt;...&gt;</code> implements
<pre> a static pointer cast this way:</P>
<pre>
template&lt;class T, class U&gt; template&lt;class T, class U&gt;
shared_ptr&lt;T&gt; static_pointer_cast(shared_ptr&lt;U&gt; const &amp;r); shared_ptr&lt;T&gt; static_pointer_cast(shared_ptr&lt;U&gt; const &amp;r);
</pre> </pre>
<P>Pointer cast functions from <CITE><A href="../../boost/pointer_cast.hpp">boost/pointer_cast.hpp</A></CITE> <P>Pointer cast functions from <CITE><A href="../../boost/pointer_cast.hpp">boost/pointer_cast.hpp</A></CITE>
are overloads of <code>boost::static_pointer_cast</code>, <code>boost::dynamic_pointer_cast</code>, are overloads of <code>boost::static_pointer_cast</code>, <code>boost::dynamic_pointer_cast</code>,
<code>boost::reinterpret_pointer_cast</code> and <code>boost::const_pointer_cast</code> <code>boost::reinterpret_pointer_cast</code> and <code>boost::const_pointer_cast</code>
for raw pointers. This way when developing pointer type independent classes, for raw pointers. This way when developing pointer type independent classes,
for example, memory managers or shared memory compatible classes, the same code for example, memory managers or shared memory compatible classes, the same code
can be used for raw and smart pointers.</p> can be used for raw and smart pointers.</p>
<H2><A name="synopsis">Synopsis</A></H2> <H2><A name="synopsis">Synopsis</A></H2>
<BLOCKQUOTE> <BLOCKQUOTE>
<PRE> <PRE>
namespace boost { namespace boost {
template&lt;class T, class U&gt; template&lt;class T, class U&gt;
@@ -48,12 +49,12 @@ inline T* reinterpret_pointer_cast(U *ptr)
} // namespace boost } // namespace boost
</PRE> </PRE>
</BLOCKQUOTE> </BLOCKQUOTE>
<P>As you can see from the above synopsis, the pointer cast functions are just <P>As you can see from the above synopsis, the pointer cast functions are just
wrappers around standard C++ cast operators.</P> wrappers around standard C++ cast operators.</P>
<H2><A name="example">Example</A></H2> <H2><A name="example">Example</A></H2>
<BLOCKQUOTE> <BLOCKQUOTE>
<PRE> <PRE>
#include &lt;boost/pointer_cast.hpp&gt; #include &lt;boost/pointer_cast.hpp&gt;
#include &lt;boost/shared_ptr.hpp&gt; #include &lt;boost/shared_ptr.hpp&gt;
@@ -93,13 +94,13 @@ int main()
delete ptr; delete ptr;
return 0; return 0;
}</PRE> }</PRE>
</BLOCKQUOTE> </BLOCKQUOTE>
<P>The example demonstrates how the generic pointer casts help us create pointer <P>The example demonstrates how the generic pointer casts help us create pointer
independent code.</P> independent code.</P>
<hr> <hr>
<p>Revised: $Date$</p> <p>$Date$</p>
<p>Copyright 2005 Ion Gazta<74>aga. Use, modification, and distribution are subject to <p>Copyright 2005 Ion Gazta<74>aga. Use, modification, and distribution are subject to
the Boost Software License, Version 1.0. (See accompanying file <A href="../../LICENSE_1_0.txt"> the Boost Software License, Version 1.0. (See accompanying file <A href="../../LICENSE_1_0.txt">
LICENSE_1_0.txt</A> or a copy at &lt;<A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>&gt;.)</p> LICENSE_1_0.txt</A> or a copy at &lt;<A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>&gt;.)</p>
</body> </body>
</html> </html>

View File

@@ -1,33 +1,33 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html> <html>
<head> <head>
<title>pointer_to_other.hpp</title> <title>pointer_to_other</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head> </head>
<body bgcolor="#ffffff" text="#000000"> <body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
<h1><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" WIDTH="277" HEIGHT="86">Header <h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
<a href="../../boost/pointer_to_other.hpp">boost/pointer_to_other.hpp</a></h1> width="277" align="middle" border="0">pointer_to_other</h1>
<p> <p>
The pointer to other utility provides a way, given a source pointer type, The pointer to other utility provides a way, given a source pointer type,
to obtain a pointer of the same type to another pointee type. The utility is to obtain a pointer of the same type to another pointee type. The utility is
defined in <cite><a href="../../boost/pointer_to_other.hpp">boost/pointer_to_other.hpp</a>.</cite></p> defined in <cite><a href="../../boost/pointer_to_other.hpp">boost/pointer_to_other.hpp</a>.</cite></p>
<p>There is test/example code in <cite><a href="test/pointer_to_other_test.cpp">pointer_to_other_test.cpp</a></cite>.</p> <p>There is test/example code in <cite><a href="test/pointer_to_other_test.cpp">pointer_to_other_test.cpp</a></cite>.</p>
<h2><a name="contents">Contents</a></h2> <h2><a name="contents">Contents</a></h2>
<ul> <ul>
<li> <li>
<a href="#rationale">Rationale</a> <a href="#rationale">Rationale</a>
<li> <li>
<a href="#synopsis">Synopsis</a> <a href="#synopsis">Synopsis</a>
<li> <li>
<a href="#example">Example</a></li> <a href="#example">Example</a></li>
</ul> </ul>
<h2><a name="rationale">Rationale</a></h2> <h2><a name="rationale">Rationale</a></h2>
<p>When building pointer independent classes, like memory managers, allocators, or <p>When building pointer independent classes, like memory managers, allocators, or
containers, there is often a need to define pointers generically, so that if a containers, there is often a need to define pointers generically, so that if a
template parameter represents a pointer (for example, a raw or smart pointer to template parameter represents a pointer (for example, a raw or smart pointer to
an int), we can define another pointer of the same type to another pointee (a an int), we can define another pointer of the same type to another pointee (a
raw or smart pointer to a float.)</p> raw or smart pointer to a float.)</p>
<pre>template &lt;class IntPtr&gt; <pre>template &lt;class IntPtr&gt;
class FloatPointerHolder class FloatPointerHolder
{ {
<em>// Let's define a pointer to a float</em> <em>// Let's define a pointer to a float</em>
@@ -35,8 +35,8 @@ class FloatPointerHolder
&lt;IntPtr, float&gt;::type float_ptr_t; &lt;IntPtr, float&gt;::type float_ptr_t;
float_ptr_t float_ptr; float_ptr_t float_ptr;
};</pre> };</pre>
<h2><a name="synopsis">Synopsis</a></h2> <h2><a name="synopsis">Synopsis</a></h2>
<pre> <pre>
namespace boost { namespace boost {
template&lt;class T, class U&gt; template&lt;class T, class U&gt;
@@ -69,10 +69,10 @@ struct pointer_to_other&lt; T*, U &gt;
}; };
} <em>// namespace boost</em></pre> } <em>// namespace boost</em></pre>
<p>If these definitions are not correct for a specific smart pointer, we can define <p>If these definitions are not correct for a specific smart pointer, we can define
a specialization of pointer_to_other.</p> a specialization of pointer_to_other.</p>
<h2><a name="example">Example</a></h2> <h2><a name="example">Example</a></h2>
<pre><em>// Let's define a memory allocator that can <pre><em>// Let's define a memory allocator that can
// work with raw and smart pointers</em> // work with raw and smart pointers</em>
#include &lt;boost/pointer_to_other.hpp&gt; #include &lt;boost/pointer_to_other.hpp&gt;
@@ -97,12 +97,12 @@ class memory_allocator
block_ptr_t free_blocks; block_ptr_t free_blocks;
};</pre> };</pre>
<p>As we can see, using pointer_to_other we can create pointer independent code.</p> <p>As we can see, using pointer_to_other we can create pointer independent code.</p>
<hr> <hr>
<p>Last revised: $Date$</p> <p>$Date$</p>
<p><small>Copyright 2005, 2006 Ion Gazta<74>aga and Peter Dimov. Use, modification, <p><small>Copyright 2005, 2006 Ion Gazta<74>aga and Peter Dimov. Use, modification,
and distribution are subject to the Boost Software License, Version 1.0.<br> and distribution are subject to the Boost Software License, Version 1.0.<br>
(See accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or a (See accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or a
copy at &lt; <a href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>&gt;.)</small></p> copy at &lt; <a href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>&gt;.)</small></p>
</body> </body>
</html> </html>

View File

@@ -1,38 +1,38 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html> <html>
<head> <head>
<title>scoped_array</title> <title>scoped_array</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head> </head>
<body bgcolor="#ffffff" text="#000000"> <body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
<h1><A href="../../index.htm"><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="277" height="86" <h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
border="0"></A>scoped_array class template</h1> width="277" align="middle" border="0">scoped_array class template</h1>
<p>The <b>scoped_array</b> class template stores a pointer to a dynamically <p>The <b>scoped_array</b> class template stores a pointer to a dynamically
allocated array. (Dynamically allocated arrays are allocated with the C++ <b>new[]</b> allocated array. (Dynamically allocated arrays are allocated with the C++ <b>new[]</b>
expression.) The array pointed to is guaranteed to be deleted, either on expression.) The array pointed to is guaranteed to be deleted, either on
destruction of the <b>scoped_array</b>, or via an explicit <b>reset</b>.</p> destruction of the <b>scoped_array</b>, or via an explicit <b>reset</b>.</p>
<p>The <b>scoped_array</b> template is a simple solution for simple needs. It <p>The <b>scoped_array</b> template is a simple solution for simple needs. It
supplies a basic "resource acquisition is initialization" facility, without supplies a basic "resource acquisition is initialization" facility, without
shared-ownership or transfer-of-ownership semantics. Both its name and shared-ownership or transfer-of-ownership semantics. Both its name and
enforcement of semantics (by being <a href="../utility/utility.htm#Class_noncopyable"> enforcement of semantics (by being <a href="../utility/utility.htm#Class_noncopyable">
noncopyable</a>) signal its intent to retain ownership solely within the noncopyable</a>) signal its intent to retain ownership solely within the
current scope. Because it is <a href="../utility/utility.htm#Class_noncopyable">noncopyable</a>, current scope. Because it is <a href="../utility/utility.htm#Class_noncopyable">noncopyable</a>,
it is safer than <b>shared_array</b> for pointers which should not be copied.</p> it is safer than <b>shared_array</b> for pointers which should not be copied.</p>
<p>Because <b>scoped_array</b> is so simple, in its usual implementation every <p>Because <b>scoped_array</b> is so simple, in its usual implementation every
operation is as fast as a built-in array pointer and it has no more space operation is as fast as a built-in array pointer and it has no more space
overhead that a built-in array pointer.</p> overhead that a built-in array pointer.</p>
<p>It cannot be used in C++ standard library containers. See <a href="shared_array.htm"> <p>It cannot be used in C++ standard library containers. See <a href="shared_array.htm">
<b>shared_array</b></a> if <b>scoped_array</b> does not meet your needs.</p> <b>shared_array</b></a> if <b>scoped_array</b> does not meet your needs.</p>
<p>It cannot correctly hold a pointer to a single object. See <a href="scoped_ptr.htm"><b>scoped_ptr</b></a> <p>It cannot correctly hold a pointer to a single object. See <a href="scoped_ptr.htm"><b>scoped_ptr</b></a>
for that usage.</p> for that usage.</p>
<p>A <b>std::vector</b> is an alternative to a <b>scoped_array</b> that is a bit <p>A <b>std::vector</b> is an alternative to a <b>scoped_array</b> that is a bit
heavier duty but far more flexible. A <b>boost::array</b> is an alternative heavier duty but far more flexible. A <b>boost::array</b> is an alternative
that does not use dynamic allocation.</p> that does not use dynamic allocation.</p>
<p>The class template is parameterized on <b>T</b>, the type of the object pointed <p>The class template is parameterized on <b>T</b>, the type of the object pointed
to. <b>T</b> must meet the smart pointer <a href="smart_ptr.htm#common_requirements"> to. <b>T</b> must meet the smart pointer <a href="smart_ptr.htm#common_requirements">
common requirements</a>.</p> common requirements</a>.</p>
<h2>Synopsis</h2> <h2>Synopsis</h2>
<pre>namespace boost { <pre>namespace boost {
template&lt;class T&gt; class scoped_array : <a href="../utility/utility.htm#Class_noncopyable">noncopyable</a> { template&lt;class T&gt; class scoped_array : <a href="../utility/utility.htm#Class_noncopyable">noncopyable</a> {
@@ -55,62 +55,61 @@
template&lt;class T&gt; void <a href="#free-swap">swap</a>(scoped_array&lt;T&gt; &amp; a, scoped_array&lt;T&gt; &amp; b); // never throws template&lt;class T&gt; void <a href="#free-swap">swap</a>(scoped_array&lt;T&gt; &amp; a, scoped_array&lt;T&gt; &amp; b); // never throws
}</pre> }</pre>
<h2>Members</h2> <h2>Members</h2>
<h3> <h3>
<a name="element_type">element_type</a></h3> <a name="element_type">element_type</a></h3>
<pre>typedef T element_type;</pre> <pre>typedef T element_type;</pre>
<p>Provides the type of the stored pointer.</p> <p>Provides the type of the stored pointer.</p>
<h3><a name="ctor">constructors</a></h3> <h3><a name="ctor">constructors</a></h3>
<pre>explicit scoped_array(T * p = 0); // never throws</pre> <pre>explicit scoped_array(T * p = 0); // never throws</pre>
<p>Constructs a <b>scoped_array</b>, storing a copy of <b>p</b>, which must have <p>Constructs a <b>scoped_array</b>, storing a copy of <b>p</b>, which must have
been allocated via a C++ <b>new</b>[] expression or be 0. <b>T</b> is not been allocated via a C++ <b>new</b>[] expression or be 0. <b>T</b> is not
required be a complete type. See the smart pointer <a href="smart_ptr.htm#common_requirements"> required be a complete type. See the smart pointer <a href="smart_ptr.htm#common_requirements">
common requirements</a>.</p> common requirements</a>.</p>
<h3><a name="destructor">destructor</a></h3> <h3><a name="destructor">destructor</a></h3>
<pre>~scoped_array(); // never throws</pre> <pre>~scoped_array(); // never throws</pre>
<p>Deletes the array pointed to by the stored pointer. Note that <b>delete[]</b> on <p>Deletes the array pointed to by the stored pointer. Note that <b>delete[]</b> on
a pointer with a value of 0 is harmless. The guarantee that this does not throw a pointer with a value of 0 is harmless. The guarantee that this does not throw
exceptions depends on the requirement that the deleted array's objects' exceptions depends on the requirement that the deleted array's objects'
destructors do not throw exceptions. See the smart pointer <a href="smart_ptr.htm#common_requirements"> destructors do not throw exceptions. See the smart pointer <a href="smart_ptr.htm#common_requirements">
common requirements</a>.</p> common requirements</a>.</p>
<h3><a name="reset">reset</a></h3> <h3><a name="reset">reset</a></h3>
<pre>void reset(T * p = 0); // never throws</pre> <pre>void reset(T * p = 0); // never throws</pre>
<p> <p>
Deletes the array pointed to by the stored pointer and then stores a copy of p, Deletes the array pointed to by the stored pointer and then stores a copy of p,
which must have been allocated via a C++ <b>new[]</b> expression or be 0. The which must have been allocated via a C++ <b>new[]</b> expression or be 0. The
guarantee that this does not throw exceptions depends on the requirement that guarantee that this does not throw exceptions depends on the requirement that
the deleted array's objects' destructors do not throw exceptions. See the smart the deleted array's objects' destructors do not throw exceptions. See the smart
pointer <a href="smart_ptr.htm#common_requirements">common requirements</a>.</p> pointer <a href="smart_ptr.htm#common_requirements">common requirements</a>.</p>
<h3><a name="operator[]">subscripting</a></h3> <h3><a name="operator[]">subscripting</a></h3>
<pre>T &amp; operator[](std::ptrdiff_t i) const; // never throws</pre> <pre>T &amp; operator[](std::ptrdiff_t i) const; // never throws</pre>
<p>Returns a reference to element <b>i</b> of the array pointed to by the stored <p>Returns a reference to element <b>i</b> of the array pointed to by the stored
pointer. Behavior is undefined and almost certainly undesirable if the stored pointer. Behavior is undefined and almost certainly undesirable if the stored
pointer is 0, or if <b>i</b> is less than 0 or is greater than or equal to the pointer is 0, or if <b>i</b> is less than 0 or is greater than or equal to the
number of elements in the array.</p> number of elements in the array.</p>
<h3><a name="get">get</a></h3> <h3><a name="get">get</a></h3>
<pre>T * get() const; // never throws</pre> <pre>T * get() const; // never throws</pre>
<p>Returns the stored pointer. <b>T</b> need not be a complete type. See the smart <p>Returns the stored pointer. <b>T</b> need not be a complete type. See the smart
pointer <a href="smart_ptr.htm#common_requirements">common requirements</a>.</p> pointer <a href="smart_ptr.htm#common_requirements">common requirements</a>.</p>
<h3><a name="conversions">conversions</a></h3> <h3><a name="conversions">conversions</a></h3>
<pre>operator <i>unspecified-bool-type</i> () const; // never throws</pre> <pre>operator <i>unspecified-bool-type</i> () const; // never throws</pre>
<p>Returns an unspecified value that, when used in boolean contexts, is equivalent <p>Returns an unspecified value that, when used in boolean contexts, is equivalent
to <code>get() != 0</code>.</p> to <code>get() != 0</code>.</p>
<h3><a name="swap">swap</a></h3> <h3><a name="swap">swap</a></h3>
<pre>void swap(scoped_array &amp; b); // never throws</pre> <pre>void swap(scoped_array &amp; b); // never throws</pre>
<p>Exchanges the contents of the two smart pointers. <b>T</b> need not be a <p>Exchanges the contents of the two smart pointers. <b>T</b> need not be a
complete type. See the smart pointer <a href="smart_ptr.htm#common_requirements">common complete type. See the smart pointer <a href="smart_ptr.htm#common_requirements">common
requirements</a>.</p> requirements</a>.</p>
<h2><a name="functions">Free Functions</a></h2> <h2><a name="functions">Free Functions</a></h2>
<h3><a name="free-swap">swap</a></h3> <h3><a name="free-swap">swap</a></h3>
<pre>template&lt;class T&gt; void swap(scoped_array&lt;T&gt; &amp; a, scoped_array&lt;T&gt; &amp; b); // never throws</pre> <pre>template&lt;class T&gt; void swap(scoped_array&lt;T&gt; &amp; a, scoped_array&lt;T&gt; &amp; b); // never throws</pre>
<p>Equivalent to <b>a.swap(b)</b>. Matches the interface of <b>std::swap</b>. <p>Equivalent to <b>a.swap(b)</b>. Matches the interface of <b>std::swap</b>.
Provided as an aid to generic programming.</p> Provided as an aid to generic programming.</p>
<hr> <hr>
<p>Revised <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan--> <p>$Date$</p>
09 January 2003<!--webbot bot="Timestamp" endspan i-checksum="32310"--></p> <p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
<p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. Copyright 2002-2005 Peter Dimov. Distributed under the Boost Software License, Version
Copyright 2002-2005 Peter Dimov. Distributed under the Boost Software License, Version 1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p> </body>
</body>
</html> </html>

View File

@@ -1,38 +1,38 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html> <html>
<head> <head>
<title>scoped_ptr</title> <title>scoped_ptr</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head> </head>
<body bgcolor="#ffffff" text="#000000"> <body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
<h1><A href="../../index.htm"><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="277" height="86" <h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
border="0"></A>scoped_ptr class template</h1> width="277" align="middle" border="0">scoped_ptr class template</h1>
<p>The <b>scoped_ptr</b> class template stores a pointer to a dynamically allocated <p>The <b>scoped_ptr</b> class template stores a pointer to a dynamically allocated
object. (Dynamically allocated objects are allocated with the C++ <b>new</b> expression.) object. (Dynamically allocated objects are allocated with the C++ <b>new</b> expression.)
The object pointed to is guaranteed to be deleted, either on destruction of the <b>scoped_ptr</b>, The object pointed to is guaranteed to be deleted, either on destruction of the <b>scoped_ptr</b>,
or via an explicit <b>reset</b>. See the <a href="#example">example</a>.</p> or via an explicit <b>reset</b>. See the <a href="#example">example</a>.</p>
<p>The <b>scoped_ptr</b> template is a simple solution for simple needs. It <p>The <b>scoped_ptr</b> template is a simple solution for simple needs. It
supplies a basic "resource acquisition is initialization" facility, without supplies a basic "resource acquisition is initialization" facility, without
shared-ownership or transfer-of-ownership semantics. Both its name and shared-ownership or transfer-of-ownership semantics. Both its name and
enforcement of semantics (by being <a href="../utility/utility.htm#Class_noncopyable"> enforcement of semantics (by being <a href="../utility/utility.htm#Class_noncopyable">
noncopyable</a>) signal its intent to retain ownership solely within the noncopyable</a>) signal its intent to retain ownership solely within the
current scope. Because it is <a href="../utility/utility.htm#Class_noncopyable">noncopyable</a>, current scope. Because it is <a href="../utility/utility.htm#Class_noncopyable">noncopyable</a>,
it is safer than <b>shared_ptr</b> or <b>std::auto_ptr</b> for pointers which it is safer than <b>shared_ptr</b> or <b>std::auto_ptr</b> for pointers which
should not be copied.</p> should not be copied.</p>
<p>Because <b>scoped_ptr</b> is simple, in its usual implementation every operation <p>Because <b>scoped_ptr</b> is simple, in its usual implementation every operation
is as fast as for a built-in pointer and it has no more space overhead that a is as fast as for a built-in pointer and it has no more space overhead that a
built-in pointer.</p> built-in pointer.</p>
<p><STRONG>scoped_ptr</STRONG> cannot be used in C++ Standard Library containers. <p><STRONG>scoped_ptr</STRONG> cannot be used in C++ Standard Library containers.
Use <a href="shared_ptr.htm"><b>shared_ptr</b></a> if you need a smart pointer Use <a href="shared_ptr.htm"><b>shared_ptr</b></a> if you need a smart pointer
that can.</p> that can.</p>
<p><STRONG>scoped_ptr</STRONG> cannot correctly hold a pointer to a dynamically <p><STRONG>scoped_ptr</STRONG> cannot correctly hold a pointer to a dynamically
allocated array. See <a href="scoped_array.htm"><b>scoped_array</b></a> for allocated array. See <a href="scoped_array.htm"><b>scoped_array</b></a> for
that usage.</p> that usage.</p>
<p>The class template is parameterized on <b>T</b>, the type of the object pointed <p>The class template is parameterized on <b>T</b>, the type of the object pointed
to. <b>T</b> must meet the smart pointer <a href="smart_ptr.htm#common_requirements"> to. <b>T</b> must meet the smart pointer <a href="smart_ptr.htm#common_requirements">
common requirements</a>.</p> common requirements</a>.</p>
<h2>Synopsis</h2> <h2>Synopsis</h2>
<pre>namespace boost { <pre>namespace boost {
template&lt;class T&gt; class scoped_ptr : <a href="../utility/utility.htm#Class_noncopyable">noncopyable</a> { template&lt;class T&gt; class scoped_ptr : <a href="../utility/utility.htm#Class_noncopyable">noncopyable</a> {
@@ -56,60 +56,60 @@
template&lt;class T&gt; void <a href="#free-swap">swap</a>(scoped_ptr&lt;T&gt; &amp; a, scoped_ptr&lt;T&gt; &amp; b); // never throws template&lt;class T&gt; void <a href="#free-swap">swap</a>(scoped_ptr&lt;T&gt; &amp; a, scoped_ptr&lt;T&gt; &amp; b); // never throws
}</pre> }</pre>
<h2>Members</h2> <h2>Members</h2>
<h3><a name="element_type">element_type</a></h3> <h3><a name="element_type">element_type</a></h3>
<pre>typedef T element_type;</pre> <pre>typedef T element_type;</pre>
<p>Provides the type of the stored pointer.</p> <p>Provides the type of the stored pointer.</p>
<h3><a name="constructors">constructors</a></h3> <h3><a name="constructors">constructors</a></h3>
<pre>explicit scoped_ptr(T * p = 0); // never throws</pre> <pre>explicit scoped_ptr(T * p = 0); // never throws</pre>
<p>Constructs a <b>scoped_ptr</b>, storing a copy of <b>p</b>, which must have been <p>Constructs a <b>scoped_ptr</b>, storing a copy of <b>p</b>, which must have been
allocated via a C++ <b>new</b> expression or be 0. <b>T</b> is not required be allocated via a C++ <b>new</b> expression or be 0. <b>T</b> is not required be
a complete type. See the smart pointer <a href="smart_ptr.htm#common_requirements">common a complete type. See the smart pointer <a href="smart_ptr.htm#common_requirements">common
requirements</a>.</p> requirements</a>.</p>
<h3><a name="destructor">destructor</a></h3> <h3><a name="destructor">destructor</a></h3>
<pre>~scoped_ptr(); // never throws</pre> <pre>~scoped_ptr(); // never throws</pre>
<p>Destroys the object pointed to by the stored pointer, if any, as if by using <tt>delete <p>Destroys the object pointed to by the stored pointer, if any, as if by using <tt>delete
this-&gt;get()</tt>.</p> this-&gt;get()</tt>.</p>
<P> <P>
The guarantee that this does not throw exceptions depends on the requirement The guarantee that this does not throw exceptions depends on the requirement
that the deleted object's destructor does not throw exceptions. See the smart that the deleted object's destructor does not throw exceptions. See the smart
pointer <a href="smart_ptr.htm#common_requirements">common requirements</a>.</P> pointer <a href="smart_ptr.htm#common_requirements">common requirements</a>.</P>
<h3><a name="reset">reset</a></h3> <h3><a name="reset">reset</a></h3>
<pre>void reset(T * p = 0); // never throws</pre> <pre>void reset(T * p = 0); // never throws</pre>
<p> <p>
Deletes the object pointed to by the stored pointer and then stores a copy of Deletes the object pointed to by the stored pointer and then stores a copy of
p, which must have been allocated via a C++ <b>new</b> expression or be 0. The p, which must have been allocated via a C++ <b>new</b> expression or be 0. The
guarantee that this does not throw exceptions depends on the requirement that guarantee that this does not throw exceptions depends on the requirement that
the deleted object's destructor does not throw exceptions. See the smart the deleted object's destructor does not throw exceptions. See the smart
pointer <a href="smart_ptr.htm#common_requirements">common requirements</a>.</p> pointer <a href="smart_ptr.htm#common_requirements">common requirements</a>.</p>
<h3><a name="indirection">indirection</a></h3> <h3><a name="indirection">indirection</a></h3>
<pre>T &amp; operator*() const; // never throws</pre> <pre>T &amp; operator*() const; // never throws</pre>
<p>Returns a reference to the object pointed to by the stored pointer. Behavior is <p>Returns a reference to the object pointed to by the stored pointer. Behavior is
undefined if the stored pointer is 0.</p> undefined if the stored pointer is 0.</p>
<pre>T * operator-&gt;() const; // never throws</pre> <pre>T * operator-&gt;() const; // never throws</pre>
<p>Returns the stored pointer. Behavior is undefined if the stored pointer is 0.</p> <p>Returns the stored pointer. Behavior is undefined if the stored pointer is 0.</p>
<h3><a name="get">get</a></h3> <h3><a name="get">get</a></h3>
<pre>T * get() const; // never throws</pre> <pre>T * get() const; // never throws</pre>
<p>Returns the stored pointer. <b>T</b> need not be a complete type. See the smart <p>Returns the stored pointer. <b>T</b> need not be a complete type. See the smart
pointer <a href="smart_ptr.htm#common_requirements">common requirements</a>.</p> pointer <a href="smart_ptr.htm#common_requirements">common requirements</a>.</p>
<h3><a name="conversions">conversions</a></h3> <h3><a name="conversions">conversions</a></h3>
<pre>operator <i>unspecified-bool-type</i> () const; // never throws</pre> <pre>operator <i>unspecified-bool-type</i> () const; // never throws</pre>
<p>Returns an unspecified value that, when used in boolean contexts, is equivalent <p>Returns an unspecified value that, when used in boolean contexts, is equivalent
to <code>get() != 0</code>.</p> to <code>get() != 0</code>.</p>
<h3><a name="swap">swap</a></h3> <h3><a name="swap">swap</a></h3>
<pre>void swap(scoped_ptr &amp; b); // never throws</pre> <pre>void swap(scoped_ptr &amp; b); // never throws</pre>
<p>Exchanges the contents of the two smart pointers. <b>T</b> need not be a <p>Exchanges the contents of the two smart pointers. <b>T</b> need not be a
complete type. See the smart pointer <a href="smart_ptr.htm#common_requirements">common complete type. See the smart pointer <a href="smart_ptr.htm#common_requirements">common
requirements</a>.</p> requirements</a>.</p>
<h2><a name="functions">Free Functions</a></h2> <h2><a name="functions">Free Functions</a></h2>
<h3><a name="free-swap">swap</a></h3> <h3><a name="free-swap">swap</a></h3>
<pre>template&lt;class T&gt; void swap(scoped_ptr&lt;T&gt; &amp; a, scoped_ptr&lt;T&gt; &amp; b); // never throws</pre> <pre>template&lt;class T&gt; void swap(scoped_ptr&lt;T&gt; &amp; a, scoped_ptr&lt;T&gt; &amp; b); // never throws</pre>
<p>Equivalent to <b>a.swap(b)</b>. Matches the interface of <b>std::swap</b>. <p>Equivalent to <b>a.swap(b)</b>. Matches the interface of <b>std::swap</b>.
Provided as an aid to generic programming.</p> Provided as an aid to generic programming.</p>
<h2><a name="example">Example</a></h2> <h2><a name="example">Example</a></h2>
<p>Here's an example that uses <b>scoped_ptr</b>.</p> <p>Here's an example that uses <b>scoped_ptr</b>.</p>
<blockquote> <blockquote>
<pre>#include &lt;boost/scoped_ptr.hpp&gt; <pre>#include &lt;boost/scoped_ptr.hpp&gt;
#include &lt;iostream&gt; #include &lt;iostream&gt;
struct Shoe { ~Shoe() { std::cout &lt;&lt; "Buckle my shoe\n"; } }; struct Shoe { ~Shoe() { std::cout &lt;&lt; "Buckle my shoe\n"; } };
@@ -128,54 +128,53 @@ int main()
std::cout &lt;&lt; my_instance.add_one() &lt;&lt; '\n'; std::cout &lt;&lt; my_instance.add_one() &lt;&lt; '\n';
std::cout &lt;&lt; my_instance.add_one() &lt;&lt; '\n'; std::cout &lt;&lt; my_instance.add_one() &lt;&lt; '\n';
}</pre> }</pre>
</blockquote> </blockquote>
<p>The example program produces the beginning of a child's nursery rhyme:</p> <p>The example program produces the beginning of a child's nursery rhyme:</p>
<blockquote> <blockquote>
<pre>1 <pre>1
2 2
Buckle my shoe</pre> Buckle my shoe</pre>
</blockquote> </blockquote>
<h2>Rationale</h2> <h2>Rationale</h2>
<p>The primary reason to use <b>scoped_ptr</b> rather than <b>auto_ptr</b> is to <p>The primary reason to use <b>scoped_ptr</b> rather than <b>auto_ptr</b> is to
let readers of your code know that you intend "resource acquisition is let readers of your code know that you intend "resource acquisition is
initialization" to be applied only for the current scope, and have no intent to initialization" to be applied only for the current scope, and have no intent to
transfer ownership.</p> transfer ownership.</p>
<p>A secondary reason to use <b>scoped_ptr</b> is to prevent a later maintenance <p>A secondary reason to use <b>scoped_ptr</b> is to prevent a later maintenance
programmer from adding a function that transfers ownership by returning the <b>auto_ptr</b>, programmer from adding a function that transfers ownership by returning the <b>auto_ptr</b>,
because the maintenance programmer saw <b>auto_ptr</b>, and assumed ownership because the maintenance programmer saw <b>auto_ptr</b>, and assumed ownership
could safely be transferred.</p> could safely be transferred.</p>
<p>Think of <b>bool</b> vs <b>int</b>. We all know that under the covers <b>bool</b> <p>Think of <b>bool</b> vs <b>int</b>. We all know that under the covers <b>bool</b>
is usually just an <b>int</b>. Indeed, some argued against including <b>bool</b> is usually just an <b>int</b>. Indeed, some argued against including <b>bool</b>
in the C++ standard because of that. But by coding <b>bool</b> rather than <b>int</b>, in the C++ standard because of that. But by coding <b>bool</b> rather than <b>int</b>,
you tell your readers what your intent is. Same with <b>scoped_ptr</b>; by you tell your readers what your intent is. Same with <b>scoped_ptr</b>; by
using it you are signaling intent.</p> using it you are signaling intent.</p>
<p>It has been suggested that <b>scoped_ptr&lt;T&gt;</b> is equivalent to <b>std::auto_ptr&lt;T&gt; <p>It has been suggested that <b>scoped_ptr&lt;T&gt;</b> is equivalent to <b>std::auto_ptr&lt;T&gt;
const</b>. Ed Brey pointed out, however, that <b>reset</b> will not work on const</b>. Ed Brey pointed out, however, that <b>reset</b> will not work on
a <b>std::auto_ptr&lt;T&gt; const.</b></p> a <b>std::auto_ptr&lt;T&gt; const.</b></p>
<h2><a name="Handle/Body">Handle/Body</a> Idiom</h2> <h2><a name="Handle/Body">Handle/Body</a> Idiom</h2>
<p>One common usage of <b>scoped_ptr</b> is to implement a handle/body (also called <p>One common usage of <b>scoped_ptr</b> is to implement a handle/body (also called
pimpl) idiom which avoids exposing the body (implementation) in the header pimpl) idiom which avoids exposing the body (implementation) in the header
file.</p> file.</p>
<p>The <a href="example/scoped_ptr_example_test.cpp">scoped_ptr_example_test.cpp</a> <p>The <a href="example/scoped_ptr_example_test.cpp">scoped_ptr_example_test.cpp</a>
sample program includes a header file, <a href="example/scoped_ptr_example.hpp">scoped_ptr_example.hpp</a>, sample program includes a header file, <a href="example/scoped_ptr_example.hpp">scoped_ptr_example.hpp</a>,
which uses a <b>scoped_ptr&lt;&gt;</b> to an incomplete type to hide the which uses a <b>scoped_ptr&lt;&gt;</b> to an incomplete type to hide the
implementation. The instantiation of member functions which require a complete implementation. The instantiation of member functions which require a complete
type occurs in the <a href="example/scoped_ptr_example.cpp">scoped_ptr_example.cpp</a> type occurs in the <a href="example/scoped_ptr_example.cpp">scoped_ptr_example.cpp</a>
implementation file.</p> implementation file.</p>
<h2>Frequently Asked Questions</h2> <h2>Frequently Asked Questions</h2>
<p><b>Q</b>. Why doesn't <b>scoped_ptr</b> have a release() member?<br> <p><b>Q</b>. Why doesn't <b>scoped_ptr</b> have a release() member?<br>
<b>A</b>. When reading source code, it is valuable to be able to draw <b>A</b>. When reading source code, it is valuable to be able to draw
conclusions about program behavior based on the types being used. If <STRONG>scoped_ptr</STRONG> conclusions about program behavior based on the types being used. If <STRONG>scoped_ptr</STRONG>
had a release() member, it would become possible to transfer ownership of the had a release() member, it would become possible to transfer ownership of the
held pointer, weakening its role as a way of limiting resource lifetime to a held pointer, weakening its role as a way of limiting resource lifetime to a
given context. Use <STRONG>std::auto_ptr</STRONG> where transfer of ownership given context. Use <STRONG>std::auto_ptr</STRONG> where transfer of ownership
is required. (supplied by Dave Abrahams)</p> is required. (supplied by Dave Abrahams)</p>
<hr> <hr>
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B %Y" startspan --> <p>$Date</p>
09 January 2003<!--webbot bot="Timestamp" endspan i-checksum="32310" --></p> <p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
<p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. Copyright 2002-2005 Peter Dimov. Distributed under the Boost Software License, Version
Copyright 2002-2005 Peter Dimov. Distributed under the Boost Software License, Version 1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p> </body>
</body>
</html> </html>

View File

@@ -1,35 +1,35 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html> <html>
<head> <head>
<title>shared_array</title> <title>shared_array</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head> </head>
<body bgcolor="#ffffff" text="#000000"> <body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
<h1><A href="../../index.htm"><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="277" height="86" <h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
border="0"></A>shared_array class template</h1> width="277" align="middle" border="0">shared_array class template</h1>
<p>The <b>shared_array</b> class template stores a pointer to a dynamically <p>The <b>shared_array</b> class template stores a pointer to a dynamically
allocated array. (Dynamically allocated array are allocated with the C++ <b>new[]</b> allocated array. (Dynamically allocated array are allocated with the C++ <b>new[]</b>
expression.) The object pointed to is guaranteed to be deleted when the last <b>shared_array</b> expression.) The object pointed to is guaranteed to be deleted when the last <b>shared_array</b>
pointing to it is destroyed or reset.</p> pointing to it is destroyed or reset.</p>
<p>Every <b>shared_array</b> meets the <b>CopyConstructible</b> and <b>Assignable</b> <p>Every <b>shared_array</b> meets the <b>CopyConstructible</b> and <b>Assignable</b>
requirements of the C++ Standard Library, and so can be used in standard requirements of the C++ Standard Library, and so can be used in standard
library containers. Comparison operators are supplied so that <b>shared_array</b> library containers. Comparison operators are supplied so that <b>shared_array</b>
works with the standard library's associative containers.</p> works with the standard library's associative containers.</p>
<p>Normally, a <b>shared_array</b> cannot correctly hold a pointer to an object <p>Normally, a <b>shared_array</b> cannot correctly hold a pointer to an object
that has been allocated with the non-array form of <STRONG>new</STRONG>. See <a href="shared_ptr.htm"> that has been allocated with the non-array form of <STRONG>new</STRONG>. See <a href="shared_ptr.htm">
<b>shared_ptr</b></a> for that usage.</p> <b>shared_ptr</b></a> for that usage.</p>
<p>Because the implementation uses reference counting, cycles of <b>shared_array</b> <p>Because the implementation uses reference counting, cycles of <b>shared_array</b>
instances will not be reclaimed. For example, if <b>main()</b> holds a <b>shared_array</b> instances will not be reclaimed. For example, if <b>main()</b> holds a <b>shared_array</b>
to <b>A</b>, which directly or indirectly holds a <b>shared_array</b> back to <b>A</b>, to <b>A</b>, which directly or indirectly holds a <b>shared_array</b> back to <b>A</b>,
<b>A</b>'s use count will be 2. Destruction of the original <b>shared_array</b> <b>A</b>'s use count will be 2. Destruction of the original <b>shared_array</b>
will leave <b>A</b> dangling with a use count of 1.</p> will leave <b>A</b> dangling with a use count of 1.</p>
<p>A <b>shared_ptr</b> to a <b>std::vector</b> is an alternative to a <b>shared_array</b> <p>A <b>shared_ptr</b> to a <b>std::vector</b> is an alternative to a <b>shared_array</b>
that is a bit heavier duty but far more flexible.</p> that is a bit heavier duty but far more flexible.</p>
<p>The class template is parameterized on <b>T</b>, the type of the object pointed <p>The class template is parameterized on <b>T</b>, the type of the object pointed
to. <b>T</b> must meet the smart pointer <a href="smart_ptr.htm#common_requirements"> to. <b>T</b> must meet the smart pointer <a href="smart_ptr.htm#common_requirements">
common requirements</a>.</p> common requirements</a>.</p>
<h2>Synopsis</h2> <h2>Synopsis</h2>
<pre>namespace boost { <pre>namespace boost {
template&lt;class T&gt; class shared_array { template&lt;class T&gt; class shared_array {
@@ -68,118 +68,116 @@
template&lt;class T&gt; void <a href="#free-swap">swap</a>(shared_array&lt;T&gt; &amp; a, shared_array&lt;T&gt; &amp; b); // never throws template&lt;class T&gt; void <a href="#free-swap">swap</a>(shared_array&lt;T&gt; &amp; a, shared_array&lt;T&gt; &amp; b); // never throws
}</pre> }</pre>
<h2>Members</h2> <h2>Members</h2>
<h3><a name="element_type">element_type</a></h3> <h3><a name="element_type">element_type</a></h3>
<pre>typedef T element_type;</pre> <pre>typedef T element_type;</pre>
<p>Provides the type of the stored pointer.</p> <p>Provides the type of the stored pointer.</p>
<h3><a name="constructors">constructors</a></h3> <h3><a name="constructors">constructors</a></h3>
<pre>explicit shared_array(T * p = 0);</pre> <pre>explicit shared_array(T * p = 0);</pre>
<p>Constructs a <b>shared_array</b>, storing a copy of <b>p</b>, which must be a <p>Constructs a <b>shared_array</b>, storing a copy of <b>p</b>, which must be a
pointer to an array that was allocated via a C++ <b>new[]</b> expression or be pointer to an array that was allocated via a C++ <b>new[]</b> expression or be
0. Afterwards, the <a href="#use_count">use count</a> is 1 (even if p == 0; see <a href="#destructor"> 0. Afterwards, the <a href="#use_count">use count</a> is 1 (even if p == 0; see <a href="#destructor">
~shared_array</a>). The only exception which may be thrown by this ~shared_array</a>). The only exception which may be thrown by this
constructor is <b>std::bad_alloc</b>. If an exception is thrown, <b>delete[] p</b> constructor is <b>std::bad_alloc</b>. If an exception is thrown, <b>delete[] p</b>
is called.</p> is called.</p>
<pre>template&lt;class D&gt; shared_array(T * p, D d);</pre> <pre>template&lt;class D&gt; shared_array(T * p, D d);</pre>
<p>Constructs a <b>shared_array</b>, storing a copy of <b>p</b> and of <b>d</b>. <p>Constructs a <b>shared_array</b>, storing a copy of <b>p</b> and of <b>d</b>.
Afterwards, the <a href="#use_count">use count</a> is 1. <b>D</b>'s copy Afterwards, the <a href="#use_count">use count</a> is 1. <b>D</b>'s copy
constructor and destructor must not throw. When the the time comes to delete constructor and destructor must not throw. When the the time comes to delete
the array pointed to by <b>p</b>, the object <b>d</b> is used in the statement <b>d(p)</b>. the array pointed to by <b>p</b>, the object <b>d</b> is used in the statement <b>d(p)</b>.
Invoking the object <b>d</b> with parameter <b>p</b> in this way must not Invoking the object <b>d</b> with parameter <b>p</b> in this way must not
throw. The only exception which may be thrown by this constructor is <b>std::bad_alloc</b>. throw. The only exception which may be thrown by this constructor is <b>std::bad_alloc</b>.
If an exception is thrown, <b>d(p)</b> is called.</p> If an exception is thrown, <b>d(p)</b> is called.</p>
<pre>shared_array(shared_array const &amp; r); // never throws</pre> <pre>shared_array(shared_array const &amp; r); // never throws</pre>
<p>Constructs a <b>shared_array</b>, as if by storing a copy of the pointer stored <p>Constructs a <b>shared_array</b>, as if by storing a copy of the pointer stored
in <b>r</b>. Afterwards, the <a href="#use_count">use count</a> for all copies in <b>r</b>. Afterwards, the <a href="#use_count">use count</a> for all copies
is 1 more than the initial use count.</p> is 1 more than the initial use count.</p>
<h3><a name="destructor">destructor</a></h3> <h3><a name="destructor">destructor</a></h3>
<pre>~shared_array(); // never throws</pre> <pre>~shared_array(); // never throws</pre>
<p>Decrements the <a href="#use_count">use count</a>. Then, if the use count is 0, <p>Decrements the <a href="#use_count">use count</a>. Then, if the use count is 0,
deletes the array pointed to by the stored pointer. Note that <b>delete[]</b> on deletes the array pointed to by the stored pointer. Note that <b>delete[]</b> on
a pointer with a value of 0 is harmless. <b>T</b> need not be a complete type. a pointer with a value of 0 is harmless. <b>T</b> need not be a complete type.
The guarantee that this does not throw exceptions depends on the requirement The guarantee that this does not throw exceptions depends on the requirement
that the deleted object's destructor does not throw exceptions. See the smart that the deleted object's destructor does not throw exceptions. See the smart
pointer <a href="smart_ptr.htm#common_requirements">common requirements</a>.</p> pointer <a href="smart_ptr.htm#common_requirements">common requirements</a>.</p>
<h3><a name="assignment">assignment</a></h3> <h3><a name="assignment">assignment</a></h3>
<pre>shared_array &amp; operator=(shared_array const &amp; r); // never throws</pre> <pre>shared_array &amp; operator=(shared_array const &amp; r); // never throws</pre>
<p>Constructs a new <b>shared_array</b> as described <a href="#constructors">above</a>, <p>Constructs a new <b>shared_array</b> as described <a href="#constructors">above</a>,
then replaces this <b>shared_array</b> with the new one, destroying the then replaces this <b>shared_array</b> with the new one, destroying the
replaced object.</p> replaced object.</p>
<h3><a name="reset">reset</a></h3> <h3><a name="reset">reset</a></h3>
<pre>void reset(T * p = 0);</pre> <pre>void reset(T * p = 0);</pre>
<p>Constructs a new <b>shared_array</b> as described <a href="#constructors">above</a>, <p>Constructs a new <b>shared_array</b> as described <a href="#constructors">above</a>,
then replaces this <b>shared_array</b> with the new one, destroying the then replaces this <b>shared_array</b> with the new one, destroying the
replaced object. The only exception which may be thrown is <b>std::bad_alloc</b>. replaced object. The only exception which may be thrown is <b>std::bad_alloc</b>.
If an exception is thrown, <b>delete[] p</b> is called.</p> If an exception is thrown, <b>delete[] p</b> is called.</p>
<pre>template&lt;class D&gt; void reset(T * p, D d);</pre> <pre>template&lt;class D&gt; void reset(T * p, D d);</pre>
<p>Constructs a new <b>shared_array</b> as described <a href="#constructors">above</a>, <p>Constructs a new <b>shared_array</b> as described <a href="#constructors">above</a>,
then replaces this <b>shared_array</b> with the new one, destroying the then replaces this <b>shared_array</b> with the new one, destroying the
replaced object. <b>D</b>'s copy constructor must not throw. The only exception replaced object. <b>D</b>'s copy constructor must not throw. The only exception
which may be thrown is <b>std::bad_alloc</b>. If an exception is thrown, <b>d(p)</b> which may be thrown is <b>std::bad_alloc</b>. If an exception is thrown, <b>d(p)</b>
is called.</p> is called.</p>
<h3><a name="indexing">indexing</a></h3> <h3><a name="indexing">indexing</a></h3>
<pre>T &amp; operator[](std::ptrdiff_t i) const; // never throws</pre> <pre>T &amp; operator[](std::ptrdiff_t i) const; // never throws</pre>
<p>Returns a reference to element <b>i</b> of the array pointed to by the stored <p>Returns a reference to element <b>i</b> of the array pointed to by the stored
pointer. Behavior is undefined and almost certainly undesirable if the stored pointer. Behavior is undefined and almost certainly undesirable if the stored
pointer is 0, or if <b>i</b> is less than 0 or is greater than or equal to the pointer is 0, or if <b>i</b> is less than 0 or is greater than or equal to the
number of elements in the array.</p> number of elements in the array.</p>
<h3><a name="get">get</a></h3> <h3><a name="get">get</a></h3>
<pre>T * get() const; // never throws</pre> <pre>T * get() const; // never throws</pre>
<p>Returns the stored pointer. <b>T</b> need not be a complete type. See the smart <p>Returns the stored pointer. <b>T</b> need not be a complete type. See the smart
pointer <a href="smart_ptr.htm#common_requirements">common requirements</a>.</p> pointer <a href="smart_ptr.htm#common_requirements">common requirements</a>.</p>
<h3><a name="unique">unique</a></h3> <h3><a name="unique">unique</a></h3>
<pre>bool unique() const; // never throws</pre> <pre>bool unique() const; // never throws</pre>
<p>Returns true if no other <b>shared_array</b> is sharing ownership of the stored <p>Returns true if no other <b>shared_array</b> is sharing ownership of the stored
pointer, false otherwise. <b>T</b> need not be a complete type. See the smart pointer, false otherwise. <b>T</b> need not be a complete type. See the smart
pointer <a href="smart_ptr.htm#common_requirements">common requirements</a>.</p> pointer <a href="smart_ptr.htm#common_requirements">common requirements</a>.</p>
<h3><a name="use_count">use_count</a></h3> <h3><a name="use_count">use_count</a></h3>
<pre>long use_count() const; // never throws</pre> <pre>long use_count() const; // never throws</pre>
<p>Returns the number of <b>shared_array</b> objects sharing ownership of the <p>Returns the number of <b>shared_array</b> objects sharing ownership of the
stored pointer. <b>T</b> need not be a complete type. See the smart pointer <a href="smart_ptr.htm#common_requirements"> stored pointer. <b>T</b> need not be a complete type. See the smart pointer <a href="smart_ptr.htm#common_requirements">
common requirements</a>.</p> common requirements</a>.</p>
<p>Because <b>use_count</b> is not necessarily efficient to implement for <p>Because <b>use_count</b> is not necessarily efficient to implement for
implementations of <b>shared_array</b> that do not use an explicit reference implementations of <b>shared_array</b> that do not use an explicit reference
count, it might be removed from some future version. Thus it should be used for count, it might be removed from some future version. Thus it should be used for
debugging purposes only, and not production code.</p> debugging purposes only, and not production code.</p>
<h3><a name="conversions">conversions</a></h3> <h3><a name="conversions">conversions</a></h3>
<pre>operator <i>unspecified-bool-type</i> () const; // never throws</pre> <pre>operator <i>unspecified-bool-type</i> () const; // never throws</pre>
<p>Returns an unspecified value that, when used in boolean contexts, is equivalent <p>Returns an unspecified value that, when used in boolean contexts, is equivalent
to <code>get() != 0</code>.</p> to <code>get() != 0</code>.</p>
<h3><a name="swap">swap</a></h3> <h3><a name="swap">swap</a></h3>
<pre>void swap(shared_ptr &amp; b); // never throws</pre> <pre>void swap(shared_ptr &amp; b); // never throws</pre>
<p>Exchanges the contents of the two smart pointers. <b>T</b> need not be a <p>Exchanges the contents of the two smart pointers. <b>T</b> need not be a
complete type. See the smart pointer <a href="smart_ptr.htm#common_requirements">common complete type. See the smart pointer <a href="smart_ptr.htm#common_requirements">common
requirements</a>.</p> requirements</a>.</p>
<h2><a name="functions">Free Functions</a></h2> <h2><a name="functions">Free Functions</a></h2>
<h3><a name="comparison">comparison</a></h3> <h3><a name="comparison">comparison</a></h3>
<pre>template&lt;class T&gt; <pre>template&lt;class T&gt;
bool operator==(shared_array&lt;T&gt; const &amp; a, shared_array&lt;T&gt; const &amp; b); // never throws bool operator==(shared_array&lt;T&gt; const &amp; a, shared_array&lt;T&gt; const &amp; b); // never throws
template&lt;class T&gt; template&lt;class T&gt;
bool operator!=(shared_array&lt;T&gt; const &amp; a, shared_array&lt;T&gt; const &amp; b); // never throws bool operator!=(shared_array&lt;T&gt; const &amp; a, shared_array&lt;T&gt; const &amp; b); // never throws
template&lt;class T&gt; template&lt;class T&gt;
bool operator&lt;(shared_array&lt;T&gt; const &amp; a, shared_array&lt;T&gt; const &amp; b); // never throws</pre> bool operator&lt;(shared_array&lt;T&gt; const &amp; a, shared_array&lt;T&gt; const &amp; b); // never throws</pre>
<p>Compares the stored pointers of the two smart pointers. <b>T</b> need not be a <p>Compares the stored pointers of the two smart pointers. <b>T</b> need not be a
complete type. See the smart pointer <a href="smart_ptr.htm#common_requirements">common complete type. See the smart pointer <a href="smart_ptr.htm#common_requirements">common
requirements</a>.</p> requirements</a>.</p>
<p>The <b>operator&lt;</b> overload is provided to define an ordering so that <b>shared_array</b> <p>The <b>operator&lt;</b> overload is provided to define an ordering so that <b>shared_array</b>
objects can be used in associative containers such as <b>std::map</b>. The objects can be used in associative containers such as <b>std::map</b>. The
implementation uses <b>std::less&lt;T *&gt;</b> to perform the comparison. This implementation uses <b>std::less&lt;T *&gt;</b> to perform the comparison. This
ensures that the comparison is handled correctly, since the standard mandates ensures that the comparison is handled correctly, since the standard mandates
that relational operations on pointers are unspecified (5.9 [expr.rel] that relational operations on pointers are unspecified (5.9 [expr.rel]
paragraph 2) but <b>std::less&lt;&gt;</b> on pointers is well-defined (20.3.3 paragraph 2) but <b>std::less&lt;&gt;</b> on pointers is well-defined (20.3.3
[lib.comparisons] paragraph 8).</p> [lib.comparisons] paragraph 8).</p>
<h3><a name="free-swap">swap</a></h3> <h3><a name="free-swap">swap</a></h3>
<pre>template&lt;class T&gt; <pre>template&lt;class T&gt;
void swap(shared_array&lt;T&gt; &amp; a, shared_array&lt;T&gt; &amp; b) // never throws</pre> void swap(shared_array&lt;T&gt; &amp; a, shared_array&lt;T&gt; &amp; b) // never throws</pre>
<p>Equivalent to <b>a.swap(b)</b>. Matches the interface of <b>std::swap</b>. <p>Equivalent to <b>a.swap(b)</b>. Matches the interface of <b>std::swap</b>.
Provided as an aid to generic programming.</p> Provided as an aid to generic programming.</p>
<hr> <hr>
<p>Revised <p>$Date$</p>
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan --> <p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler.
09 January 2003<!--webbot bot="Timestamp" endspan i-checksum="32310" --></p> Copyright 2002-2005 Peter Dimov. Distributed under the Boost Software License, Version
<p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. 1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or
Copyright 2002-2005 Peter Dimov. Distributed under the Boost Software License, Version copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or </body>
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> </html>

File diff suppressed because it is too large Load Diff

View File

@@ -1,196 +1,221 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html> <html>
<head> <head>
<title>Smart Pointers</title> <title>Smart Pointers</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head> </head>
<body bgcolor="#ffffff" text="#000000"> <body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
<h1><A href="../../index.htm"><img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="277" height="86" <h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
border="0"></A>Smart Pointers</h1> width="277" align="middle" border="0">Smart Pointers</h1>
<p><a href="#Introduction">Introduction</a><br> <p><a href="#Introduction">Introduction</a><br>
<a href="#common_requirements">Common Requirements</a><br> <a href="#common_requirements">Common Requirements</a><br>
<a href="#Exception_Safety">Exception Safety</a><br> <a href="#Exception_Safety">Exception Safety</a><br>
<a href="#Exception-specifications">Exception-specifications</a><br> <a href="#Exception-specifications">Exception-specifications</a><br>
<a href="#History">History and Acknowledgements</a><br> <a href="#History">History and Acknowledgements</a><br>
<a href="#References">References</a></p> <a href="#References">References</a></p>
<h2><a name="Introduction">Introduction</a></h2> <h2><a name="Introduction">Introduction</a></h2>
<p>Smart pointers are objects which store pointers to dynamically allocated (heap) <p>Smart pointers are objects which store pointers to dynamically allocated (heap)
objects. They behave much like built-in C++ pointers except that they objects. They behave much like built-in C++ pointers except that they
automatically delete the object pointed to at the appropriate time. Smart automatically delete the object pointed to at the appropriate time. Smart
pointers are particularly useful in the face of exceptions as they ensure pointers are particularly useful in the face of exceptions as they ensure
proper destruction of dynamically allocated objects. They can also be used to proper destruction of dynamically allocated objects. They can also be used to
keep track of dynamically allocated objects shared by multiple owners.</p> keep track of dynamically allocated objects shared by multiple owners.</p>
<p>Conceptually, smart pointers are seen as owning the object pointed to, and thus <p>Conceptually, smart pointers are seen as owning the object pointed to, and thus
responsible for deletion of the object when it is no longer needed.</p> responsible for deletion of the object when it is no longer needed.</p>
<p>The smart pointer library provides six smart pointer class templates:</p> <p>The smart pointer library provides six smart pointer class templates:</p>
<div align="left"> <div align="left">
<table border="1" cellpadding="4" cellspacing="0"> <table border="1" cellpadding="4" cellspacing="0">
<tr> <tr>
<td><a href="scoped_ptr.htm"><b>scoped_ptr</b></a></td> <td><a href="scoped_ptr.htm"><b>scoped_ptr</b></a></td>
<td><a href="../../boost/scoped_ptr.hpp">&lt;boost/scoped_ptr.hpp&gt;</a></td> <td><a href="../../boost/scoped_ptr.hpp">&lt;boost/scoped_ptr.hpp&gt;</a></td>
<td>Simple sole ownership of single objects. Noncopyable.</td> <td>Simple sole ownership of single objects. Noncopyable.</td>
</tr> </tr>
<tr> <tr>
<td><a href="scoped_array.htm"><b>scoped_array</b></a></td> <td><a href="scoped_array.htm"><b>scoped_array</b></a></td>
<td><a href="../../boost/scoped_array.hpp">&lt;boost/scoped_array.hpp&gt;</a></td> <td><a href="../../boost/scoped_array.hpp">&lt;boost/scoped_array.hpp&gt;</a></td>
<td>Simple sole ownership of arrays. Noncopyable.</td> <td>Simple sole ownership of arrays. Noncopyable.</td>
</tr> </tr>
<tr> <tr>
<td><a href="shared_ptr.htm"><b>shared_ptr</b></a></td> <td><a href="shared_ptr.htm"><b>shared_ptr</b></a></td>
<td><a href="../../boost/shared_ptr.hpp">&lt;boost/shared_ptr.hpp&gt;</a></td> <td><a href="../../boost/shared_ptr.hpp">&lt;boost/shared_ptr.hpp&gt;</a></td>
<td>Object ownership shared among multiple pointers.</td> <td>Object ownership shared among multiple pointers.</td>
</tr> </tr>
<tr> <tr>
<td><a href="shared_array.htm"><b>shared_array</b></a></td> <td><a href="shared_array.htm"><b>shared_array</b></a></td>
<td><a href="../../boost/shared_array.hpp">&lt;boost/shared_array.hpp&gt;</a></td> <td><a href="../../boost/shared_array.hpp">&lt;boost/shared_array.hpp&gt;</a></td>
<td>Array ownership shared among multiple pointers.</td> <td>Array ownership shared among multiple pointers.</td>
</tr> </tr>
<tr> <tr>
<td><a href="weak_ptr.htm"><b>weak_ptr</b></a></td> <td><a href="weak_ptr.htm"><b>weak_ptr</b></a></td>
<td><a href="../../boost/weak_ptr.hpp">&lt;boost/weak_ptr.hpp&gt;</a></td> <td><a href="../../boost/weak_ptr.hpp">&lt;boost/weak_ptr.hpp&gt;</a></td>
<td>Non-owning observers of an object owned by <b>shared_ptr</b>.</td> <td>Non-owning observers of an object owned by <b>shared_ptr</b>.</td>
</tr> </tr>
<tr> <tr>
<td><a href="intrusive_ptr.html"><b>intrusive_ptr</b></a></td> <td><a href="intrusive_ptr.html"><b>intrusive_ptr</b></a></td>
<td><a href="../../boost/intrusive_ptr.hpp">&lt;boost/intrusive_ptr.hpp&gt;</a></td> <td><a href="../../boost/intrusive_ptr.hpp">&lt;boost/intrusive_ptr.hpp&gt;</a></td>
<td>Shared ownership of objects with an embedded reference count.</td> <td>Shared ownership of objects with an embedded reference count.</td>
</tr> </tr>
</table> </table>
</div> </div>
<p>These templates are designed to complement the <b>std::auto_ptr</b> template.</p> <p>These templates are designed to complement the <b>std::auto_ptr</b> template.</p>
<p>They are examples of the "resource acquisition is initialization" idiom <p>They are examples of the "resource acquisition is initialization" idiom
described in Bjarne Stroustrup's "The C++ Programming Language", 3rd edition, described in Bjarne Stroustrup's "The C++ Programming Language", 3rd edition,
Section 14.4, Resource Management.</p> Section 14.4, Resource Management.</p>
<p>Additionally, the smart pointer library provides efficient factory functions <p>Additionally, the smart pointer library provides efficient factory functions
for creating <code>shared_ptr</code> objects:</p> for creating smart pointer objects:</p>
<div align="left"> <div align="left">
<table border="1" cellpadding="4" cellspacing="0"> <table border="1" cellpadding="4" cellspacing="0">
<tr> <tr>
<td><a href="make_shared.html"><b>make_shared and allocate_shared</b></a></td> <td><a href="make_shared.html"><b>make_shared, allocate_shared</b></a> for objects</td>
<td><a href="../../boost/make_shared.hpp">&lt;boost/make_shared.hpp&gt;</a></td> <td><a href="../../boost/make_shared.hpp">&lt;boost/make_shared.hpp&gt;</a></td>
<td>Efficient creation of <code>shared_ptr</code> objects.</td> <td>Efficient creation of <code>shared_ptr</code> objects.</td>
</tr> </tr>
</table> <tr>
</div> <td><a href="make_shared_array.html"><b>make_shared, allocate_shared</b></a> for arrays</td>
<p>A test program, <a href="test/smart_ptr_test.cpp">smart_ptr_test.cpp</a>, is <td><a href="../../boost/make_shared.hpp">&lt;boost/make_shared.hpp&gt;</a></td>
provided to verify correct operation.</p> <td>Efficient creation of <code>shared_ptr</code> arrays.</td>
<p>A page on <a href="compatibility.htm">compatibility</a> with older versions of </tr>
the Boost smart pointer library describes some of the changes since earlier <tr>
versions of the smart pointer implementation.</p> <td><a href="make_unique.html"><b>make_unique</b></a></td>
<p>A page on <a href="smarttests.htm">smart pointer timings</a> will be of interest <td><a href="../../boost/make_unique.hpp">&lt;boost/make_unique.hpp&gt;</a></td>
to those curious about performance issues.</p> <td>Creation of <code>unique_ptr</code> objects and arrays.</td>
<P>A page on <A href="sp_techniques.html">smart pointer programming techniques</A> lists </tr>
some advanced applications of <code>shared_ptr</code> and <code>weak_ptr</code>.</P> </table>
<h2><a name="common_requirements">Common Requirements</a></h2> </div>
<p>These smart pointer class templates have a template parameter, <b>T</b>, which <p>A test program, <a href="test/smart_ptr_test.cpp">smart_ptr_test.cpp</a>, is
specifies the type of the object pointed to by the smart pointer. The behavior provided to verify correct operation.</p>
of the smart pointer templates is undefined if the destructor or <b>operator delete</b> <p>A page on <a href="compatibility.htm">compatibility</a> with older versions of
for objects of type <b>T</b> throw exceptions.</p> the Boost smart pointer library describes some of the changes since earlier
<p><b>T</b> may be an incomplete type at the point of smart pointer declaration. versions of the smart pointer implementation.</p>
Unless otherwise specified, it is required that <b>T</b> be a complete type at <p>A page on <a href="smarttests.htm">smart pointer timings</a> will be of interest
points of smart pointer instantiation. Implementations are required to diagnose to those curious about performance issues.</p>
(treat as an error) all violations of this requirement, including deletion of <P>A page on <A href="sp_techniques.html">smart pointer programming techniques</A> lists
an incomplete type. See the description of the <a href="../utility/utility.htm#checked_delete"> some advanced applications of <code>shared_ptr</code> and <code>weak_ptr</code>.</P>
<b>checked_delete</b></a> function template.</p> <h2><a name="common_requirements">Common Requirements</a></h2>
<P>Note that <STRONG>shared_ptr</STRONG> does not have this restriction, as most of <p>These smart pointer class templates have a template parameter, <b>T</b>, which
its member functions do not require <STRONG>T</STRONG> to be a complete type.</P> specifies the type of the object pointed to by the smart pointer. The behavior
<h3>Rationale</h3> of the smart pointer templates is undefined if the destructor or <b>operator delete</b>
<p>The requirements on <b>T</b> are carefully crafted to maximize safety yet allow for objects of type <b>T</b> throw exceptions.</p>
handle-body (also called pimpl) and similar idioms. In these idioms a smart <p><b>T</b> may be an incomplete type at the point of smart pointer declaration.
pointer may appear in translation units where <b>T</b> is an incomplete type. Unless otherwise specified, it is required that <b>T</b> be a complete type at
This separates interface from implementation and hides implementation from points of smart pointer instantiation. Implementations are required to diagnose
translation units which merely use the interface. Examples described in the (treat as an error) all violations of this requirement, including deletion of
documentation for specific smart pointers illustrate use of smart pointers in an incomplete type. See the description of the <a href="../utility/utility.htm#checked_delete">
these idioms.</p> <b>checked_delete</b></a> function template.</p>
<p>Note that <b>scoped_ptr</b> requires that <b>T</b> be a complete type at <P>Note that <STRONG>shared_ptr</STRONG> does not have this restriction, as most of
destruction time, but <b>shared_ptr</b> does not.</p> its member functions do not require <STRONG>T</STRONG> to be a complete type.</P>
<h2><a name="Exception_Safety">Exception Safety</a></h2> <h3>Rationale</h3>
<p>Several functions in these smart pointer classes are specified as having "no <p>The requirements on <b>T</b> are carefully crafted to maximize safety yet allow
effect" or "no effect except such-and-such" if an exception is thrown. This handle-body (also called pimpl) and similar idioms. In these idioms a smart
means that when an exception is thrown by an object of one of these classes, pointer may appear in translation units where <b>T</b> is an incomplete type.
the entire program state remains the same as it was prior to the function call This separates interface from implementation and hides implementation from
which resulted in the exception being thrown. This amounts to a guarantee that translation units which merely use the interface. Examples described in the
there are no detectable side effects. Other functions never throw exceptions. documentation for specific smart pointers illustrate use of smart pointers in
The only exception ever thrown by functions which do throw (assuming <b>T</b> meets these idioms.</p>
the <a href="#common_requirements">common requirements</a>) is <b>std::bad_alloc</b>, <p>Note that <b>scoped_ptr</b> requires that <b>T</b> be a complete type at
and that is thrown only by functions which are explicitly documented as destruction time, but <b>shared_ptr</b> does not.</p>
possibly throwing <b>std::bad_alloc</b>.</p> <h2><a name="Exception_Safety">Exception Safety</a></h2>
<h2><a name="Exception-specifications">Exception-specifications</a></h2> <p>Several functions in these smart pointer classes are specified as having "no
<p>Exception-specifications are not used; see <a href="http://www.boost.org/more/lib_guide.htm#Exception-specification"> effect" or "no effect except such-and-such" if an exception is thrown. This
exception-specification rationale</a>.</p> means that when an exception is thrown by an object of one of these classes,
<p>All the smart pointer templates contain member functions which can never throw the entire program state remains the same as it was prior to the function call
exceptions, because they neither throw exceptions themselves nor call other which resulted in the exception being thrown. This amounts to a guarantee that
functions which may throw exceptions. These members are indicated by a comment: <code> there are no detectable side effects. Other functions never throw exceptions.
// never throws</code>. The only exception ever thrown by functions which do throw (assuming <b>T</b> meets
</p> the <a href="#common_requirements">common requirements</a>) is <b>std::bad_alloc</b>,
<p>Functions which destroy objects of the pointed to type are prohibited from and that is thrown only by functions which are explicitly documented as
throwing exceptions by the <a href="#common_requirements">common requirements</a>.</p> possibly throwing <b>std::bad_alloc</b>.</p>
<h2><a name="History">History</a> and Acknowledgements</h2> <h2><a name="Exception-specifications">Exception-specifications</a></h2>
<p>January 2002. Peter Dimov reworked all four classes, adding features, fixing <p>Exception-specifications are not used; see <a href="http://www.boost.org/more/lib_guide.htm#Exception-specification">
bugs, and splitting them into four separate headers, and added <b>weak_ptr</b>. exception-specification rationale</a>.</p>
See the <a href="compatibility.htm">compatibility</a> page for a summary of the <p>All the smart pointer templates contain member functions which can never throw
changes.</p> exceptions, because they neither throw exceptions themselves nor call other
<p>May 2001. Vladimir Prus suggested requiring a complete type on destruction. functions which may throw exceptions. These members are indicated by a comment: <code>
Refinement evolved in discussions including Dave Abrahams, Greg Colvin, Beman // never throws</code>.
Dawes, Rainer Deyke, Peter Dimov, John Maddock, Vladimir Prus, Shankar Sai, and </p>
others.</p> <p>Functions which destroy objects of the pointed to type are prohibited from
<p>November 1999. Darin Adler provided <b>operator ==</b>, <b>operator !=</b>, and <b>std::swap</b> throwing exceptions by the <a href="#common_requirements">common requirements</a>.</p>
and <b>std::less</b> specializations for shared types.</p> <h2><a name="History">History</a> and Acknowledgements</h2>
<p>September 1999. Luis Coelho provided <b>shared_ptr::swap</b> and <b>shared_array::swap</b></p> <p>February 2014. Glen Fernandes updated overloads of <b>make_shared</b> and
<p>May 1999. In April and May, 1999, Valentin Bonnard and David Abrahams made a <b>allocate_shared</b> to conform to the specification in C++ standard paper
number of suggestions resulting in numerous improvements.</p> <a href="#D&amp;F-14">[D&amp;F-14]</a>, and implemented <b>make_unique</b> for
<p>October 1998. Beman Dawes proposed reviving the original semantics under the arrays and objects. Peter Dimov and Glen Fernandes updated the scalar and
names <b>safe_ptr</b> and <b>counted_ptr</b>, meeting of Per Andersson, Matt array implementations, respectively, to resolve C++ standard library defect
Austern, Greg Colvin, Sean Corfield, Pete Becker, Nico Josuttis, Dietmar K&uuml;hl, 2070.</p>
Nathan Myers, Chichiang Wan and Judy Ward. During the discussion, the four new <p>November 2012. Glen Fernandes provided implementations of <b>make_shared</b>
class names were finalized, it was decided that there was no need to exactly and <b>allocate_shared</b> for arrays. They achieve a single allocation for an
follow the <b>std::auto_ptr</b> interface, and various function signatures and array that can be initialized with constructor arguments or initializer lists
semantics were finalized.</p> as well as overloads for default initialization and no value initialization.
<p>Over the next three months, several implementations were considered for <b>shared_ptr</b>, See the <a href="make_shared_array.html">make_shared and allocate_shared for
and discussed on the <a href="http://www.boost.org">boost.org</a> mailing list. arrays</a> page for more information.</p>
The implementation questions revolved around the reference count which must be <p>January 2002. Peter Dimov reworked all four classes, adding features, fixing
kept, either attached to the pointed to object, or detached elsewhere. Each of bugs, and splitting them into four separate headers, and added <b>weak_ptr</b>.
those variants have themselves two major variants: See the <a href="compatibility.htm">compatibility</a> page for a summary of the
<ul> changes.</p>
<li> <p>May 2001. Vladimir Prus suggested requiring a complete type on destruction.
Direct detached: the shared_ptr contains a pointer to the object, and a pointer Refinement evolved in discussions including Dave Abrahams, Greg Colvin, Beman
to the count. Dawes, Rainer Deyke, Peter Dimov, John Maddock, Vladimir Prus, Shankar Sai, and
<li> others.</p>
Indirect detached: the shared_ptr contains a pointer to a helper object, which <p>November 1999. Darin Adler provided <b>operator ==</b>, <b>operator !=</b>, and <b>std::swap</b>
in turn contains a pointer to the object and the count. and <b>std::less</b> specializations for shared types.</p>
<li> <p>September 1999. Luis Coelho provided <b>shared_ptr::swap</b> and <b>shared_array::swap</b></p>
Embedded attached: the count is a member of the object pointed to. <p>May 1999. In April and May, 1999, Valentin Bonnard and David Abrahams made a
<li> number of suggestions resulting in numerous improvements.</p>
Placement attached: the count is attached via operator new manipulations.</li> <p>October 1998. Beman Dawes proposed reviving the original semantics under the
</ul> names <b>safe_ptr</b> and <b>counted_ptr</b>, meeting of Per Andersson, Matt
<p>Each implementation technique has advantages and disadvantages. We went so far Austern, Greg Colvin, Sean Corfield, Pete Becker, Nico Josuttis, Dietmar K&uuml;hl,
as to run various timings of the direct and indirect approaches, and found that Nathan Myers, Chichiang Wan and Judy Ward. During the discussion, the four new
at least on Intel Pentium chips there was very little measurable difference. class names were finalized, it was decided that there was no need to exactly
Kevlin Henney provided a paper he wrote on "Counted Body Techniques." Dietmar follow the <b>std::auto_ptr</b> interface, and various function signatures and
K&uuml;hl suggested an elegant partial template specialization technique to allow semantics were finalized.</p>
users to choose which implementation they preferred, and that was also <p>Over the next three months, several implementations were considered for <b>shared_ptr</b>,
experimented with.</p> and discussed on the <a href="http://www.boost.org">boost.org</a> mailing list.
<p>But Greg Colvin and Jerry Schwarz argued that "parameterization will discourage The implementation questions revolved around the reference count which must be
users", and in the end we choose to supply only the direct implementation.</p> kept, either attached to the pointed to object, or detached elsewhere. Each of
<p>Summer, 1994. Greg Colvin proposed to the C++ Standards Committee classes named <b>auto_ptr</b> those variants have themselves two major variants:
and <b>counted_ptr</b> which were very similar to what we now call <b>scoped_ptr</b> <ul>
and <b>shared_ptr</b>. <a href="#Col-94">[Col-94]</a> In one of the very few <li>
cases where the Library Working Group's recommendations were not followed by Direct detached: the shared_ptr contains a pointer to the object, and a pointer
the full committee, <b>counted_ptr</b> was rejected and surprising to the count.
transfer-of-ownership semantics were added to <b>auto_ptr</b>.</p> <li>
<h2><a name="References">References</a></h2> Indirect detached: the shared_ptr contains a pointer to a helper object, which
<p>[<a name="Col-94">Col-94</a>] Gregory Colvin, <a href="http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/1994/N0555.pdf"> in turn contains a pointer to the object and the count.
Exception Safe Smart Pointers</a>, C++ committee document 94-168/N0555, <li>
July, 1994.</p> Embedded attached: the count is a member of the object pointed to.
<p>[<a name="E&amp;D-94">E&amp;D-94</a>] John R. Ellis &amp; David L. Detlefs, <a href="http://www.usenix.org/publications/library/proceedings/c++94/full_papers/ellis.a"> <li>
Safe, Efficient Garbage Collection for C++</a>, Usenix Proceedings, Placement attached: the count is attached via operator new manipulations.</li>
February, 1994. This paper includes an extensive discussion of weak pointers </ul>
and an extensive bibliography.</p> <p>Each implementation technique has advantages and disadvantages. We went so far
<hr> as to run various timings of the direct and indirect approaches, and found that
<p>$Date$</p> at least on Intel Pentium chips there was very little measurable difference.
<p><small>Copyright 1999 Greg Colvin and Beman Dawes. Copyright 2002 Darin Adler. Kevlin Henney provided a paper he wrote on "Counted Body Techniques." Dietmar
Distributed under the Boost Software License, Version 1.0. See accompanying K&uuml;hl suggested an elegant partial template specialization technique to allow
file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or copy at users to choose which implementation they preferred, and that was also
<A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p> experimented with.</p>
</body> <p>But Greg Colvin and Jerry Schwarz argued that "parameterization will discourage
users", and in the end we choose to supply only the direct implementation.</p>
<p>Summer, 1994. Greg Colvin proposed to the C++ Standards Committee classes named <b>auto_ptr</b>
and <b>counted_ptr</b> which were very similar to what we now call <b>scoped_ptr</b>
and <b>shared_ptr</b>. <a href="#Col-94">[Col-94]</a> In one of the very few
cases where the Library Working Group's recommendations were not followed by
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="D&amp;F-14">D&amp;F-14</a>] Peter Dimov &amp; Glen Fernandes, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3870.html">
Extending make_shared to Support Arrays, Revision 1</a>, C++ committee document N3870,
January, 2014.</p>
<p>[<a name="Col-94">Col-94</a>] Gregory Colvin, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1994/N0555.pdf">
Exception Safe Smart Pointers</a>, C++ committee document 94-168/N0555,
July, 1994.</p>
<p>[<a name="E&amp;D-94">E&amp;D-94</a>] John R. Ellis &amp; David L. Detlefs, <a href="http://www.usenix.org/publications/library/proceedings/c++94/full_papers/ellis.a">
Safe, Efficient Garbage Collection for C++</a>, Usenix Proceedings,
February, 1994. This paper includes an extensive discussion of weak pointers
and an extensive bibliography.</p>
<hr>
<p>$Date$</p>
<p><small>Copyright 1999 Greg Colvin and Beman Dawes. 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>
</body>
</html> </html>

View File

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

View File

@@ -1,67 +1,67 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html> <html>
<head> <head>
<title>Smart Pointer Programming Techniques</title> <title>Smart Pointer Programming Techniques</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head> </head>
<body text="#000000" bgColor="#ffffff"> <body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#0000ff">
<h1><A href="../../index.htm"><IMG height="86" alt="boost.png (6897 bytes)" src="../../boost.png" width="277" align="middle" <h1><img height="86" alt="boost.png (6897 bytes)" src="../../boost.png"
border="0"></A>Smart Pointer Programming Techniques</h1> width="277" align="middle" border="0">Smart Pointer Programming Techniques</h1>
<p><A href="#incomplete">Using incomplete classes for implementation hiding</A><br> <p><A href="#incomplete">Using incomplete classes for implementation hiding</A><br>
<A href="#pimpl">The "Pimpl" idiom</A><br> <A href="#pimpl">The "Pimpl" idiom</A><br>
<A href="#abstract">Using abstract classes for implementation hiding</A><br> <A href="#abstract">Using abstract classes for implementation hiding</A><br>
<A href="#preventing_delete">Preventing <code>delete px.get()</code></A><br> <A href="#preventing_delete">Preventing <code>delete px.get()</code></A><br>
<A href="#array">Using a <code>shared_ptr</code> to hold a pointer to an array</A><br> <A href="#array">Using a <code>shared_ptr</code> to hold a pointer to an array</A><br>
<A href="#encapsulation">Encapsulating allocation details, wrapping factory <A href="#encapsulation">Encapsulating allocation details, wrapping factory
functions</A><br> functions</A><br>
<A href="#static">Using a <code>shared_ptr</code> to hold a pointer to a statically <A href="#static">Using a <code>shared_ptr</code> to hold a pointer to a statically
allocated object</A><br> allocated object</A><br>
<A href="#com">Using a <code>shared_ptr</code> to hold a pointer to a COM object</A><br> <A href="#com">Using a <code>shared_ptr</code> to hold a pointer to a COM object</A><br>
<A href="#intrusive">Using a <code>shared_ptr</code> to hold a pointer to an object <A href="#intrusive">Using a <code>shared_ptr</code> to hold a pointer to an object
with an embedded reference count</A><br> with an embedded reference count</A><br>
<A href="#another_sp">Using a <code>shared_ptr</code> to hold another shared <A href="#another_sp">Using a <code>shared_ptr</code> to hold another shared
ownership smart pointer</A><br> ownership smart pointer</A><br>
<A href="#from_raw">Obtaining a <code>shared_ptr</code> from a raw pointer</A><br> <A href="#from_raw">Obtaining a <code>shared_ptr</code> from a raw pointer</A><br>
<A href="#in_constructor">Obtaining a <code>shared_ptr</code> (<code>weak_ptr</code>) <A href="#in_constructor">Obtaining a <code>shared_ptr</code> (<code>weak_ptr</code>)
to <code>this</code> in a constructor</A><br> to <code>this</code> in a constructor</A><br>
<A href="#from_this">Obtaining a <code>shared_ptr</code> to <code>this</code></A><br> <A href="#from_this">Obtaining a <code>shared_ptr</code> to <code>this</code></A><br>
<A href="#handle">Using <code>shared_ptr</code> as a smart counted handle</A><br> <A href="#handle">Using <code>shared_ptr</code> as a smart counted handle</A><br>
<A href="#on_block_exit">Using <code>shared_ptr</code> to execute code on block <A href="#on_block_exit">Using <code>shared_ptr</code> to execute code on block
exit</A><br> exit</A><br>
<A href="#pvoid">Using <code>shared_ptr&lt;void&gt;</code> to hold an arbitrary <A href="#pvoid">Using <code>shared_ptr&lt;void&gt;</code> to hold an arbitrary
object</A><br> object</A><br>
<A href="#extra_data">Associating arbitrary data with heterogeneous <code>shared_ptr</code> <A href="#extra_data">Associating arbitrary data with heterogeneous <code>shared_ptr</code>
instances</A><br> instances</A><br>
<A href="#as_lock">Using <code>shared_ptr</code> as a CopyConstructible mutex lock</A><br> <A href="#as_lock">Using <code>shared_ptr</code> as a CopyConstructible mutex lock</A><br>
<A href="#wrapper">Using <code>shared_ptr</code> to wrap member function calls</A><br> <A href="#wrapper">Using <code>shared_ptr</code> to wrap member function calls</A><br>
<A href="#delayed">Delayed deallocation</A><br> <A href="#delayed">Delayed deallocation</A><br>
<A href="#weak_without_shared">Weak pointers to objects not managed by a <code>shared_ptr</code></A><br> <A href="#weak_without_shared">Weak pointers to objects not managed by a <code>shared_ptr</code></A><br>
</p> </p>
<h2><A name="incomplete">Using incomplete classes for implementation hiding</A></h2> <h2><A name="incomplete">Using incomplete classes for implementation hiding</A></h2>
<p>A proven technique (that works in C, too) for separating interface from <p>A proven technique (that works in C, too) for separating interface from
implementation is to use a pointer to an incomplete class as an opaque handle:</p> implementation is to use a pointer to an incomplete class as an opaque handle:</p>
<pre>class FILE; <pre>class FILE;
FILE * fopen(char const * name, char const * mode); FILE * fopen(char const * name, char const * mode);
void fread(FILE * f, void * data, size_t size); void fread(FILE * f, void * data, size_t size);
void fclose(FILE * f); void fclose(FILE * f);
</pre> </pre>
<p>It is possible to express the above interface using <code>shared_ptr</code>, <p>It is possible to express the above interface using <code>shared_ptr</code>,
eliminating the need to manually call <code>fclose</code>:</p> eliminating the need to manually call <code>fclose</code>:</p>
<pre>class FILE; <pre>class FILE;
shared_ptr&lt;FILE&gt; fopen(char const * name, char const * mode); shared_ptr&lt;FILE&gt; fopen(char const * name, char const * mode);
void fread(shared_ptr&lt;FILE&gt; f, void * data, size_t size); void fread(shared_ptr&lt;FILE&gt; f, void * data, size_t size);
</pre> </pre>
<p>This technique relies on <code>shared_ptr</code>'s ability to execute a custom <p>This technique relies on <code>shared_ptr</code>'s ability to execute a custom
deleter, eliminating the explicit call to <code>fclose</code>, and on the fact deleter, eliminating the explicit call to <code>fclose</code>, and on the fact
that <code>shared_ptr&lt;X&gt;</code> can be copied and destroyed when <code>X</code> that <code>shared_ptr&lt;X&gt;</code> can be copied and destroyed when <code>X</code>
is incomplete.</p> is incomplete.</p>
<h2><A name="pimpl">The "Pimpl" idiom</A></h2> <h2><A name="pimpl">The "Pimpl" idiom</A></h2>
<p>A C++ specific variation of the incomplete class pattern is the "Pimpl" idiom. <p>A C++ specific variation of the incomplete class pattern is the "Pimpl" idiom.
The incomplete class is not exposed to the user; it is hidden behind a The incomplete class is not exposed to the user; it is hidden behind a
forwarding facade. <code>shared_ptr</code> can be used to implement a "Pimpl":</p> forwarding facade. <code>shared_ptr</code> can be used to implement a "Pimpl":</p>
<pre>// file.hpp: <pre>// file.hpp:
class file class file
{ {
@@ -79,7 +79,7 @@ public:
void read(void * data, size_t size); void read(void * data, size_t size);
}; };
</pre> </pre>
<pre>// file.cpp: <pre>// file.cpp:
#include "file.hpp" #include "file.hpp"
@@ -108,17 +108,17 @@ void file::read(void * data, size_t size)
pimpl_-&gt;read(data, size); pimpl_-&gt;read(data, size);
} }
</pre> </pre>
<p>The key thing to note here is that the compiler-generated copy constructor, <p>The key thing to note here is that the compiler-generated copy constructor,
assignment operator, and destructor all have a sensible meaning. As a result, <code> assignment operator, and destructor all have a sensible meaning. As a result, <code>
file</code> is <code>CopyConstructible</code> and <code>Assignable</code>, file</code> is <code>CopyConstructible</code> and <code>Assignable</code>,
allowing its use in standard containers.</p> allowing its use in standard containers.</p>
<h2><A name="abstract">Using abstract classes for implementation hiding</A></h2> <h2><A name="abstract">Using abstract classes for implementation hiding</A></h2>
<p>Another widely used C++ idiom for separating inteface and implementation is to <p>Another widely used C++ idiom for separating inteface and implementation is to
use abstract base classes and factory functions. The abstract classes are use abstract base classes and factory functions. The abstract classes are
sometimes called "interfaces" and the pattern is known as "interface-based sometimes called "interfaces" and the pattern is known as "interface-based
programming". Again, <code>shared_ptr</code> can be used as the return type of programming". Again, <code>shared_ptr</code> can be used as the return type of
the factory functions:</p> the factory functions:</p>
<pre>// X.hpp: <pre>// X.hpp:
class X class X
{ {
@@ -134,7 +134,7 @@ protected:
shared_ptr&lt;X&gt; createX(); shared_ptr&lt;X&gt; createX();
</pre> </pre>
<pre>-- X.cpp: <pre>-- X.cpp:
class X_impl: public X class X_impl: public X
{ {
@@ -162,18 +162,18 @@ shared_ptr&lt;X&gt; createX()
return px; return px;
} }
</pre> </pre>
<p>A key property of shared_ptr is that the allocation, construction, deallocation, <p>A key property of shared_ptr is that the allocation, construction, deallocation,
and destruction details are captured at the point of construction, inside the and destruction details are captured at the point of construction, inside the
factory function. Note the protected and nonvirtual destructor in the example factory function. Note the protected and nonvirtual destructor in the example
above. The client code cannot, and does not need to, delete a pointer to <code>X</code>; above. The client code cannot, and does not need to, delete a pointer to <code>X</code>;
the <code>shared_ptr&lt;X&gt;</code> instance returned from <code>createX</code> the <code>shared_ptr&lt;X&gt;</code> instance returned from <code>createX</code>
will correctly call <code>~X_impl</code>.</p> will correctly call <code>~X_impl</code>.</p>
<h2><A name="preventing_delete">Preventing <code>delete px.get()</code></A></h2> <h2><A name="preventing_delete">Preventing <code>delete px.get()</code></A></h2>
<p>It is often desirable to prevent client code from deleting a pointer that is <p>It is often desirable to prevent client code from deleting a pointer that is
being managed by <code>shared_ptr</code>. The previous technique showed one being managed by <code>shared_ptr</code>. The previous technique showed one
possible approach, using a protected destructor. Another alternative is to use possible approach, using a protected destructor. Another alternative is to use
a private deleter:</p> a private deleter:</p>
<pre>class X <pre>class X
{ {
private: private:
@@ -198,48 +198,48 @@ public:
} }
}; };
</pre> </pre>
<h2><A name="array">Using a <code>shared_ptr</code> to hold a pointer to an array</A></h2> <h2><A name="array">Using a <code>shared_ptr</code> to hold a pointer to an array</A></h2>
<p>A <code>shared_ptr</code> can be used to hold a pointer to an array allocated <p>A <code>shared_ptr</code> can be used to hold a pointer to an array allocated
with <code>new[]</code>:</p> with <code>new[]</code>:</p>
<pre>shared_ptr&lt;X&gt; px(new X[1], <A href="../utility/checked_delete.html" >checked_array_deleter</A>&lt;X&gt;()); <pre>shared_ptr&lt;X&gt; px(new X[1], <A href="../utility/checked_delete.html" >checked_array_deleter</A>&lt;X&gt;());
</pre> </pre>
<p>Note, however, that <code><A href="shared_array.htm">shared_array</A></code> is <p>Note, however, that <code><A href="shared_array.htm">shared_array</A></code> is
often preferable, if this is an option. It has an array-specific interface, often preferable, if this is an option. It has an array-specific interface,
without <code>operator*</code> and <code>operator-&gt;</code>, and does not without <code>operator*</code> and <code>operator-&gt;</code>, and does not
allow pointer conversions.</p> allow pointer conversions.</p>
<h2><A name="encapsulation">Encapsulating allocation details, wrapping factory <h2><A name="encapsulation">Encapsulating allocation details, wrapping factory
functions</A></h2> functions</A></h2>
<p><code>shared_ptr</code> can be used in creating C++ wrappers over existing C <p><code>shared_ptr</code> can be used in creating C++ wrappers over existing C
style library interfaces that return raw pointers from their factory functions style library interfaces that return raw pointers from their factory functions
to encapsulate allocation details. As an example, consider this interface, to encapsulate allocation details. As an example, consider this interface,
where <code>CreateX</code> might allocate <code>X</code> from its own private where <code>CreateX</code> might allocate <code>X</code> from its own private
heap, <code>~X</code> may be inaccessible, or <code>X</code> may be incomplete:</p> heap, <code>~X</code> may be inaccessible, or <code>X</code> may be incomplete:</p>
<pre>X * CreateX(); <pre>X * CreateX();
void DestroyX(X *); void DestroyX(X *);
</pre> </pre>
<p>The only way to reliably destroy a pointer returned by <code>CreateX</code> is <p>The only way to reliably destroy a pointer returned by <code>CreateX</code> is
to call <code>DestroyX</code>.</p> to call <code>DestroyX</code>.</p>
<P>Here is how a <code>shared_ptr</code>-based wrapper may look like:</P> <P>Here is how a <code>shared_ptr</code>-based wrapper may look like:</P>
<pre>shared_ptr&lt;X&gt; createX() <pre>shared_ptr&lt;X&gt; createX()
{ {
shared_ptr&lt;X&gt; px(CreateX(), DestroyX); shared_ptr&lt;X&gt; px(CreateX(), DestroyX);
return px; return px;
} }
</pre> </pre>
<p>Client code that calls <code>createX</code> still does not need to know how the <p>Client code that calls <code>createX</code> still does not need to know how the
object has been allocated, but now the destruction is automatic.</p> object has been allocated, but now the destruction is automatic.</p>
<h2><A name="static">Using a <code>shared_ptr</code> to hold a pointer to a statically <h2><A name="static">Using a <code>shared_ptr</code> to hold a pointer to a statically
allocated object</A></h2> allocated object</A></h2>
<p>Sometimes it is desirable to create a <code>shared_ptr</code> to an already <p>Sometimes it is desirable to create a <code>shared_ptr</code> to an already
existing object, so that the <code>shared_ptr</code> does not attempt to existing object, so that the <code>shared_ptr</code> does not attempt to
destroy the object when there are no more references left. As an example, the destroy the object when there are no more references left. As an example, the
factory function:</p> factory function:</p>
<pre>shared_ptr&lt;X&gt; createX(); <pre>shared_ptr&lt;X&gt; createX();
</pre> </pre>
<p>in certain situations may need to return a pointer to a statically allocated <code>X</code> <p>in certain situations may need to return a pointer to a statically allocated <code>X</code>
instance.</p> instance.</p>
<P>The solution is to use a custom deleter that does nothing:</P> <P>The solution is to use a custom deleter that does nothing:</P>
<pre>struct null_deleter <pre>struct null_deleter
{ {
void operator()(void const *) const void operator()(void const *) const
{ {
@@ -254,33 +254,33 @@ shared_ptr&lt;X&gt; createX()
return px; return px;
} }
</pre> </pre>
<p>The same technique works for any object known to outlive the pointer.</p> <p>The same technique works for any object known to outlive the pointer.</p>
<h2><A name="com">Using a <code>shared_ptr</code> to hold a pointer to a COM Object</A></h2> <h2><A name="com">Using a <code>shared_ptr</code> to hold a pointer to a COM Object</A></h2>
<p>Background: COM objects have an embedded reference count and two member <p>Background: COM objects have an embedded reference count and two member
functions that manipulate it. <code>AddRef()</code> increments the count. <code>Release()</code> functions that manipulate it. <code>AddRef()</code> increments the count. <code>Release()</code>
decrements the count and destroys itself when the count drops to zero.</p> decrements the count and destroys itself when the count drops to zero.</p>
<P>It is possible to hold a pointer to a COM object in a <code>shared_ptr</code>:</P> <P>It is possible to hold a pointer to a COM object in a <code>shared_ptr</code>:</P>
<pre>shared_ptr&lt;IWhatever&gt; make_shared_from_COM(IWhatever * p) <pre>shared_ptr&lt;IWhatever&gt; make_shared_from_COM(IWhatever * p)
{ {
p-&gt;AddRef(); p-&gt;AddRef();
shared_ptr&lt;IWhatever&gt; pw(p, <A href="../bind/mem_fn.html" >mem_fn</A>(&amp;IWhatever::Release)); shared_ptr&lt;IWhatever&gt; pw(p, <A href="../bind/mem_fn.html" >mem_fn</A>(&amp;IWhatever::Release));
return pw; return pw;
} }
</pre> </pre>
<p>Note, however, that <code>shared_ptr</code> copies created from <code>pw</code> will <p>Note, however, that <code>shared_ptr</code> copies created from <code>pw</code> will
not "register" in the embedded count of the COM object; they will share the not "register" in the embedded count of the COM object; they will share the
single reference created in <code>make_shared_from_COM</code>. Weak pointers single reference created in <code>make_shared_from_COM</code>. Weak pointers
created from <code>pw</code> will be invalidated when the last <code>shared_ptr</code> created from <code>pw</code> will be invalidated when the last <code>shared_ptr</code>
is destroyed, regardless of whether the COM object itself is still alive.</p> is destroyed, regardless of whether the COM object itself is still alive.</p>
<P>As <A href="../bind/mem_fn.html#Q3">explained</A> in the <code>mem_fn</code> documentation, <P>As <A href="../bind/mem_fn.html#Q3">explained</A> in the <code>mem_fn</code> documentation,
you need to <A href="../bind/mem_fn.html#stdcall">#define you need to <A href="../bind/mem_fn.html#stdcall">#define
BOOST_MEM_FN_ENABLE_STDCALL</A> first.</P> BOOST_MEM_FN_ENABLE_STDCALL</A> first.</P>
<h2><A name="intrusive">Using a <code>shared_ptr</code> to hold a pointer to an object <h2><A name="intrusive">Using a <code>shared_ptr</code> to hold a pointer to an object
with an embedded reference count</A></h2> with an embedded reference count</A></h2>
<p>This is a generalization of the above technique. The example assumes that the <p>This is a generalization of the above technique. The example assumes that the
object implements the two functions required by <code><A href="intrusive_ptr.html">intrusive_ptr</A></code>, object implements the two functions required by <code><A href="intrusive_ptr.html">intrusive_ptr</A></code>,
<code>intrusive_ptr_add_ref</code> and <code>intrusive_ptr_release</code>:</p> <code>intrusive_ptr_add_ref</code> and <code>intrusive_ptr_release</code>:</p>
<pre>template&lt;class T&gt; struct intrusive_deleter <pre>template&lt;class T&gt; struct intrusive_deleter
{ {
void operator()(T * p) void operator()(T * p)
{ {
@@ -295,15 +295,15 @@ shared_ptr&lt;X&gt; make_shared_from_intrusive(X * p)
return px; return px;
} }
</pre> </pre>
<h2><A name="another_sp">Using a <code>shared_ptr</code> to hold another shared <h2><A name="another_sp">Using a <code>shared_ptr</code> to hold another shared
ownership smart pointer</A></h2> ownership smart pointer</A></h2>
<p>One of the design goals of <code>shared_ptr</code> is to be used in library <p>One of the design goals of <code>shared_ptr</code> is to be used in library
interfaces. It is possible to encounter a situation where a library takes a <code>shared_ptr</code> interfaces. It is possible to encounter a situation where a library takes a <code>shared_ptr</code>
argument, but the object at hand is being managed by a different reference argument, but the object at hand is being managed by a different reference
counted or linked smart pointer.</p> counted or linked smart pointer.</p>
<P>It is possible to exploit <code>shared_ptr</code>'s custom deleter feature to <P>It is possible to exploit <code>shared_ptr</code>'s custom deleter feature to
wrap this existing smart pointer behind a <code>shared_ptr</code> facade:</P> wrap this existing smart pointer behind a <code>shared_ptr</code> facade:</P>
<pre>template&lt;class P&gt; struct smart_pointer_deleter <pre>template&lt;class P&gt; struct smart_pointer_deleter
{ {
private: private:
@@ -332,17 +332,17 @@ shared_ptr&lt;X&gt; make_shared_from_another(another_ptr&lt;X&gt; qx)
return px; return px;
} }
</pre> </pre>
<p>One subtle point is that deleters are not allowed to throw exceptions, and the <p>One subtle point is that deleters are not allowed to throw exceptions, and the
above example as written assumes that <code>p_.reset()</code> doesn't throw. If above example as written assumes that <code>p_.reset()</code> doesn't throw. If
this is not the case, <code>p_.reset()</code> should be wrapped in a <code>try {} this is not the case, <code>p_.reset()</code> should be wrapped in a <code>try {}
catch(...) {}</code> block that ignores exceptions. In the (usually catch(...) {}</code> block that ignores exceptions. In the (usually
unlikely) event when an exception is thrown and ignored, <code>p_</code> will unlikely) event when an exception is thrown and ignored, <code>p_</code> will
be released when the lifetime of the deleter ends. This happens when all be released when the lifetime of the deleter ends. This happens when all
references, including weak pointers, are destroyed or reset.</p> references, including weak pointers, are destroyed or reset.</p>
<P>Another twist is that it is possible, given the above <code>shared_ptr</code> instance, <P>Another twist is that it is possible, given the above <code>shared_ptr</code> instance,
to recover the original smart pointer, using <code><A href="shared_ptr.htm#get_deleter"> to recover the original smart pointer, using <code><A href="shared_ptr.htm#get_deleter">
get_deleter</A></code>:</P> get_deleter</A></code>:</P>
<pre>void extract_another_from_shared(shared_ptr&lt;X&gt; px) <pre>void extract_another_from_shared(shared_ptr&lt;X&gt; px)
{ {
typedef smart_pointer_deleter&lt; another_ptr&lt;X&gt; &gt; deleter; typedef smart_pointer_deleter&lt; another_ptr&lt;X&gt; &gt; deleter;
@@ -356,37 +356,37 @@ shared_ptr&lt;X&gt; make_shared_from_another(another_ptr&lt;X&gt; qx)
} }
} }
</pre> </pre>
<h2><A name="from_raw">Obtaining a <code>shared_ptr</code> from a raw pointer</A></h2> <h2><A name="from_raw">Obtaining a <code>shared_ptr</code> from a raw pointer</A></h2>
<p>Sometimes it is necessary to obtain a <code>shared_ptr</code> given a raw <p>Sometimes it is necessary to obtain a <code>shared_ptr</code> given a raw
pointer to an object that is already managed by another <code>shared_ptr</code> pointer to an object that is already managed by another <code>shared_ptr</code>
instance. Example:</p> instance. Example:</p>
<pre>void f(X * p) <pre>void f(X * p)
{ {
shared_ptr&lt;X&gt; px(<i>???</i>); shared_ptr&lt;X&gt; px(<i>???</i>);
} }
</pre> </pre>
<p>Inside <code>f</code>, we'd like to create a <code>shared_ptr</code> to <code>*p</code>.</p> <p>Inside <code>f</code>, we'd like to create a <code>shared_ptr</code> to <code>*p</code>.</p>
<P>In the general case, this problem has no solution. One approach is to modify <code>f</code> <P>In the general case, this problem has no solution. One approach is to modify <code>f</code>
to take a <code>shared_ptr</code>, if possible:</P> to take a <code>shared_ptr</code>, if possible:</P>
<pre>void f(shared_ptr&lt;X&gt; px); <pre>void f(shared_ptr&lt;X&gt; px);
</pre> </pre>
<p>The same transformation can be used for nonvirtual member functions, to convert <p>The same transformation can be used for nonvirtual member functions, to convert
the implicit <code>this</code>:</p> the implicit <code>this</code>:</p>
<pre>void X::f(int m); <pre>void X::f(int m);
</pre> </pre>
<p>would become a free function with a <code>shared_ptr</code> first argument:</p> <p>would become a free function with a <code>shared_ptr</code> first argument:</p>
<pre>void f(shared_ptr&lt;X&gt; this_, int m); <pre>void f(shared_ptr&lt;X&gt; this_, int m);
</pre> </pre>
<p>If <code>f</code> cannot be changed, but <code>X</code> uses intrusive counting, <p>If <code>f</code> cannot be changed, but <code>X</code> uses intrusive counting,
use <code><A href="#intrusive">make_shared_from_intrusive</A></code> described use <code><A href="#intrusive">make_shared_from_intrusive</A></code> described
above. Or, if it's known that the <code>shared_ptr</code> created in <code>f</code> above. Or, if it's known that the <code>shared_ptr</code> created in <code>f</code>
will never outlive the object, use <A href="#static">a null deleter</A>.</p> will never outlive the object, use <A href="#static">a null deleter</A>.</p>
<h2><A name="in_constructor">Obtaining a <code>shared_ptr</code> (<code>weak_ptr</code>) <h2><A name="in_constructor">Obtaining a <code>shared_ptr</code> (<code>weak_ptr</code>)
to <code>this</code> in a constructor</A></h2> to <code>this</code> in a constructor</A></h2>
<p>Some designs require objects to register themselves on construction with a <p>Some designs require objects to register themselves on construction with a
central authority. When the registration routines take a shared_ptr, this leads central authority. When the registration routines take a shared_ptr, this leads
to the question how could a constructor obtain a shared_ptr to this:</p> to the question how could a constructor obtain a shared_ptr to this:</p>
<pre>class X <pre>class X
{ {
public: public:
@@ -396,19 +396,19 @@ public:
} }
}; };
</pre> </pre>
<p>In the general case, the problem cannot be solved. The <code>X</code> instance <p>In the general case, the problem cannot be solved. The <code>X</code> instance
being constructed can be an automatic variable or a static variable; it can be being constructed can be an automatic variable or a static variable; it can be
created on the heap:</p> created on the heap:</p>
<pre>shared_ptr&lt;X&gt; px(new X);</pre> <pre>shared_ptr&lt;X&gt; px(new X);</pre>
<P>but at construction time, <code>px</code> does not exist yet, and it is <P>but at construction time, <code>px</code> does not exist yet, and it is
impossible to create another <code>shared_ptr</code> instance that shares impossible to create another <code>shared_ptr</code> instance that shares
ownership with it.</P> ownership with it.</P>
<P>Depending on context, if the inner <code>shared_ptr</code> <code>this_</code> doesn't <P>Depending on context, if the inner <code>shared_ptr</code> <code>this_</code> doesn't
need to keep the object alive, use a <code>null_deleter</code> as explained <A href="#static"> need to keep the object alive, use a <code>null_deleter</code> as explained <A href="#static">
here</A> and <A href="#weak_without_shared">here</A>. If <code>X</code> is here</A> and <A href="#weak_without_shared">here</A>. If <code>X</code> is
supposed to always live on the heap, and be managed by a <code>shared_ptr</code>, supposed to always live on the heap, and be managed by a <code>shared_ptr</code>,
use a static factory function:</P> use a static factory function:</P>
<pre>class X <pre>class X
{ {
private: private:
@@ -424,13 +424,13 @@ public:
} }
}; };
</pre> </pre>
<h2><A name="from_this">Obtaining a <code>shared_ptr</code> to <code>this</code></A></h2> <h2><A name="from_this">Obtaining a <code>shared_ptr</code> to <code>this</code></A></h2>
<p>Sometimes it is needed to obtain a <code>shared_ptr</code> from <code>this</code> <p>Sometimes it is needed to obtain a <code>shared_ptr</code> from <code>this</code>
in a virtual member function under the assumption that <code>this</code> is in a virtual member function under the assumption that <code>this</code> is
already managed by a <code>shared_ptr</code>. The transformations <A href="#from_raw"> already managed by a <code>shared_ptr</code>. The transformations <A href="#from_raw">
described in the previous technique</A> cannot be applied.</p> described in the previous technique</A> cannot be applied.</p>
<P>A typical example:</P> <P>A typical example:</P>
<pre>class X <pre>class X
{ {
public: public:
@@ -469,8 +469,8 @@ public:
} }
}; };
</pre> </pre>
<p>The solution is to keep a weak pointer to <code>this</code> as a member in <code>impl</code>:</p> <p>The solution is to keep a weak pointer to <code>this</code> as a member in <code>impl</code>:</p>
<pre>class impl: public X, public Y <pre>class impl: public X, public Y
{ {
private: private:
@@ -499,10 +499,10 @@ public:
} }
}; };
</pre> </pre>
<p>The library now includes a helper class template <code><A href="enable_shared_from_this.html"> <p>The library now includes a helper class template <code><A href="enable_shared_from_this.html">
enable_shared_from_this</A></code> that can be used to encapsulate the enable_shared_from_this</A></code> that can be used to encapsulate the
solution:</p> solution:</p>
<pre>class impl: public X, public Y, public enable_shared_from_this&lt;impl&gt; <pre>class impl: public X, public Y, public enable_shared_from_this&lt;impl&gt;
{ {
public: public:
@@ -519,19 +519,19 @@ public:
} }
} }
</pre> </pre>
<p>Note that you no longer need to manually initialize the <code>weak_ptr</code> member <p>Note that you no longer need to manually initialize the <code>weak_ptr</code> member
in <code><A href="enable_shared_from_this.html">enable_shared_from_this</A></code>. in <code><A href="enable_shared_from_this.html">enable_shared_from_this</A></code>.
Constructing a <code>shared_ptr</code> to <code>impl</code> takes care of that.</p> Constructing a <code>shared_ptr</code> to <code>impl</code> takes care of that.</p>
<h2><A name="handle">Using <code>shared_ptr</code> as a smart counted handle</A></h2> <h2><A name="handle">Using <code>shared_ptr</code> as a smart counted handle</A></h2>
<p>Some library interfaces use opaque handles, a variation of the <A href="#incomplete"> <p>Some library interfaces use opaque handles, a variation of the <A href="#incomplete">
incomplete class technique</A> described above. An example:</p> incomplete class technique</A> described above. An example:</p>
<pre>typedef void * HANDLE; <pre>typedef void * HANDLE;
HANDLE CreateProcess(); HANDLE CreateProcess();
void CloseHandle(HANDLE); void CloseHandle(HANDLE);
</pre> </pre>
<p>Instead of a raw pointer, it is possible to use <code>shared_ptr</code> as the <p>Instead of a raw pointer, it is possible to use <code>shared_ptr</code> as the
handle and get reference counting and automatic resource management for free:</p> handle and get reference counting and automatic resource management for free:</p>
<pre>typedef shared_ptr&lt;void&gt; handle; <pre>typedef shared_ptr&lt;void&gt; handle;
handle createProcess() handle createProcess()
{ {
@@ -539,42 +539,42 @@ handle createProcess()
return pv; return pv;
} }
</pre> </pre>
<h2><A name="on_block_exit">Using <code>shared_ptr</code> to execute code on block exit</A></h2> <h2><A name="on_block_exit">Using <code>shared_ptr</code> to execute code on block exit</A></h2>
<p><code>shared_ptr&lt;void&gt;</code> can automatically execute cleanup code when <p><code>shared_ptr&lt;void&gt;</code> can automatically execute cleanup code when
control leaves a scope.</p> control leaves a scope.</p>
<UL> <UL>
<LI> <LI>
Executing <code>f(p)</code>, where <code>p</code> is a pointer:</LI></UL> Executing <code>f(p)</code>, where <code>p</code> is a pointer:</LI></UL>
<pre> shared_ptr&lt;void&gt; guard(p, f); <pre> shared_ptr&lt;void&gt; guard(p, f);
</pre> </pre>
<UL> <UL>
<LI> <LI>
Executing arbitrary code: <code>f(x, y)</code>:</LI></UL> Executing arbitrary code: <code>f(x, y)</code>:</LI></UL>
<pre> shared_ptr&lt;void&gt; guard(static_cast&lt;void*&gt;(0), <A href="../bind/bind.html" >bind</A>(f, x, y)); <pre> shared_ptr&lt;void&gt; guard(static_cast&lt;void*&gt;(0), <A href="../bind/bind.html" >bind</A>(f, x, y));
</pre> </pre>
<P>For a more thorough treatment, see the article "Simplify Your Exception-Safe <P>For a more thorough treatment, see the article "Simplify Your Exception-Safe
Code" by Andrei Alexandrescu and Petru Marginean, available online at <A href="http://www.cuj.com/experts/1812/alexandr.htm?topic=experts"> Code" by Andrei Alexandrescu and Petru Marginean, available online at <A href="http://www.cuj.com/experts/1812/alexandr.htm?topic=experts">
http://www.cuj.com/experts/1812/alexandr.htm?topic=experts</A>.</P> http://www.cuj.com/experts/1812/alexandr.htm?topic=experts</A>.</P>
<h2><A name="pvoid">Using <code>shared_ptr&lt;void&gt;</code> to hold an arbitrary <h2><A name="pvoid">Using <code>shared_ptr&lt;void&gt;</code> to hold an arbitrary
object</A></h2> object</A></h2>
<p><code>shared_ptr&lt;void&gt;</code> can act as a generic object pointer similar <p><code>shared_ptr&lt;void&gt;</code> can act as a generic object pointer similar
to <code>void*</code>. When a <code>shared_ptr&lt;void&gt;</code> instance to <code>void*</code>. When a <code>shared_ptr&lt;void&gt;</code> instance
constructed as:</p> constructed as:</p>
<pre> shared_ptr&lt;void&gt; pv(new X); <pre> shared_ptr&lt;void&gt; pv(new X);
</pre> </pre>
<p>is destroyed, it will correctly dispose of the <code>X</code> object by <p>is destroyed, it will correctly dispose of the <code>X</code> object by
executing <code>~X</code>.</p> executing <code>~X</code>.</p>
<p>This propery can be used in much the same manner as a raw <code>void*</code> is <p>This propery can be used in much the same manner as a raw <code>void*</code> is
used to temporarily strip type information from an object pointer. A <code>shared_ptr&lt;void&gt;</code> used to temporarily strip type information from an object pointer. A <code>shared_ptr&lt;void&gt;</code>
can later be cast back to the correct type by using <code><A href="shared_ptr.htm#static_pointer_cast"> can later be cast back to the correct type by using <code><A href="shared_ptr.htm#static_pointer_cast">
static_pointer_cast</A></code>.</p> static_pointer_cast</A></code>.</p>
<h2><A name="extra_data">Associating arbitrary data with heterogeneous <code>shared_ptr</code> <h2><A name="extra_data">Associating arbitrary data with heterogeneous <code>shared_ptr</code>
instances</A></h2> instances</A></h2>
<p><code>shared_ptr</code> and <code>weak_ptr</code> support <code>operator&lt;</code> <p><code>shared_ptr</code> and <code>weak_ptr</code> support <code>operator&lt;</code>
comparisons required by standard associative containers such as <code>std::map</code>. comparisons required by standard associative containers such as <code>std::map</code>.
This can be used to non-intrusively associate arbitrary data with objects This can be used to non-intrusively associate arbitrary data with objects
managed by <code>shared_ptr</code>:</p> managed by <code>shared_ptr</code>:</p>
<pre>typedef int Data; <pre>typedef int Data;
std::map&lt; shared_ptr&lt;void&gt;, Data &gt; userData; std::map&lt; shared_ptr&lt;void&gt;, Data &gt; userData;
// or std::map&lt; weak_ptr&lt;void&gt;, Data &gt; userData; to not affect the lifetime // or std::map&lt; weak_ptr&lt;void&gt;, Data &gt; userData; to not affect the lifetime
@@ -585,11 +585,11 @@ shared_ptr&lt;int&gt; pi(new int(3));
userData[px] = 42; userData[px] = 42;
userData[pi] = 91; userData[pi] = 91;
</pre> </pre>
<h2><A name="as_lock">Using <code>shared_ptr</code> as a CopyConstructible mutex lock</A></h2> <h2><A name="as_lock">Using <code>shared_ptr</code> as a CopyConstructible mutex lock</A></h2>
<p>Sometimes it's necessary to return a mutex lock from a function, and a <p>Sometimes it's necessary to return a mutex lock from a function, and a
noncopyable lock cannot be returned by value. It is possible to use <code>shared_ptr</code> noncopyable lock cannot be returned by value. It is possible to use <code>shared_ptr</code>
as a mutex lock:</p> as a mutex lock:</p>
<pre>class mutex <pre>class mutex
{ {
public: public:
@@ -603,9 +603,9 @@ shared_ptr&lt;mutex&gt; lock(mutex &amp; m)
return shared_ptr&lt;mutex&gt;(&amp;m, mem_fn(&amp;mutex::unlock)); return shared_ptr&lt;mutex&gt;(&amp;m, mem_fn(&amp;mutex::unlock));
} }
</pre> </pre>
<p>Better yet, the <code>shared_ptr</code> instance acting as a lock can be <p>Better yet, the <code>shared_ptr</code> instance acting as a lock can be
encapsulated in a dedicated <code>shared_lock</code> class:</p> encapsulated in a dedicated <code>shared_lock</code> class:</p>
<pre>class shared_lock <pre>class shared_lock
{ {
private: private:
@@ -616,17 +616,17 @@ public:
template&lt;class Mutex&gt; explicit shared_lock(Mutex &amp; m): pv((m.lock(), &amp;m), mem_fn(&amp;Mutex::unlock)) {} template&lt;class Mutex&gt; explicit shared_lock(Mutex &amp; m): pv((m.lock(), &amp;m), mem_fn(&amp;Mutex::unlock)) {}
}; };
</pre> </pre>
<p><code>shared_lock</code> can now be used as:</p> <p><code>shared_lock</code> can now be used as:</p>
<pre> shared_lock lock(m); <pre> shared_lock lock(m);
</pre> </pre>
<p>Note that <code>shared_lock</code> is not templated on the mutex type, thanks to <code> <p>Note that <code>shared_lock</code> is not templated on the mutex type, thanks to <code>
shared_ptr&lt;void&gt;</code>'s ability to hide type information.</p> shared_ptr&lt;void&gt;</code>'s ability to hide type information.</p>
<h2><A name="wrapper">Using <code>shared_ptr</code> to wrap member function calls</A></h2> <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> <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 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> An implementation is given below:</p>
<pre>template&lt;class T&gt; class pointer <pre>template&lt;class T&gt; class pointer
{ {
private: private:
@@ -669,10 +669,10 @@ int main()
px-&gt;g(); px-&gt;g();
} }
</pre> </pre>
<h2><A name="delayed">Delayed deallocation</A></h2> <h2><A name="delayed">Delayed deallocation</A></h2>
<p>In some situations, a single <code>px.reset()</code> can trigger an expensive <p>In some situations, a single <code>px.reset()</code> can trigger an expensive
deallocation in a performance-critical region:</p> deallocation in a performance-critical region:</p>
<pre>class X; // ~X is expensive <pre>class X; // ~X is expensive
class Y class Y
{ {
@@ -686,10 +686,10 @@ public:
} }
}; };
</pre> </pre>
<p>The solution is to postpone the potential deallocation by moving <code>px</code> <p>The solution is to postpone the potential deallocation by moving <code>px</code>
to a dedicated free list that can be periodically emptied when performance and to a dedicated free list that can be periodically emptied when performance and
response times are not an issue:</p> response times are not an issue:</p>
<pre>vector&lt; shared_ptr&lt;void&gt; &gt; free_list; <pre>vector&lt; shared_ptr&lt;void&gt; &gt; free_list;
class Y class Y
{ {
@@ -706,9 +706,9 @@ public:
// periodically invoke free_list.clear() when convenient // periodically invoke free_list.clear() when convenient
</pre> </pre>
<p>Another variation is to move the free list logic to the construction point by <p>Another variation is to move the free list logic to the construction point by
using a delayed deleter:</p> using a delayed deleter:</p>
<pre>struct delayed_deleter <pre>struct delayed_deleter
{ {
template&lt;class T&gt; void operator()(T * p) template&lt;class T&gt; void operator()(T * p)
{ {
@@ -723,9 +723,9 @@ public:
} }
}; };
</pre> </pre>
<h2><A name="weak_without_shared">Weak pointers to objects not managed by a <code>shared_ptr</code></A></h2> <h2><A name="weak_without_shared">Weak pointers to objects not managed by a <code>shared_ptr</code></A></h2>
<p>Make the object hold a <code>shared_ptr</code> to itself, using a <code>null_deleter</code>:</p> <p>Make the object hold a <code>shared_ptr</code> to itself, using a <code>null_deleter</code>:</p>
<pre>class X <pre>class X
{ {
private: private:
@@ -748,18 +748,18 @@ public:
X &amp; operator=(X const &amp; rhs) X &amp; operator=(X const &amp; rhs)
{ {
i_ = rhs.i_; i_ = rhs.i_;
} }
weak_ptr&lt;X&gt; get_weak_ptr() const { return this_; } weak_ptr&lt;X&gt; get_weak_ptr() const { return this_; }
}; };
</pre> </pre>
<p>When the object's lifetime ends, <code>X::this_</code> will be destroyed, and <p>When the object's lifetime ends, <code>X::this_</code> will be destroyed, and
all weak pointers will automatically expire.</p> all weak pointers will automatically expire.</p>
<hr> <hr>
<p>$Date$</p> <p>$Date$</p>
<p><small>Copyright <EFBFBD> 2003 Peter Dimov. Distributed under the Boost Software License, Version <p><small>Copyright &copy; 2003 Peter Dimov. Distributed under the Boost Software License, Version
1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or 1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or
copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p> copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p>
</body> </body>
</html> </html>

View File

@@ -1,6 +1,6 @@
# Boost.SmartPtr Library test Jamfile # Boost.SmartPtr Library test Jamfile
# #
# Copyright (c) 2003-2007 Peter Dimov # Copyright (c) 2003-2013 Peter Dimov
# Copyright (c) 2003 Dave Abrahams # Copyright (c) 2003 Dave Abrahams
# #
# Distributed under the Boost Software License, Version 1.0. (See # Distributed under the Boost Software License, Version 1.0. (See
@@ -21,6 +21,7 @@ import testing ;
[ run get_deleter_test.cpp ] [ run get_deleter_test.cpp ]
[ run intrusive_ptr_test.cpp ] [ run intrusive_ptr_test.cpp ]
[ run intrusive_ptr_move_test.cpp ] [ run intrusive_ptr_move_test.cpp ]
[ run intrusive_ref_counter_test.cpp ]
[ run atomic_count_test.cpp ] [ run atomic_count_test.cpp ]
[ run lw_mutex_test.cpp ] [ run lw_mutex_test.cpp ]
[ compile-fail shared_ptr_assign_fail.cpp ] [ compile-fail shared_ptr_assign_fail.cpp ]
@@ -45,7 +46,8 @@ import testing ;
[ run spinlock_try_test.cpp : : : <threading>multi : spinlock_try_test.mt ] [ run spinlock_try_test.cpp : : : <threading>multi : spinlock_try_test.mt ]
[ run spinlock_pool_test.cpp ] [ run spinlock_pool_test.cpp ]
[ run make_shared_test.cpp ] [ run make_shared_test.cpp ]
[ run sp_convertible_test.cpp ] [ run make_shared_perfect_forwarding_test.cpp ]
[ run shared_ptr_convertible_test.cpp ]
[ run wp_convertible_test.cpp ] [ run wp_convertible_test.cpp ]
[ run ip_convertible_test.cpp ] [ run ip_convertible_test.cpp ]
[ run allocate_shared_test.cpp ] [ run allocate_shared_test.cpp ]
@@ -59,7 +61,107 @@ import testing ;
[ run sp_recursive_assign_rv_test.cpp ] [ run sp_recursive_assign_rv_test.cpp ]
[ run sp_recursive_assign2_rv_test.cpp ] [ run sp_recursive_assign2_rv_test.cpp ]
[ run esft_constructor_test.cpp ] [ run esft_constructor_test.cpp ]
[ run enable_shared_from_raw_test.cpp ]
[ compile-fail auto_ptr_lv_fail.cpp ] [ compile-fail auto_ptr_lv_fail.cpp ]
[ run atomic_count_test2.cpp ] [ run atomic_count_test2.cpp ]
[ run sp_typeinfo_test.cpp ]
[ compile make_shared_fp_test.cpp ]
[ run sp_hash_test.cpp ]
[ 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 ]
; ;
} }

View File

@@ -0,0 +1,241 @@
// allocate_shared_alloc11_test.cpp
//
// allocate_shared with a minimal C++11 allocator
//
// Copyright 2007-2009, 2014 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/detail/lightweight_test.hpp>
#include <boost/make_shared.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/config.hpp>
#include <cstddef>
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
template< class T > class cxx11_allocator
{
public:
typedef T value_type;
cxx11_allocator()
{
}
template< class Y > cxx11_allocator( cxx11_allocator<Y> const & )
{
}
T * allocate( std::size_t n )
{
return static_cast< T* >( ::operator new( n * sizeof( T ) ) );
}
void deallocate( T * p, std::size_t n )
{
::operator delete( p );
}
};
class X
{
private:
X( X const & );
X & operator=( X const & );
void * operator new( std::size_t n )
{
BOOST_ERROR( "private X::new called" );
return ::operator new( n );
}
void operator delete( void * p )
{
BOOST_ERROR( "private X::delete called" );
::operator delete( p );
}
public:
static int instances;
int v;
explicit X( int a1 = 0, int a2 = 0, int a3 = 0, int a4 = 0, int a5 = 0, int a6 = 0, int a7 = 0, int a8 = 0, int a9 = 0 ): v( a1+a2+a3+a4+a5+a6+a7+a8+a9 )
{
++instances;
}
~X()
{
--instances;
}
};
int X::instances = 0;
int main()
{
{
boost::shared_ptr< int > pi = boost::allocate_shared< int >( cxx11_allocator<int>() );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( *pi == 0 );
}
{
boost::shared_ptr< int > pi = boost::allocate_shared< int >( cxx11_allocator<int>(), 5 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( *pi == 5 );
}
BOOST_TEST( X::instances == 0 );
{
boost::shared_ptr< X > pi = boost::allocate_shared< X >( cxx11_allocator<void>() );
boost::weak_ptr<X> wp( pi );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( pi->v == 0 );
pi.reset();
BOOST_TEST( X::instances == 0 );
}
{
boost::shared_ptr< X > pi = boost::allocate_shared< X >( cxx11_allocator<void>(), 1 );
boost::weak_ptr<X> wp( pi );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( pi->v == 1 );
pi.reset();
BOOST_TEST( X::instances == 0 );
}
{
boost::shared_ptr< X > pi = boost::allocate_shared< X >( cxx11_allocator<void>(), 1, 2 );
boost::weak_ptr<X> wp( pi );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( pi->v == 1+2 );
pi.reset();
BOOST_TEST( X::instances == 0 );
}
{
boost::shared_ptr< X > pi = boost::allocate_shared< X >( cxx11_allocator<void>(), 1, 2, 3 );
boost::weak_ptr<X> wp( pi );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( pi->v == 1+2+3 );
pi.reset();
BOOST_TEST( X::instances == 0 );
}
{
boost::shared_ptr< X > pi = boost::allocate_shared< X >( cxx11_allocator<void>(), 1, 2, 3, 4 );
boost::weak_ptr<X> wp( pi );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( pi->v == 1+2+3+4 );
pi.reset();
BOOST_TEST( X::instances == 0 );
}
{
boost::shared_ptr< X > pi = boost::allocate_shared< X >( cxx11_allocator<void>(), 1, 2, 3, 4, 5 );
boost::weak_ptr<X> wp( pi );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( pi->v == 1+2+3+4+5 );
pi.reset();
BOOST_TEST( X::instances == 0 );
}
{
boost::shared_ptr< X > pi = boost::allocate_shared< X >( cxx11_allocator<void>(), 1, 2, 3, 4, 5, 6 );
boost::weak_ptr<X> wp( pi );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( pi->v == 1+2+3+4+5+6 );
pi.reset();
BOOST_TEST( X::instances == 0 );
}
{
boost::shared_ptr< X > pi = boost::allocate_shared< X >( cxx11_allocator<void>(), 1, 2, 3, 4, 5, 6, 7 );
boost::weak_ptr<X> wp( pi );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( pi->v == 1+2+3+4+5+6+7 );
pi.reset();
BOOST_TEST( X::instances == 0 );
}
{
boost::shared_ptr< X > pi = boost::allocate_shared< X >( cxx11_allocator<void>(), 1, 2, 3, 4, 5, 6, 7, 8 );
boost::weak_ptr<X> wp( pi );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( pi->v == 1+2+3+4+5+6+7+8 );
pi.reset();
BOOST_TEST( X::instances == 0 );
}
{
boost::shared_ptr< X > pi = boost::allocate_shared< X >( cxx11_allocator<void>(), 1, 2, 3, 4, 5, 6, 7, 8, 9 );
boost::weak_ptr<X> wp( pi );
BOOST_TEST( X::instances == 1 );
BOOST_TEST( pi.get() != 0 );
BOOST_TEST( pi->v == 1+2+3+4+5+6+7+8+9 );
pi.reset();
BOOST_TEST( X::instances == 0 );
}
return boost::report_errors();
}
#else // !defined( BOOST_NO_CXX11_ALLOCATOR )
int main()
{
return 0;
}
#endif

View File

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

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

View File

@@ -0,0 +1,181 @@
/*
* Copyright (c) 2012-2014 Glen Joseph Fernandes
* glenfe at live dot com
*
* Distributed under the Boost Software License,
* Version 1.0. (See accompanying file LICENSE_1_0.txt
* or copy at http://boost.org/LICENSE_1_0.txt)
*/
#include <boost/detail/lightweight_test.hpp>
#include <boost/smart_ptr/allocate_shared_array.hpp>
#include <boost/smart_ptr/weak_ptr.hpp>
#include <boost/type_traits/alignment_of.hpp>
class type {
public:
static unsigned int instances;
explicit type() {
instances++;
}
~type() {
instances--;
}
private:
type(const type&);
type& operator=(const type&);
};
unsigned int type::instances = 0;
int main() {
{
boost::shared_ptr<int[]> a1 = boost::allocate_shared_noinit<int[]>(std::allocator<int>(), 3);
int* a2 = a1.get();
BOOST_TEST(a1.use_count() == 1);
BOOST_TEST(a2 != 0);
BOOST_TEST(size_t(a2) % boost::alignment_of<int>::value == 0);
}
{
boost::shared_ptr<int[3]> a1 = boost::allocate_shared_noinit<int[3]>(std::allocator<int>());
int* a2 = a1.get();
BOOST_TEST(a1.use_count() == 1);
BOOST_TEST(a2 != 0);
BOOST_TEST(size_t(a2) % boost::alignment_of<int>::value == 0);
}
{
boost::shared_ptr<int[][2]> a1 = boost::allocate_shared_noinit<int[][2]>(std::allocator<int>(), 2);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1.use_count() == 1);
}
{
boost::shared_ptr<int[2][2]> a1 = boost::allocate_shared_noinit<int[2][2]>(std::allocator<int>());
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1.use_count() == 1);
}
{
boost::shared_ptr<const int[]> a1 = boost::allocate_shared_noinit<const int[]>(std::allocator<int>(), 3);
const int* a2 = a1.get();
BOOST_TEST(a1.use_count() == 1);
BOOST_TEST(a2 != 0);
BOOST_TEST(size_t(a2) % boost::alignment_of<int>::value == 0);
}
{
boost::shared_ptr<const int[3]> a1 = boost::allocate_shared_noinit<const int[3]>(std::allocator<int>());
const int* a2 = a1.get();
BOOST_TEST(a1.use_count() == 1);
BOOST_TEST(a2 != 0);
BOOST_TEST(size_t(a2) % boost::alignment_of<int>::value == 0);
}
{
boost::shared_ptr<const int[][2]> a1 = boost::allocate_shared_noinit<const int[][2]>(std::allocator<int>(), 2);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1.use_count() == 1);
}
{
boost::shared_ptr<const int[2][2]> a1 = boost::allocate_shared_noinit<const int[2][2]>(std::allocator<int>());
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1.use_count() == 1);
}
BOOST_TEST(type::instances == 0);
{
boost::shared_ptr<type[]> a1 = boost::allocate_shared_noinit<type[]>(std::allocator<type>(), 3);
type* a2 = a1.get();
BOOST_TEST(a1.use_count() == 1);
BOOST_TEST(a2 != 0);
BOOST_TEST(size_t(a2) % boost::alignment_of<type>::value == 0);
BOOST_TEST(type::instances == 3);
boost::weak_ptr<type[]> w1 = a1;
a1.reset();
BOOST_TEST(type::instances == 0);
}
BOOST_TEST(type::instances == 0);
{
boost::shared_ptr<type[3]> a1 = boost::allocate_shared_noinit<type[3]>(std::allocator<type>());
type* a2 = a1.get();
BOOST_TEST(a1.use_count() == 1);
BOOST_TEST(a2 != 0);
BOOST_TEST(size_t(a2) % boost::alignment_of<type>::value == 0);
BOOST_TEST(type::instances == 3);
boost::weak_ptr<type[3]> w1 = a1;
a1.reset();
BOOST_TEST(type::instances == 0);
}
BOOST_TEST(type::instances == 0);
{
boost::shared_ptr<type[][2]> a1 = boost::allocate_shared_noinit<type[][2]>(std::allocator<type>(), 2);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1.use_count() == 1);
BOOST_TEST(type::instances == 4);
a1.reset();
BOOST_TEST(type::instances == 0);
}
BOOST_TEST(type::instances == 0);
{
boost::shared_ptr<type[2][2]> a1 = boost::allocate_shared_noinit<type[2][2]>(std::allocator<type>());
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1.use_count() == 1);
BOOST_TEST(type::instances == 4);
a1.reset();
BOOST_TEST(type::instances == 0);
}
BOOST_TEST(type::instances == 0);
{
boost::shared_ptr<const type[]> a1 = boost::allocate_shared_noinit<const type[]>(std::allocator<type>(), 3);
const type* a2 = a1.get();
BOOST_TEST(a1.use_count() == 1);
BOOST_TEST(a2 != 0);
BOOST_TEST(size_t(a2) % boost::alignment_of<type>::value == 0);
BOOST_TEST(type::instances == 3);
a1.reset();
BOOST_TEST(type::instances == 0);
}
BOOST_TEST(type::instances == 0);
{
boost::shared_ptr<const type[3]> a1 = boost::allocate_shared_noinit<const type[3]>(std::allocator<type>());
const type* a2 = a1.get();
BOOST_TEST(a1.use_count() == 1);
BOOST_TEST(a2 != 0);
BOOST_TEST(size_t(a2) % boost::alignment_of<type>::value == 0);
BOOST_TEST(type::instances == 3);
a1.reset();
BOOST_TEST(type::instances == 0);
}
BOOST_TEST(type::instances == 0);
{
boost::shared_ptr<const type[][2]> a1 = boost::allocate_shared_noinit<const type[][2]>(std::allocator<type>(), 2);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1.use_count() == 1);
BOOST_TEST(type::instances == 4);
a1.reset();
BOOST_TEST(type::instances == 0);
}
BOOST_TEST(type::instances == 0);
{
boost::shared_ptr<const type[2][2]> a1 = boost::allocate_shared_noinit<const type[2][2]>(std::allocator<type>());
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1.use_count() == 1);
BOOST_TEST(type::instances == 4);
a1.reset();
BOOST_TEST(type::instances == 0);
}
return boost::report_errors();
}

View File

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

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

Some files were not shown because too many files have changed in this diff Show More