Compare commits

...

404 Commits

Author SHA1 Message Date
Peter Dimov
1dcc441ca1 Remove windows-2019 from GHA 2025-08-16 11:30:43 +03:00
Peter Dimov
cdf118b15b Avoid msvc-14.2 Appveyor timeout 2025-08-16 10:03:54 +03:00
Peter Dimov
ab75e1f892 Update appveyor.yml 2025-08-15 20:09:22 +03:00
Peter Dimov
dcfb560de3 Add msvc-14.2 to appveyor.yml 2025-08-15 19:51:08 +03:00
Peter Dimov
362fb1d677 Update appveyor.yml 2025-08-15 19:15:52 +03:00
Peter Dimov
79dac0e691 Merge pull request #118 from RedBeard0531/features/constexpr
Enable C++20 constexpr for intrusive_ptr
2025-05-10 11:52:28 +03:00
Mathias Stearn
d08d035bdf Enable C++20 constexpr for intrusive_ptr
fixes #117
2025-05-09 22:37:02 +02:00
Peter Dimov
709e446968 Update ci.yml 2025-05-08 16:04:15 +03:00
Peter Dimov
0b0924ff82 Update revision history 2025-01-15 19:40:28 +02:00
Peter Dimov
e7433ba545 Fix operator<< for shared_ptr and intrusive_ptr. Fixes #115. 2025-01-13 16:13:04 +02:00
Peter Dimov
785a17aaaf Add wide stream tests. Refs #115. 2025-01-13 16:12:31 +02:00
Peter Dimov
576d31f206 Add sp_ostream_test, ip_ostream_test, lsp_ostream_test 2025-01-13 15:24:45 +02:00
Peter Dimov
1b89a64e9b Add missing inline to boost::detail::lw_thread_routine to prevent multiple definition errors. 2025-01-07 21:31:20 +02:00
Peter Dimov
840e2ff1a8 Update .drone.jsonnet 2024-12-14 05:42:59 +02:00
Peter Dimov
622e2c3f83 Apply Node20 workaround 2024-12-14 05:41:18 +02:00
Peter Dimov
0630607f39 Update ci.yml 2024-12-14 05:40:47 +02:00
Peter Dimov
316f4cef77 Documentation fixes 2024-10-14 22:05:22 +03:00
Peter Dimov
9e866b8a95 Remove macos-12, add macos-15, ubuntu-24.04 2024-10-07 18:12:45 +03:00
Peter Dimov
cd01b87478 Update test/Jamfile 2024-10-07 14:19:59 +03:00
Peter Dimov
b3a4c39456 Update build.jam 2024-10-06 22:07:47 +03:00
Peter Dimov
5cdd3585db Regenerate CMakeLists.txt 2024-10-06 22:06:23 +03:00
Peter Dimov
916c8a7d7c Remove uses of boost::type_with_alignment 2024-10-06 21:03:51 +03:00
Peter Dimov
beaf20e7b5 Add sp_type_with_alignment 2024-10-06 20:56:48 +03:00
Peter Dimov
5e6b3a9702 Remove use of boost::type_identity 2024-10-06 20:32:29 +03:00
Peter Dimov
63589908b5 Add sp_type_identity 2024-10-06 20:29:27 +03:00
Peter Dimov
9466e73cbe Remove uses of boost::is_unbounded_array 2024-10-06 20:08:02 +03:00
Peter Dimov
b12e342c52 Remove uses of boost::is_bounded_array 2024-10-06 20:04:34 +03:00
Peter Dimov
7f880bc205 Add sp_is_unbounded_array 2024-10-06 19:58:40 +03:00
Peter Dimov
90fd5a1fc9 Add detail/sp_type_traits.hpp, sp_is_bounded_array 2024-10-06 19:54:45 +03:00
Peter Dimov
0bedddbf16 Remove uses of boost::is_array 2024-10-06 19:35:07 +03:00
Peter Dimov
173cf9ad7b Remove uses of boost::remove_cv 2024-10-06 19:28:42 +03:00
Peter Dimov
9db2b96843 Remove uses of boost::remove_extent 2024-10-06 19:26:17 +03:00
Peter Dimov
9b309184f8 Remove uses of boost::extent 2024-10-06 19:23:15 +03:00
Peter Dimov
7c87ae7985 Remove use of boost::remove_const 2024-10-06 19:19:48 +03:00
Peter Dimov
f2abcf1654 Remove uses of boost::enable_if_ 2024-10-06 19:16:42 +03:00
Peter Dimov
1361171bac Remove uses of boost::alignment_of 2024-10-06 18:57:30 +03:00
Peter Dimov
c5023afe04 Remove uses of boost::is_convertible 2024-10-06 18:48:33 +03:00
Peter Dimov
7cfc326207 Remove uses of boost::remove_reference 2024-10-06 18:44:04 +03:00
Peter Dimov
6b7effc83d Update test/CMakeLists.txt 2024-10-06 18:39:40 +03:00
Peter Dimov
89b4fa2552 Update build.jam 2024-10-06 18:18:02 +03:00
Peter Dimov
f991bdc8b3 Regenerate CMakeLists.txt 2024-10-06 18:17:31 +03:00
Peter Dimov
f57b455020 Remove uses of BOOST_STATIC_CONSTEXPR 2024-10-04 21:32:17 +03:00
Peter Dimov
8b22f5cb4f Remove uses of BOOST_OVERRIDE and BOOST_NOEXCEPT_OR_NOTHROW 2024-10-04 21:27:07 +03:00
Peter Dimov
1c988756d5 Remove uses of BOOST_CONSTEXPR 2024-10-03 18:31:59 +03:00
Peter Dimov
890b661909 Retain BOOST_SP_NOEXCEPT for compatibility 2024-10-03 18:21:19 +03:00
Peter Dimov
ab13ffa91d Remove uses of BOOST_NOEXCEPT 2024-10-03 18:15:27 +03:00
Peter Dimov
950ef1c130 Remove definition of BOOST_SP_NOEXCEPT to ensure no uses remain 2024-10-03 18:15:27 +03:00
Peter Dimov
fc43a2b9d1 Remove uses of BOOST_SP_NOEXCEPT from sp_counted_impl.hpp 2024-10-03 18:15:27 +03:00
Peter Dimov
df366326e1 Remove uses of BOOST_SP_NOEXCEPT from sp_counted_base_std_atomic.hpp 2024-10-03 18:15:27 +03:00
Peter Dimov
d77c27986e Remove uses of BOOST_SP_NOEXCEPT from sp_counted_base_nt.hpp 2024-10-03 18:15:27 +03:00
Peter Dimov
dbceed6210 Remove uses of BOOST_SP_NOEXCEPT from shared_count.hpp 2024-10-03 18:15:26 +03:00
Peter Dimov
9ed43780e4 Remove uses of BOOST_SP_NOEXCEPT from local_sp_deleter.hpp 2024-10-03 18:15:26 +03:00
Peter Dimov
9026b9c556 Remove uses of BOOST_SP_NOEXCEPT from local_counted_base.hpp 2024-10-03 18:15:26 +03:00
Peter Dimov
c4fed8ca7f Remove uses of BOOST_SP_NOEXCEPT from weak_ptr.hpp 2024-10-03 18:15:26 +03:00
Peter Dimov
f866c6a9ae Remove uses of BOOST_SP_NOEXCEPT from shared_ptr.hpp 2024-10-03 18:15:26 +03:00
Peter Dimov
87a4dc144f Remove uses of BOOST_SP_NOEXCEPT from shared_array.hpp 2024-10-03 18:15:26 +03:00
Peter Dimov
e6529af03f Remove uses of BOOST_SP_NOEXCEPT from scoped_ptr.hpp 2024-10-03 18:15:26 +03:00
Peter Dimov
b521582d46 Remove uses of BOOST_SP_NOEXCEPT from scoped_array.hpp 2024-10-03 18:15:26 +03:00
Peter Dimov
ca64f5c015 Remove uses of BOOST_SP_NOEXCEPT from make_shared_object.hpp 2024-10-03 18:15:26 +03:00
Peter Dimov
9a1d7008eb Remove uses of BOOST_SP_NOEXCEPT from make_local_shared_object.hpp 2024-10-03 18:15:26 +03:00
Peter Dimov
8a03c71a28 Remove uses of BOOST_SP_NOEXCEPT from local_shared_ptr.hpp 2024-10-03 18:15:26 +03:00
Peter Dimov
222323dc49 Remove uses of BOOST_SP_NOEXCEPT from intrusive_ref_counter.hpp 2024-10-03 18:15:26 +03:00
Peter Dimov
62fd6baa48 Remove uses of BOOST_SP_NOEXCEPT from intrusive_ptr.hpp 2024-10-03 18:15:26 +03:00
Peter Dimov
96ef19e72d Remove uses of BOOST_SP_NOEXCEPT from enable_shared_from_this.hpp 2024-10-03 18:15:26 +03:00
Peter Dimov
78057574cf Remove uses of BOOST_SP_NOEXCEPT from enable_shared_from.hpp 2024-10-03 18:15:26 +03:00
Peter Dimov
03e1bb314b Remove uses of BOOST_SP_NOEXCEPT from atomic_shared_ptr.hpp 2024-10-03 18:15:26 +03:00
Peter Dimov
505ed6753d Remove uses of BOOST_SP_NOEXCEPT from allocate_unique.hpp 2024-10-03 18:15:26 +03:00
Peter Dimov
82bee8581d Remove uses of BOOST_SP_NOEXCEPT from allocate_shared_array.hpp 2024-10-03 18:15:26 +03:00
Peter Dimov
b4174f66fa Remove uses of BOOST_SP_NOEXCEPT from allocate_local_shared_array.hpp 2024-10-03 18:15:26 +03:00
Peter Dimov
bf31a25fa5 Remove use of boost::has_virtual_destructor from pointer_cast.hpp 2024-10-03 18:15:25 +03:00
Peter Dimov
06da5cd574 Remove uses of BOOST_SP_NOEXCEPT from pointer_cast.hpp 2024-10-03 18:15:25 +03:00
Peter Dimov
c0c6244297 Update revision history 2024-10-03 18:15:06 +03:00
Peter Dimov
b0200dd829 Issue deprecation messages when a macro slated for removal is defined 2024-10-01 17:56:33 +03:00
Peter Dimov
7f7e3748cf Update revision history 2024-09-29 15:30:57 +03:00
Peter Dimov
682b285a21 Deprecate headers in boost/detail/ 2024-09-26 04:11:10 +03:00
Peter Dimov
94d31304f3 Remove uses of BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP 2024-09-25 20:26:14 +03:00
Peter Dimov
aa1a9ef2d7 Use static_assert in sp_assert_convertible 2024-09-25 20:15:31 +03:00
Peter Dimov
63ac28d26f Remove definition of sp_enable_if_auto_ptr, no longer used 2024-09-25 20:12:28 +03:00
Peter Dimov
72a019944c Remove obsolete comments 2024-09-25 19:30:15 +03:00
Peter Dimov
12733a052b Update test/Jamfile 2024-09-25 19:28:18 +03:00
Peter Dimov
e5472d59d1 Remove uses of BOOST_NO_CXX11_HDR_UNORDERED_SET 2024-09-25 19:23:01 +03:00
Peter Dimov
d58213cfcb Remove use of BOOST_NO_CXX11_HDR_TYPE_TRAITS 2024-09-25 18:22:32 +03:00
Peter Dimov
38d54034d7 Update sp_constexpr_test, sp_constexpr_test2 2024-09-25 18:19:55 +03:00
Peter Dimov
8863958e8d Remove use of BOOST_NO_CXX11_TEMPLATE_ALIASES 2024-09-25 18:14:53 +03:00
Peter Dimov
123040290c Remove use of BOOST_STATIC_ASSERT_MSG 2024-09-25 18:12:37 +03:00
Peter Dimov
abb0071ca6 Remove uses of BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX 2024-09-25 18:08:57 +03:00
Peter Dimov
000c7ae5ac Remove detail/operator_bool.hpp 2024-09-25 12:49:13 +03:00
Peter Dimov
f11b931cfd Remove uses of BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS 2024-09-25 12:47:28 +03:00
Peter Dimov
5d8304d2cc Remove uses of BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS 2024-09-25 12:42:20 +03:00
Peter Dimov
044d1f2cb9 Remove uses of BOOST_NO_CXX11_HDR_FUNCTIONAL 2024-09-25 12:39:46 +03:00
Peter Dimov
dccecc2500 Remove uses of BOOST_NO_CXX11_ALLOCATOR 2024-09-25 03:13:22 +03:00
Peter Dimov
0aa32dc692 Remove remaining uses of BOOST_NO_CXX11_RVALUE_REFERENCES 2024-09-25 03:07:04 +03:00
Peter Dimov
b4a0629b63 Remove uses of BOOST_NO_CXX11_VARIADIC_TEMPLATES 2024-09-25 03:04:27 +03:00
Peter Dimov
38b737c490 Remove uses of detail::sp_forward 2024-09-25 02:51:40 +03:00
Peter Dimov
314267a5f7 Remove uses of BOOST_NO_CXX11_SMART_PTR 2024-09-25 02:45:57 +03:00
Peter Dimov
ce308f21e8 Remove uses of BOOST_NO_CXX11_RVALUE_REFERENCES 2024-09-24 22:51:38 +03:00
Peter Dimov
cd0b99380e Disable C++03/C++11 ABI tests 2024-09-24 19:43:45 +03:00
Peter Dimov
0e6dd82e8e Remove boost::detail::sp_nullptr_t 2024-09-24 19:11:15 +03:00
Peter Dimov
569b07b91c Remove uses of BOOST_NO_CXX11_NULLPTR 2024-09-24 19:05:48 +03:00
Peter Dimov
bd0419c290 Remove uses of BOOST_SP_NO_SP_CONVERTIBLE 2024-09-24 18:49:22 +03:00
Peter Dimov
26cf7ff744 Remove uses of BOOST_NO_FUNCTION_TEMPLATE_ORDERING 2024-09-24 18:44:53 +03:00
Peter Dimov
c132c339c7 Remove uses of BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION 2024-09-24 18:41:46 +03:00
Peter Dimov
4a3432759d Remove uses of BOOST_NO_CV_VOID_SPECIALIZATIONS 2024-09-24 18:37:59 +03:00
Peter Dimov
3832411d31 Remove uses of BOOST_NO_MEMBER_TEMPLATES, BOOST_MSVC6_MEMBER_TEMPLATES 2024-09-24 18:35:32 +03:00
Peter Dimov
66e6f9b2ef Remove uses of BOOST_NO_MEMBER_TEMPLATE_FRIENDS 2024-09-24 18:33:22 +03:00
Peter Dimov
d2c2407585 Remove uses of BOOST_NO_IOSTREAM et al 2024-09-24 18:30:06 +03:00
Peter Dimov
694e6822ac Remove obsolete uses of BOOST_MSVC 2024-09-24 18:25:13 +03:00
Peter Dimov
fd94706918 Remove __CODEGUARD__ workarounds 2024-09-24 18:10:16 +03:00
Peter Dimov
c5e1280b77 Remove __BORLANDC__ workarounds 2024-09-24 18:09:33 +03:00
Peter Dimov
d66b173710 Remove BOOST_BORLANDC workarounds 2024-09-24 18:08:14 +03:00
Peter Dimov
d908c4d288 Remove requires_cxx11.hpp 2024-09-24 17:47:51 +03:00
Peter Dimov
41a36f89ec Regenerate CMakeLists.txt 2024-09-24 17:41:55 +03:00
Peter Dimov
c1e7bd1a51 Update meta/libraries.json 2024-09-24 17:41:09 +03:00
Peter Dimov
1dddd9f306 Remove C++03 from CI 2024-09-24 17:40:34 +03:00
Peter Dimov
e9c54b2430 Add VERBATIM to add_custom_target 2024-08-27 21:04:58 +03:00
Peter Dimov
17e299f11e Update build.jam, test/Jamfile 2024-08-27 19:13:36 +03:00
Peter Dimov
71902a7bdb Merge branch 'modular' of https://github.com/grafikrobot/boostorg.smart_ptr into feature/modular-b2 2024-08-27 19:06:55 +03:00
Peter Dimov
e9790f99f7 Update .drone.jsonnet 2024-08-27 16:38:50 +03:00
Rene Rivera
d4c605e6ff Sync from upstream. 2024-08-20 09:56:41 -05:00
René Ferdinand Rivera Morell
f5152b0904 Remove CI fetch of functional. 2024-08-18 11:20:51 -05:00
René Ferdinand Rivera Morell
7caada352c Remove CI fetch of functional. 2024-08-18 11:20:26 -05:00
René Ferdinand Rivera Morell
11e56a4ad9 Remove CI fetch of functional. 2024-08-18 11:18:51 -05:00
René Ferdinand Rivera Morell
c33504189a Remove CI fetch of functional. 2024-08-18 11:18:24 -05:00
Rene Rivera
960741cb2e Replace functional deps with correct container_hash deps. 2024-08-17 12:04:30 -05:00
Peter Dimov
c8ef3e2276 Update ContainerHash includes 2024-08-17 20:01:25 +03:00
Rene Rivera
72c25383d5 Manually fetch functional, as depinst doesn't. 2024-08-16 23:25:09 -05:00
Rene Rivera
6b826f1139 Manually fetch functional, as depinst doesn't. 2024-08-16 22:29:05 -05:00
Rene Rivera
591d0e0728 Add test to depinst search to try and get functional. 2024-08-16 21:52:55 -05:00
Rene Rivera
e86015f9f6 Move inter-lib dependencies to a project variable and into the build targets. 2024-07-23 22:34:22 -05:00
Rene Rivera
4f9487d0f3 Update copyright dates. 2024-07-20 22:52:03 -05:00
Rene Rivera
0925dcce4e Change all <source> references to <library>. 2024-07-20 21:25:39 -05:00
Rene Rivera
6bc7ec7e6b Sync from upstream. 2024-07-12 08:52:50 -05:00
Peter Dimov
1650077eee Update ci.yml 2024-07-08 21:10:41 +03:00
Peter Dimov
635dfe46ee Update C++03 deprecation message 2024-07-08 21:02:19 +03:00
Rene Rivera
fc0eeeffa6 Bump B2 require to 5.2 2024-06-14 11:33:56 -05:00
Rene Rivera
4df3174d4a Add requires-b2 check to top-level build file. 2024-05-05 09:00:01 -05:00
Rene Rivera
1a51e0f02c Sync from upstream. 2024-04-20 15:31:46 -05:00
Peter Dimov
c4ae5e0c42 Do not disable GCC intrinsics under clang-cl 2024-04-13 20:29:34 +03:00
Daniel Arndt
85b0ab073c Don't define BOOST_SP_HAS_GCC_INTRINSICS for MSVC 2024-04-12 08:10:31 -05:00
Rene Rivera
ac9154d1e5 Switch to library requirements instead of source. As source puts extra source in install targets. 2024-03-29 21:15:59 -05:00
Rene Rivera
788313fda2 Make the library modular usable. 2024-03-11 08:38:16 -05:00
Peter Dimov
3ef8cfd02f Update appveyor.yml 2024-02-29 16:58:54 +02:00
Peter Dimov
cd2aac8442 Update .drone.jsonnet 2024-02-29 16:40:23 +02:00
Peter Dimov
3ca07d82a7 Update test/Jamfile; Bind requires C++11 2024-02-29 16:14:39 +02:00
Peter Dimov
f8303629f1 Update requires_cxx11.hpp 2024-02-29 15:57:41 +02:00
Peter Dimov
ef0e40bcda Update ci.yml 2024-01-06 17:23:57 +02:00
Peter Dimov
4af91d46f1 Fix -Wundef warning by removing outdated workarounds 2024-01-06 15:48:05 +02:00
Peter Dimov
42dfdc9e51 Compile sp_pedantic_test.cpp with -Wundef 2024-01-06 15:35:52 +02:00
Peter Dimov
763c7f56cd Disable hash tests for gcc-4.6 2023-10-18 16:52:35 +03:00
Peter Dimov
029f089a4a Disable tests that require ContainerHash for C++03 compilers 2023-10-18 15:20:57 +03:00
Peter Dimov
66d11714bd Update ci.yml 2023-10-18 14:14:49 +03:00
Peter Dimov
ac0381f0b8 Update C++03 deprecation message 2023-10-18 14:12:02 +03:00
Peter Dimov
13be03abf8 Avoid -Wsign-conversion warning 2023-06-25 13:47:24 +03:00
Peter Dimov
5e7596ef06 Update ci.yml 2023-06-03 03:40:50 +03:00
Peter Dimov
ef1651449f Update C++03 deprecation message 2023-06-03 02:20:39 +03:00
Peter Dimov
b34786c4d4 Interleave calls to sp_thread_pause and sp_thread_sleep in yield_k, instead of doing a single pause at 0 2023-06-03 02:16:52 +03:00
Peter Dimov
aacfb25c82 Add BOOST_HEADER_DEPRECATED to boost/smart_ptr/detail/sp_thread_*.hpp 2023-06-03 02:14:43 +03:00
Peter Dimov
c7349834be Update CI files 2023-06-03 02:09:45 +03:00
Peter Dimov
414b0a65d9 Use yield primitives from Core 2023-06-02 22:08:15 +03:00
Peter Dimov
bcb2566e74 Disable dll_test_shared under UBSan 2023-03-06 08:01:35 +02:00
Peter Dimov
7070f9b3f8 Update .drone.jsonnet 2023-03-06 05:12:28 +02:00
Peter Dimov
78fd14f412 Add C++03 deprecation notice 2023-03-06 03:54:51 +02:00
Peter Dimov
861622d329 Update ci.yml 2023-03-06 01:34:27 +02:00
Glen Fernandes
366c60ad3b Add note about C++20 providing make_unique_for_overwrite 2022-12-15 01:11:38 -05:00
Peter Dimov
331c50132b Update appveyor.yml 2022-11-10 17:59:23 +02:00
Peter Dimov
97c9204a95 Align spinlock::v_ as a bool because of Apple PPC32. Refs #105. 2022-11-10 17:08:55 +02:00
Peter Dimov
c577d68b02 Disable make_shared_move_emulation_test for Clang 3.5, 3.6, 3.7 2022-10-20 00:19:59 +03:00
Peter Dimov
2ce29622f5 Update .drone.jsonnet 2022-10-19 21:36:15 +03:00
Peter Dimov
7e9c54ffa2 Disable -Wdeprecated-builtins for Clang 15 - the warning comes from Boost.Move 2022-10-19 20:52:55 +03:00
Peter Dimov
ca8d5216fc Remove new char[12345]; from smart_ptr_test, because it causes ASAN to fail 2022-10-19 20:50:16 +03:00
Peter Dimov
79e46f1719 Add Drone support 2022-10-19 19:48:32 +03:00
Peter Dimov
e6b5dc5ada Update ci.yml 2022-10-15 03:03:09 +03:00
Peter Dimov
dd57aa5b70 Update ci.yml 2022-10-11 02:59:52 +03:00
Peter Dimov
e4637b8500 Merge pull request #98 from egorpugin/patch-1
Add missing ifdef check.
2022-10-11 02:55:52 +03:00
Egor Pugin
a0d4ec3915 Add missing ifdef check. 2022-10-10 22:26:59 +03:00
Jordan Williams
59b5b17e81 Add support for different sync instructions for CodeWarrior PPC (#95)
* Use msync or se_isync as appropriate for CodeWarrior PPC

* Un-obsolete sp_counted_base_cw_ppc

* Remove untested VLE_ON branch

* Use the supported compiler intrinsic __sync(); instead of msync asm

* Revert "Use the supported compiler intrinsic __sync(); instead of msync asm"

This reverts commit 9b92ea28f0.
2022-06-22 18:41:00 +03:00
Peter Dimov
f2ab3b21f0 Merge pull request #90 from fanquake/use_core_checked_delete
refactor: use boost/core/checked_delete.hpp over boost/checked_delete.hpp
2022-05-20 03:45:08 +03:00
Peter Dimov
e04196b6a1 Update ci.yml 2022-05-20 01:35:15 +03:00
Peter Dimov
95eaa2d7c3 Update shared_ptr move constructors to improve codegen 2022-05-19 22:20:50 +03:00
Peter Dimov
2e31d0d633 Add ubuntu-22.04 to posix-cmake-test in ci.yml 2022-05-19 21:09:26 +03:00
Peter Dimov
b8cb132ab4 Update ci.yml 2022-05-19 20:15:52 +03:00
fanquake
f4d7116241 refactor: use core/checked_delete.hpp over checked_delete.hpp
boost/checked_delete.hpp has been deprecated.
2022-04-03 16:49:10 +01:00
Glen Fernandes
f2cc84a23c Correct example in documentation 2021-12-17 01:36:17 -05:00
Peter Dimov
f12a33813d Remove msvc-14.2 (in GHA); use clang-win from 2019 2021-12-17 02:49:45 +02:00
Glen Fernandes
cfde4f7407 Correct spelling in changelog 2021-12-16 11:47:55 -05:00
Glen Fernandes
b8d340b495 Update changelog 2021-12-16 11:29:54 -05:00
Glen Fernandes
6716193d9c Add get_allocator_pointer 2021-12-16 11:26:11 -05:00
Peter Dimov
8f40bff2f6 Remove cxxstd=2a from clang-8 2021-10-29 00:48:48 +03:00
Peter Dimov
1ef8f4e72d Remove 16.04 from ci.yml 2021-10-28 23:31:51 +03:00
Peter Dimov
f651a49d96 Enable syntax hightlighting 2021-10-28 23:16:09 +03:00
Peter Dimov
598314b8e1 Add msvc-14.3 to ci.yml 2021-10-28 23:15:44 +03:00
Peter Dimov
72221d1da0 Update ci.yml 2021-06-08 18:59:28 +03:00
Peter Dimov
2cbeb5b185 Update ci.yml 2021-06-08 18:32:47 +03:00
Peter Dimov
67e657c228 Build CMake tests in .travis.yml 2021-06-08 08:18:47 +03:00
Peter Dimov
eba3cf92e7 Disable failing tests on 4.4 in addition to 4.4.7 2021-06-08 05:58:06 +03:00
Peter Dimov
8340a13539 Merge branch 'feature/move-up-deleter' into feature/move-only-deleter 2021-05-11 18:03:35 +03:00
Peter Dimov
098d0f4ce3 Disable sp_unique_ptr_test2 on msvc-10.0 2021-05-11 15:54:21 +03:00
Peter Dimov
fec5fb97c8 Enable move-only deleters in the nullptr_t constructors 2021-05-11 02:15:27 +03:00
Peter Dimov
b52d7548b3 Enable move-only deleters in the allocator constructor 2021-05-11 02:05:28 +03:00
Peter Dimov
594c7485a5 Enable move-only deleters 2021-05-11 01:59:01 +03:00
Peter Dimov
d751041fb9 Add more test cases to sp_unique_ptr_test2 2021-05-11 01:33:48 +03:00
Peter Dimov
d41546ddce Move the unique_ptr deleter instead of copying it 2021-05-11 01:20:02 +03:00
Peter Dimov
f3424e74e8 Update .github/workflows 2021-04-19 18:53:52 +03:00
Peter Dimov
0eee7efd54 Update .github/workflows 2021-04-19 18:18:38 +03:00
Peter Dimov
dc2a127369 Update .travis.yml 2021-01-26 12:53:36 +02:00
Edward Diener
42575a0e51 Add "cxxstd" json field 2021-01-21 12:04:23 -05:00
Peter Dimov
64b2eac868 Add .github/workflows 2021-01-20 00:41:39 +02:00
Peter Dimov
856ed108e8 Update maintainer e-mail 2020-12-12 01:05:17 +02:00
Peter Dimov
678a544d27 Add cxxstd=latest to msvc-14.2 2020-11-14 21:42:09 +02:00
Peter Dimov
f1b06df6f4 Use address-model=32 for msvc-9.0,10.0,11.0 2020-11-14 21:37:15 +02:00
Peter Dimov
620620df3d Merge branch 'develop' 2020-06-19 19:17:05 +03:00
Peter Dimov
0bd61c1089 Remove boost_install call from CMakeLists.txt 2020-06-17 19:36:01 +03:00
Peter Dimov
d1295a9974 Remove boost_install call from CMakeLists.txt 2020-06-11 17:19:17 +03:00
Peter Dimov
6e8c15c02f Fix typo, trailing whitespace 2020-06-10 21:59:48 +03:00
Peter Dimov
7c0dcd338a Refactor yield_k.hpp 2020-06-10 18:58:08 +03:00
Peter Dimov
8d79ceaf8a Revert using a relaxed load before test_and_set; not necessary, and slower, with a proper yielding strategy as opposed to just pause-spinning 2020-06-10 18:20:33 +03:00
Peter Dimov
d35cf29b99 Revert "Use a relaxed load before XCHG to not lock cache line on contention (AMD spinlock recommendation per <https://probablydance.com/2019/12/30/measuring-mutexes-spinlocks-and-how-bad-the-linux-scheduler-really-is/>)"
This reverts commit 8afe162910.
2020-06-10 18:18:35 +03:00
Peter Dimov
72ca834ae8 Change yield_k to not use sp_thread_yield; using sp_thread_sleep is always strictly superior, at least on Windows 2020-06-07 21:24:21 +03:00
Peter Dimov
8afe162910 Use a relaxed load before XCHG to not lock cache line on contention (AMD spinlock recommendation per <https://probablydance.com/2019/12/30/measuring-mutexes-spinlocks-and-how-bad-the-linux-scheduler-really-is/>) 2020-06-07 21:07:35 +03:00
Peter Dimov
5d31c1c443 Refactor yield_k.hpp 2020-06-07 20:40:41 +03:00
Peter Dimov
3db4ad9a15 Use a relaxed load before test_and_set to not lock cache line on contention (AMD spinlock recommendation per <https://probablydance.com/2019/12/30/measuring-mutexes-spinlocks-and-how-bad-the-linux-scheduler-really-is/>) 2020-06-07 17:59:55 +03:00
Peter Dimov
d0655ab145 Add atomic_count_gcc_atomic.hpp 2020-06-07 06:29:14 +03:00
Peter Dimov
7c01e640f7 Use int_least32_t in atomic_count_sync; prefer it to atomic_count_gcc_x86; mark latter obsolete 2020-06-07 06:05:17 +03:00
Peter Dimov
00db1e02c6 Add spinlock_gcc_atomic.hpp 2020-06-07 05:00:03 +03:00
Peter Dimov
914b93430a Change spinlock_sync.hpp to use a single byte 2020-06-07 04:10:49 +03:00
Peter Dimov
15ffd7852b Remove Clang C11 implementation; no longer used 2020-06-07 02:05:55 +03:00
Peter Dimov
c66c4f5ed1 Mark platform-specific implementations as obsolete 2020-06-07 02:04:42 +03:00
Peter Dimov
7e9d8c39a3 Add sp_has_gcc_intrinsics.hpp, sp_counted_base_gcc_atomic.hpp 2020-06-06 20:43:08 +03:00
Peter Dimov
a0d08b17e0 Fix include guards 2020-06-06 17:13:56 +03:00
Peter Dimov
108a86cdbd Rename sp_has_sync.hpp to sp_has_sync_intrinsics.hpp 2020-06-06 17:11:28 +03:00
Peter Dimov
d08bdc86e5 Remove unused files 2020-06-06 16:59:36 +03:00
Peter Dimov
f8dcf5f6f4 Use BOOST_SMT_PAUSE starting from the first iteration 2020-06-06 16:54:57 +03:00
Peter Dimov
d38f64ded9 Update documentation 2020-06-06 00:35:12 +03:00
Peter Dimov
b66fe51566 Avoid g++ 4.4 conflict between hash() and boost::hash 2020-06-06 00:15:58 +03:00
Peter Dimov
1b5568d585 Add sp_unordered_test 2020-06-05 18:54:44 +03:00
Peter Dimov
fad0c20263 Add owner_hash 2020-06-05 18:45:00 +03:00
Peter Dimov
1c61e54b13 Update documentation 2020-06-05 18:12:59 +03:00
Peter Dimov
a0fc1e6daa Add wp_unordered_test 2020-06-04 20:52:17 +03:00
Peter Dimov
5dd84ea389 Add .owner_hash_value to shared/weak_ptr, hash_value, std::hash/equal_to specializations for weak_ptr 2020-06-04 20:40:57 +03:00
Peter Dimov
bc677e9098 Do not require boost::hash in the std::hash specializations 2020-06-03 17:38:03 +03:00
Peter Dimov
688cfed63e Add Boost::bind to CMake test dependencies 2020-06-03 07:38:07 +03:00
Peter Dimov
c63dc266b9 Update submodule libs/bind on Travis/Appveyor 2020-06-02 21:51:00 +03:00
Peter Dimov
6c181a0707 When BOOST_SP_REPORT_IMPLEMENTATION is defined, report what platform-specific atomic implementation is used 2020-06-02 20:51:38 +03:00
Peter Dimov
4047290b85 Add multithreaded tests 2020-06-02 18:58:45 +03:00
Peter Dimov
dc6c76d7e9 Move lightweight_thread.hpp to smart_ptr/detail 2020-06-02 17:55:15 +03:00
Peter Dimov
5a18ffdc56 Add std::hash specializations for shared_ptr, local_shared_ptr, intrusive_ptr 2020-06-02 05:59:23 +03:00
Peter Dimov
09fdd5ebfd Add FreeBSD to Travis 2020-06-01 18:18:57 +03:00
Peter Dimov
911874e139 Add gcc-10 to Travis 2020-06-01 18:18:12 +03:00
Peter Dimov
c7c0eacb74 Add initializers to eq and lt 2020-06-01 15:08:53 +03:00
Peter Dimov
9ed9f43ca8 Document owner_less, owner_equal_to 2020-06-01 03:53:21 +03:00
Peter Dimov
0ddf990869 Add noexcept to owner_less, owner_equal_to 2020-06-01 03:44:41 +03:00
Peter Dimov
a08a5f3d41 Update introduction 2020-06-01 03:26:02 +03:00
Peter Dimov
77c2d4cad7 Add owner_less_test2 2020-06-01 03:13:42 +03:00
Peter Dimov
fd612dc114 Add owner_equal_to 2020-06-01 03:05:34 +03:00
Peter Dimov
e67ebef9a7 Update changelog 2020-06-01 02:01:10 +03:00
Peter Dimov
6f5b9c7b37 Document local_shared_ptr::owner_equals 2020-06-01 01:59:40 +03:00
Peter Dimov
91f3aa0386 Add local_shared_ptr::owner_equals 2020-06-01 01:35:25 +03:00
Peter Dimov
686a354f21 Add lsp_owner_before_test 2020-06-01 01:16:46 +03:00
Peter Dimov
efceb04665 Asciidoctor 2 fixes 2020-06-01 01:02:09 +03:00
Peter Dimov
ca57860ae2 Update footer 2020-06-01 00:41:25 +03:00
Peter Dimov
9dcd05f918 Document owner_equals 2020-06-01 00:40:02 +03:00
Peter Dimov
4b724ab3f8 Add mixed shared_count/weak_count operator== overloads to avoid refcount manipulation 2020-05-31 22:07:36 +03:00
Peter Dimov
58915ca2fe Add owner_equals 2020-05-31 21:41:06 +03:00
Peter Dimov
62b0e5cdf4 Add mixed shared_count/weak_count operator< overloads to avoid refcount manipulation 2020-05-31 21:12:12 +03:00
Peter Dimov
951ff783b5 Add sp_owner_before_test 2020-05-31 20:33:24 +03:00
Peter Dimov
6421394e70 Fix msvc-8.0 failures 2020-05-31 20:14:25 +03:00
Glen Fernandes
121312cc22 Use allocator access utilities 2020-05-21 23:14:23 -04:00
Peter Dimov
1e5df9d551 Merge pull request #79 from EugeneZelenko/use-boost-override
Fix Clang-tidy modernize-use-override warnings.
2020-05-19 01:58:20 +03:00
Peter Dimov
496127ab99 Merge pull request #77 from eldiener/develop
Changes for Embarcadero C++ clang-based compilers, targeting Boost 1.74
2020-05-19 01:57:37 +03:00
Eugene Zelenko
2af343a2cb Fix Clang-tidy modernize-use-override warnings. 2020-05-12 18:01:55 -07:00
Edward Diener
c6b3700ef1 Merge branch 'develop' of https://github.com/boostorg/smart_ptr into cppbuilder 2020-05-06 11:32:12 -04:00
Edward Diener
2a93d30e73 Change conditions to be the same. 2020-05-06 11:31:57 -04:00
Peter Dimov
02cc561248 Only use warnings-as-errors on msvc, gcc, clang 2020-04-28 05:05:57 +03:00
Peter Dimov
066b398114 Disable -Wc11-extensions in sp_counted_base_clang.hpp 2020-04-27 00:50:15 +03:00
Peter Dimov
9c43c69c14 Add sp_pedantic_test 2020-04-26 19:57:05 +03:00
Peter Dimov
eb8998cd91 Add Clang 10 to Travis 2020-04-26 18:27:35 +03:00
Edward Diener
df06c324a7 Merge branch 'develop' of https://github.com/boostorg/smart_ptr into cppbuilder 2020-04-19 02:49:06 -04:00
Peter Dimov
0ddfab493c Do not enable -Wsuggest-override in C++03 mode 2020-04-14 07:12:35 +03:00
Peter Dimov
a2732e207a Add BOOST_OVERRIDE to sp_counted_impl.hpp 2020-04-14 00:55:52 +03:00
Peter Dimov
5be7523ebe Merge branch 'develop' into feature/suggest-override 2020-04-14 00:45:24 +03:00
Peter Dimov
2320dafc03 Add BOOST_OVERRIDE to bad_weak_ptr.hpp and local_counted_base.hpp 2020-04-14 00:42:57 +03:00
Peter Dimov
7ab4093f46 Use shared_ptr and make_shared in sp_override_test 2020-04-14 00:32:25 +03:00
Peter Dimov
296c203135 Rename sp_warning_test to sp_override_test 2020-04-14 00:15:32 +03:00
Glen Fernandes
2dd35e5fbc Mark functions with BOOST_OVERRIDE 2020-04-13 15:34:13 -04:00
Peter Dimov
977544feda Add sp_warning_test 2020-04-08 21:25:36 +03:00
Peter Dimov
54b5498208 Manually convince clang-cl to fail shared_from_fail and weak_from_fail 2020-04-02 04:01:21 +03:00
Peter Dimov
da81452f1f Make shared_from_this and weak_from_this private in enable_shared_from. Fixes #75. 2020-04-02 02:16:59 +03:00
Peter Dimov
7b9a969215 Add deduction guides to shared_ptr and weak_ptr. Fixes #73. 2020-04-02 00:28:02 +03:00
Edward Diener
cd562eb053 Change __BORLANDC__ to BOOST_BORLANDC, which is defined in Boost config for the Embarcadero non-clang-based compilers. 2020-03-26 17:17:22 -04:00
Glen Fernandes
91cd83e5bf Correct make_unique_noinit example 2020-02-13 21:36:58 -05:00
Peter Dimov
2fdb8c4b0a Fix Travis issues; remove unnecessary jobs 2020-01-14 19:16:05 +02:00
Peter Dimov
e806b53433 Update Travis 2020-01-14 17:04:51 +02:00
Peter Dimov
e0c7bd9a7e Don't build tests when installing; link to Threads::Threads in tests because of lw_thread_test.cpp 2020-01-10 00:54:01 +02:00
Peter Dimov
766ab05a12 Update submodule libs/preprocessor on Travis (needed by CMake tests) 2020-01-09 15:53:38 +02:00
Peter Dimov
05cbefd28e Update submodule tools/cmake on Travis 2020-01-09 01:41:15 +02:00
Peter Dimov
bfbdf4f45f Add CMake install support, tests 2020-01-08 05:08:37 +02:00
Peter Dimov
169c0cd52a Remove lwm_nop.hpp; add lwm_std_mutex.hpp 2020-01-08 03:57:13 +02:00
Peter Dimov
7d70691a16 Remove Windows Runtime workaround from yield_k.hpp; it's no longer relevant, Sleep is available 2020-01-08 03:09:11 +02:00
Peter Dimov
90c27d7cfa Remove Windows Runtime workaround from lwm_win32_cs.hpp; it's no longer relevant, InitializeCriticalSection is available 2020-01-08 02:55:14 +02:00
Glen Fernandes
43d1fe12c5 Include lightweight_test from core and workaround from config 2020-01-01 08:31:25 -05:00
Peter Dimov
a2749dddb4 Disable 32 bit clang-win to avoid mspdbcore.dll errors 2019-12-05 15:49:48 +02:00
Peter Dimov
a71e62146c Add VS2019 to Appveyor; separate clang-win into its own job 2019-11-24 00:05:38 +02:00
Glen Fernandes
274ec17836 Even more documentation corrections 2019-09-15 02:06:23 -04:00
Glen Fernandes
a7341070f1 More documentation corrections 2019-09-03 11:53:42 -04:00
Glen Fernandes
a6323354cd Update constraints and synopsis in documentation 2019-09-02 22:10:09 -04:00
Glen Fernandes
f788448101 Document alloc_deleter 2019-08-30 12:52:50 -04:00
Glen Fernandes
283f2d2a11 Simplify synopsis using alias template 2019-08-30 12:04:09 -04:00
Glen Fernandes
034f94617d Workaround for VC10 unique_ptr operator-> 2019-08-30 12:03:36 -04:00
Glen Fernandes
6a5f67b3a2 Disable tests on VC10 which lacks conforming unique_ptr 2019-08-30 10:50:56 -04:00
Glen Fernandes
dcd3c8ef80 In test cases, include allocate_unique first 2019-08-30 08:17:54 -04:00
Glen Fernandes
bb2a453ff6 Add additional test cases 2019-08-30 08:16:11 -04:00
Glen Fernandes
e56eec70ca Call to_address in the scalar destroy case too 2019-08-30 07:39:02 -04:00
Glen Fernandes
60c26acab8 Implement allocate_unique 2019-08-30 00:31:28 -04:00
Peter Dimov
00f6b5dcb0 Split gcc 8/9 Travis jobs (again) due to log size 2019-08-29 13:20:36 +03:00
Peter Dimov
6195ae1eb0 Disable -Wdelete-non-virtual-dtor 2019-08-29 12:27:51 +03:00
Peter Dimov
30291c406a Update .travis.yml 2019-08-29 01:01:52 +03:00
Peter Dimov
610f19f247 Merge pull request #69 from CJBussey/feature/fix_warning_implicit_conversion
atomic_count_std_atomic: static_cast v to std::int_least32_t
2019-06-23 04:21:52 -07:00
Carl Bussey
876d40a9ab atomic_count_std_atomic: static_cast v to std::int_least32_t
* fix implicit conversion warning
2019-06-18 11:44:17 +02:00
Peter Dimov
e4d642c46a Revert Travis to Trusty 2019-05-30 02:42:39 +03:00
Glen Fernandes
3dffa64f58 Bind allocator to element type, not scalar type 2019-05-15 07:33:04 -04:00
Glen Fernandes
af92bd89ef allocation_ptr will be modified, renamed, and moved to detail 2019-05-05 22:21:22 -04:00
Glen Fernandes
4742143605 Support allocation_ptr of const and volatile types 2019-05-04 09:43:11 -04:00
Glen Fernandes
872bf10347 Move construct and destroy from Smart_Ptr to Core 2019-05-03 17:39:25 -04:00
Glen Fernandes
c0ae9b3728 Implement allocation_ptr 2019-05-02 19:26:29 -04:00
Glen Fernandes
1298c2e8e5 Include sp_noexcept.hpp in sp_construct.hpp 2019-05-02 18:00:53 -04:00
Glen Fernandes
d593061b15 Move construct and destroy utilities to common header 2019-05-02 09:48:45 -04:00
Glen Fernandes
5072045f12 Use boost::noinit_adapt free function 2019-04-29 00:37:55 -04:00
Glen Fernandes
442e179920 Simplify implementation in terms of noinit_adaptor 2019-04-28 22:42:37 -04:00
Peter Dimov
9544a8cb91 Add revision history for 1.65 2019-04-24 17:21:37 +03:00
Peter Dimov
5823d6bcc9 Document enable_shared_from 2019-04-24 05:16:03 +03:00
Peter Dimov
f56e609757 Fix mistake in weak_from_this_test 2019-04-24 04:57:37 +03:00
Peter Dimov
8df63a3d0e Add tests for enable_shared_from 2019-04-24 04:50:59 +03:00
Peter Dimov
4b6cb1223b Add boost/smart_ptr/enable_shared_from.hpp 2019-04-24 04:50:30 +03:00
Peter Dimov
719e819570 Under g++ 4.4, <memory> doesn't compile with rtti=off 2019-04-22 15:57:56 +03:00
Peter Dimov
a571b3a250 Only include core/typeinfo.hpp when needed 2019-04-22 06:07:36 +03:00
Peter Dimov
f17c5e8e3b Add a few no_rtti tests 2019-04-22 05:43:08 +03:00
Peter Dimov
e306b30dcf Use a private detail/sp_typeinfo header instead of the deprecated Core one 2019-04-22 05:25:07 +03:00
Peter Dimov
b6b49ef591 Split g++ 8 Travis job, because log length 2019-04-22 02:19:27 +03:00
Peter Dimov
2122c7753c Avoid memcpy over a spinlock, because g++ 8 warns 2019-04-22 02:17:28 +03:00
Peter Dimov
7c76fb385d Add clang-win to Appveyor 2019-04-22 00:59:38 +03:00
Peter Dimov
372fac679b Remove _internal_aliasing_assign 2019-04-21 23:13:06 +03:00
Peter Dimov
e3adcaed1e Add revision history 2019-04-21 23:00:24 +03:00
Peter Dimov
016e682af6 Document weak_ptr aliasing constructors and empty 2019-04-21 22:52:44 +03:00
Peter Dimov
78e095d761 Disable tests that don't compile on msvc-8.0 2019-04-21 22:50:24 +03:00
Peter Dimov
eb8a91cb46 Add tests for the weak_ptr aliasing constructors 2019-04-21 22:44:09 +03:00
Peter Dimov
513cd15378 Add aliasing constructors to weak_ptr. Closes #67. 2019-04-21 22:43:04 +03:00
Peter Dimov
7bfa6a1f3d Fix typo 2019-04-21 21:33:55 +03:00
Peter Dimov
8120bb44cb Add rvalue pointer casts (closes #66) 2019-04-21 00:47:36 +03:00
Peter Dimov
18974ea2db Add cast tests to intrusive_ptr_test 2019-04-20 18:54:13 +03:00
Peter Dimov
2a4aca403a Merge branch 'develop' into feature/intrusive-ptr-tests 2019-04-20 18:15:31 +03:00
Peter Dimov
4d0d81477c Update msvc workarounds for 14.2 2019-04-20 18:15:05 +03:00
Peter Dimov
1725e26f70 Add assignment tests to intrusive_ptr_test 2019-04-20 18:02:11 +03:00
Peter Dimov
47fffaf11c Switch Appveyor to 2015 image 2019-04-14 18:24:21 +03:00
Peter Dimov
7f0323a347 Merge branch 'develop' of https://github.com/boostorg/smart_ptr into develop 2019-03-25 19:25:44 +02:00
Peter Dimov
6d8ea0f0c4 Remove project-id from doc/Jamfile 2019-03-25 19:25:33 +02:00
Glen Fernandes
d10299159a More asciidoctor changes
Reinstate the none/blank trick, but remove the blank line after it in local_shared_ptr.adoc that causes the problem. Also use that trick in place of the nested DLs which don't work with Asciidoctor 2
2019-03-24 23:41:08 -04:00
Glen Fernandes
adcab0e313 Update asciidoc to work with Asciidoctor 2.0 2019-03-24 20:28:17 -04:00
Peter Dimov
4fbb9ff076 Merge branch 'develop' 2019-03-02 21:08:43 +02:00
Glen Fernandes
8ccb36dfcf Use traits from TypeTraits 2019-02-22 19:36:32 -05:00
Glen Fernandes
fde2e91443 Use traits from TypeTraits 2019-02-22 19:01:55 -05:00
Peter Dimov
aa1341a6a2 Add BOOST_SP_NOEXCEPT to sp_counted_base_nt.hpp 2019-01-28 21:24:09 +02:00
Peter Dimov
053779f3ee Add BOOST_SP_NOEXCEPT to sp_counted_base_clang.hpp 2019-01-28 20:52:28 +02:00
Peter Dimov
51d8167fbf Add more BOOST_SP_NOEXCEPT 2019-01-28 18:46:39 +02:00
Peter Dimov
5f95fe9848 Fix .travis.yml 2019-01-06 04:37:59 +02:00
Peter Dimov
599d0bbba9 Add test/cmake_subdir_test 2019-01-05 19:43:22 +02:00
Peter Dimov
f769217ca8 Update CMakeLists.txt 2019-01-04 19:40:30 +02:00
Mike Dev
5d5d28a92e [CMake] Generate cmake target that other libraries can use
... to express their dependency on this library and retrieve any
configuration information such as the include directory and
transitive dependencies.
2019-01-02 22:32:38 +01:00
Peter Dimov
85fd341402 Merge pull request #59 from Kojoley/patch-1
Do not include the whole Predef for a single macro
2018-12-29 02:24:02 +02:00
Nikita Kniazev
eac6411867 Do not include the whole Predef for a single macro 2018-12-28 03:03:02 +03:00
Peter Dimov
97ef7970e8 Remove VARIANT from .travis.yml 2018-12-23 16:44:03 +02:00
Peter Dimov
4baa21dd5e Add libstdc++-5 for clang 7-ubsan 2018-12-23 08:17:32 +02:00
Peter Dimov
d0a89a81f0 More g++ warning suppression 2018-12-23 06:21:55 +02:00
Peter Dimov
ab2b977e4a Update clang-5 ubsan to clang-7 2018-12-23 05:19:07 +02:00
Peter Dimov
f380d4466c Avoid some g++ warnings in shared_ptr_test 2018-12-23 05:06:24 +02:00
Peter Dimov
2932ca4203 Change sp_counted_base_nt/_pt to use boost::int_least32_t instead of long (which may be 64 bit) 2018-12-23 01:54:36 +02:00
Peter Dimov
660d26c2c3 Change 03/11 to 98/0x for gcc 4.4 2018-12-23 00:08:32 +02:00
Peter Dimov
a095084492 Improve abi_test 2018-12-23 00:06:13 +02:00
Peter Dimov
a314765b94 Test variant=debug,release on Travis 2018-12-22 23:52:07 +02:00
Peter Dimov
02eba55685 Add abi_test 2018-12-22 22:56:20 +02:00
Peter Dimov
9c2c991291 Update .yml files 2018-12-18 21:53:58 +02:00
Peter Dimov
2e57ddb953 Update documentation of intrusive_ptr (document move ops, fix op<) 2018-11-25 17:54:51 +02:00
Peter Dimov
f6c3508aee Add make_local_shared_const_test 2018-11-10 21:04:22 +02:00
Peter Dimov
b7cca00408 Add make_shared_const_test 2018-11-10 20:44:00 +02:00
Peter Dimov
7e50abb9ec Merge pull request #55 from Romain-Geissler-1A/noexcept
Use BOOST_NOEXCEPT_OR_NOTHROW in public headers to prepare for C++20.
2018-11-10 19:32:01 +02:00
Peter Dimov
e7360779b0 Add g++ 8, clang 6.0, 7 to Travis 2018-11-10 18:35:29 +02:00
Romain Geissler
456da93897 Use BOOST_NOEXCEPT_OR_NOTHROW in public headers to prepare for C++20. 2018-11-09 14:55:34 +00:00
Peter Dimov
04f0847af4 Add --depth 1 to Appveyor 2018-09-21 20:53:27 +03:00
Glen Fernandes
29a08cdff6 Use BOOST_SYMBOL_VISIBLE with local_counted_base and children 2018-09-19 13:50:13 -04:00
Peter Dimov
6d3af760f6 Generously dispense BOOST_SYMBOL_VISIBLE 2018-09-18 03:18:23 +03:00
Peter Dimov
a9f39d2b94 Test make_shared/allocate_shared in dll_test too 2018-09-17 22:04:27 +03:00
Peter Dimov
4e2f236116 Add dll_test (to check for visibility issues) 2018-09-17 21:50:47 +03:00
Peter Dimov
4eb53db537 Use intrin.h under clang-cl 2018-08-12 01:26:59 +03:00
Glen Fernandes
a2b6ba85f3 Simplify exception safety in array construct utilities 2018-08-01 08:45:10 -04:00
Peter Dimov
e37cd4154f Work around ld: unrecognized option '--push-state--no-as-needed' 2018-05-10 16:16:08 +03:00
Peter Dimov
8563fc5c4e Add tests that include <windows.h> 2018-03-11 23:00:50 +02:00
Peter Dimov
67fab5c9ec Clang x64 warns that __stdcall is ignored, so don't use it there 2018-03-08 06:53:28 +02:00
Peter Dimov
f16fbdce26 Fix sp_interlocked on Cygwin 64 2018-03-08 05:15:49 +02:00
Peter Dimov
c3b3835a58 Mingw doesn't have _RTL_CRITICAL_SECTION 2018-03-08 03:34:00 +02:00
Peter Dimov
d1600b8abc Do not define pthread_* in lightweight_thread.hpp; mingw-w64 includes pthread.h in the standard library headers 2018-03-08 01:19:44 +02:00
Peter Dimov
5885763287 Remove clang from Appveyor; doesn't really work. 2018-03-08 00:39:15 +02:00
Peter Dimov
9bb12692b3 Only test C++14 with clang on Appveyor 2018-03-07 21:23:01 +02:00
Peter Dimov
773ef80f5d Add mingw configurations; move LLVM clang in its own VS2017 job 2018-03-07 20:06:04 +02:00
Peter Dimov
704de2bd67 Add Cygwin to Appveyor 2018-03-07 18:27:45 +02:00
Peter Dimov
1caa233faa Add address-model=32,64 to Appveyor 2018-03-07 17:37:28 +02:00
337 changed files with 11921 additions and 5450 deletions

422
.drone.jsonnet Normal file
View File

@@ -0,0 +1,422 @@
# Copyright 2022 Peter Dimov
# Distributed under the Boost Software License, Version 1.0.
# https://www.boost.org/LICENSE_1_0.txt
local library = "smart_ptr";
local triggers =
{
branch: [ "master", "develop", "feature/*" ]
};
local ubsan = { UBSAN: '1', UBSAN_OPTIONS: 'print_stacktrace=1' };
local asan = { ASAN: '1' };
local linux_pipeline(name, image, environment, packages = "", sources = [], arch = "amd64") =
{
name: name,
kind: "pipeline",
type: "docker",
trigger: triggers,
platform:
{
os: "linux",
arch: arch
},
steps:
[
{
name: "everything",
image: image,
environment: environment,
commands:
[
'set -e',
'uname -a',
'echo $DRONE_STAGE_MACHINE',
'wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -',
] +
(if sources != [] then [ ('apt-add-repository "' + source + '"') for source in sources ] else []) +
(if packages != "" then [ 'apt-get update', 'apt-get -y install ' + packages ] else []) +
[
'export LIBRARY=' + library,
'./.drone/drone.sh',
]
}
]
};
local macos_pipeline(name, environment, xcode_version = "12.2", osx_version = "catalina", arch = "amd64") =
{
name: name,
kind: "pipeline",
type: "exec",
trigger: triggers,
platform: {
"os": "darwin",
"arch": arch
},
node: {
"os": osx_version
},
steps: [
{
name: "everything",
environment: environment + { "DEVELOPER_DIR": "/Applications/Xcode-" + xcode_version + ".app/Contents/Developer" },
commands:
[
'export LIBRARY=' + library,
'./.drone/drone.sh',
]
}
]
};
local windows_pipeline(name, image, environment, arch = "amd64") =
{
name: name,
kind: "pipeline",
type: "docker",
trigger: triggers,
platform:
{
os: "windows",
arch: arch
},
"steps":
[
{
name: "everything",
image: image,
environment: environment,
commands:
[
'cmd /C .drone\\\\drone.bat ' + library,
]
}
]
};
[
linux_pipeline(
"Linux 14.04 GCC 4.8*",
"cppalliance/droneubuntu1404:1",
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11' },
),
linux_pipeline(
"Linux 14.04 GCC 4.9",
"cppalliance/droneubuntu1404:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-4.9', CXXSTD: '11' },
"g++-4.9",
[ "ppa:ubuntu-toolchain-r/test" ],
),
linux_pipeline(
"Linux 16.04 GCC 5*",
"cppalliance/droneubuntu1604:1",
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11,14' },
),
linux_pipeline(
"Linux 18.04 GCC 6",
"cppalliance/droneubuntu1804:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-6', CXXSTD: '11,14' },
"g++-6",
),
linux_pipeline(
"Linux 18.04 GCC 7* 32/64",
"cppalliance/droneubuntu1804:1",
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11,14,17', ADDRMD: '32,64' },
),
linux_pipeline(
"Linux 18.04 GCC 8 32/64",
"cppalliance/droneubuntu1804:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-8', CXXSTD: '11,14,17', ADDRMD: '32,64' },
"g++-8-multilib",
),
linux_pipeline(
"Linux 20.04 GCC 9* 32/64",
"cppalliance/droneubuntu2004:1",
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11,14,17,2a', ADDRMD: '32,64' },
),
linux_pipeline(
"Linux 20.04 GCC 9* ARM64",
"cppalliance/droneubuntu2004:multiarch",
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11,14,17,2a' },
arch="arm64",
),
linux_pipeline(
"Linux 20.04 GCC 9* S390x",
"cppalliance/droneubuntu2004:multiarch",
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11,14,17,2a' },
arch="s390x",
),
linux_pipeline(
"Linux 20.04 GCC 10 32/64",
"cppalliance/droneubuntu2004:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-10', CXXSTD: '11,14,17,20', ADDRMD: '32,64' },
"g++-10-multilib",
),
linux_pipeline(
"Linux 22.04 GCC 11* 32/64",
"cppalliance/droneubuntu2204:1",
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11,14,17,2a', ADDRMD: '32,64' },
),
linux_pipeline(
"Linux 22.04 GCC 12 32/64",
"cppalliance/droneubuntu2204:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-12', CXXSTD: '11,14,17,20,2b', ADDRMD: '32,64' },
"g++-12-multilib",
),
linux_pipeline(
"Linux 24.04 GCC 13 32 ASAN",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-13', CXXSTD: '11,14,17,20,2b', ADDRMD: '32' } + asan,
"g++-13-multilib",
),
linux_pipeline(
"Linux 24.04 GCC 13 32 UBSAN",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-13', CXXSTD: '11,14,17,20,2b', ADDRMD: '32' } + ubsan,
"g++-13-multilib",
),
linux_pipeline(
"Linux 24.04 GCC 13 64 UBSAN",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-13', CXXSTD: '11,14,17,20,2b', ADDRMD: '64' } + ubsan,
"g++-13-multilib",
),
linux_pipeline(
"Linux 24.04 GCC 14 UBSAN",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-14', CXXSTD: '11,14,17,20,2b' } + ubsan,
"g++-14-multilib",
),
linux_pipeline(
"Linux 24.04 GCC 14 ASAN",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-14', CXXSTD: '11,14,17,20,2b' } + asan,
"g++-14-multilib",
),
linux_pipeline(
"Linux 16.04 Clang 3.5",
"cppalliance/droneubuntu1604:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-3.5', CXXSTD: '11' },
"clang-3.5",
),
linux_pipeline(
"Linux 16.04 Clang 3.6",
"cppalliance/droneubuntu1604:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-3.6', CXXSTD: '11,14' },
"clang-3.6",
),
linux_pipeline(
"Linux 16.04 Clang 3.7",
"cppalliance/droneubuntu1604:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-3.7', CXXSTD: '11,14' },
"clang-3.7",
),
linux_pipeline(
"Linux 16.04 Clang 3.8",
"cppalliance/droneubuntu1604:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-3.8', CXXSTD: '11,14' },
"clang-3.8",
),
linux_pipeline(
"Linux 18.04 Clang 3.9",
"cppalliance/droneubuntu1804:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-3.9', CXXSTD: '11,14' },
"clang-3.9",
),
linux_pipeline(
"Linux 18.04 Clang 4.0",
"cppalliance/droneubuntu1804:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-4.0', CXXSTD: '11,14' },
"clang-4.0",
),
linux_pipeline(
"Linux 18.04 Clang 5.0",
"cppalliance/droneubuntu1804:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-5.0', CXXSTD: '11,14' },
"clang-5.0",
),
linux_pipeline(
"Linux 20.04 Clang 6.0",
"cppalliance/droneubuntu2004:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-6.0', CXXSTD: '11,14,17' },
"clang-6.0",
),
linux_pipeline(
"Linux 20.04 Clang 7",
"cppalliance/droneubuntu2004:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-7', CXXSTD: '11,14,17' },
"clang-7",
),
linux_pipeline(
"Linux 20.04 Clang 8",
"cppalliance/droneubuntu2004:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-8', CXXSTD: '11,14,17' },
"clang-8",
),
linux_pipeline(
"Linux 20.04 Clang 9",
"cppalliance/droneubuntu2004:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-9', CXXSTD: '11,14,17,2a' },
"clang-9",
),
linux_pipeline(
"Linux 20.04 Clang 10",
"cppalliance/droneubuntu2004:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-10', CXXSTD: '11,14,17,2a' },
"clang-10",
),
linux_pipeline(
"Linux 20.04 Clang 11",
"cppalliance/droneubuntu2004:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-11', CXXSTD: '11,14,17,2a' },
"clang-11",
),
linux_pipeline(
"Linux 20.04 Clang 12",
"cppalliance/droneubuntu2004:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-12', CXXSTD: '11,14,17,20' },
"clang-12",
),
linux_pipeline(
"Linux 22.04 Clang 13",
"cppalliance/droneubuntu2204:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-13', CXXSTD: '11,14,17,20,2b' },
"clang-13",
),
linux_pipeline(
"Linux 22.04 Clang 14",
"cppalliance/droneubuntu2204:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-14', CXXSTD: '11,14,17,20,2b' },
"clang-14",
),
linux_pipeline(
"Linux 22.04 Clang 15",
"cppalliance/droneubuntu2204:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-15', CXXSTD: '11,14,17,20,2b' },
"clang-15",
),
linux_pipeline(
"Linux 24.04 Clang 16",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-16', CXXSTD: '11,14,17,20,2b' },
"clang-16",
),
linux_pipeline(
"Linux 24.04 Clang 17 UBSAN",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-17', CXXSTD: '11,14,17,20,2b' } + ubsan,
"clang-17",
),
linux_pipeline(
"Linux 24.04 Clang 17 ASAN",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-17', CXXSTD: '11,14,17,20,2b' } + asan,
"clang-17",
),
linux_pipeline(
"Linux 24.04 Clang 18 UBSAN",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-18', CXXSTD: '11,14,17,20,2b' } + ubsan,
"clang-18",
),
linux_pipeline(
"Linux 24.04 Clang 18 ASAN",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-18', CXXSTD: '11,14,17,20,2b' } + asan,
"clang-18",
),
linux_pipeline(
"Linux 24.10 Clang 19",
"cppalliance/droneubuntu2410:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-19', CXXSTD: '11,14,17,20,2b' },
"clang-19",
),
macos_pipeline(
"MacOS 10.15 Xcode 12.2 UBSAN",
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '11,14,1z' } + ubsan,
),
macos_pipeline(
"MacOS 10.15 Xcode 12.2 ASAN",
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '11,14,1z' } + asan,
),
macos_pipeline(
"MacOS 12.4 Xcode 13.4.1 UBSAN",
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '11,14,17,20,2b' } + ubsan,
xcode_version = "13.4.1", osx_version = "monterey", arch = "arm64",
),
macos_pipeline(
"MacOS 12.4 Xcode 13.4.1 ASAN",
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '11,14,17,20,2b' } + asan,
xcode_version = "13.4.1", osx_version = "monterey", arch = "arm64",
),
windows_pipeline(
"Windows VS2015 msvc-14.0",
"cppalliance/dronevs2015",
{ TOOLSET: 'msvc-14.0', CXXSTD: '14,latest', B2_DONT_EMBED_MANIFEST: '1' },
),
windows_pipeline(
"Windows VS2017 msvc-14.1",
"cppalliance/dronevs2017",
{ TOOLSET: 'msvc-14.1', CXXSTD: '14,17,latest' },
),
windows_pipeline(
"Windows VS2019 msvc-14.2",
"cppalliance/dronevs2019",
{ TOOLSET: 'msvc-14.2', CXXSTD: '14,17,20,latest' },
),
windows_pipeline(
"Windows VS2022 msvc-14.3",
"cppalliance/dronevs2022:1",
{ TOOLSET: 'msvc-14.3', CXXSTD: '14,17,20,latest' },
),
]

23
.drone/drone.bat Normal file
View File

@@ -0,0 +1,23 @@
@REM Copyright 2022 Peter Dimov
@REM Distributed under the Boost Software License, Version 1.0.
@REM https://www.boost.org/LICENSE_1_0.txt
@ECHO ON
set LIBRARY=%1
set DRONE_BUILD_DIR=%CD%
set BOOST_BRANCH=develop
if "%DRONE_BRANCH%" == "master" set BOOST_BRANCH=master
cd ..
git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
git submodule update --init tools/boostdep
xcopy /s /e /q %DRONE_BUILD_DIR% libs\%LIBRARY%\
python tools/boostdep/depinst/depinst.py %LIBRARY%
cmd /c bootstrap
b2 -d0 headers
if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
if not "%ADDRMD%" == "" set ADDRMD=address-model=%ADDRMD%
b2 -j3 libs/%LIBRARY%/test toolset=%TOOLSET% %CXXSTD% %ADDRMD% variant=debug,release embed-manifest-via=linker

25
.drone/drone.sh Executable file
View File

@@ -0,0 +1,25 @@
#!/bin/bash
# Copyright 2022 Peter Dimov
# Distributed under the Boost Software License, Version 1.0.
# https://www.boost.org/LICENSE_1_0.txt
set -ex
export PATH=~/.local/bin:/usr/local/bin:$PATH
DRONE_BUILD_DIR=$(pwd)
BOOST_BRANCH=develop
if [ "$DRONE_BRANCH" = "master" ]; then BOOST_BRANCH=master; fi
cd ..
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
git submodule update --init tools/boostdep
cp -r $DRONE_BUILD_DIR/* libs/$LIBRARY
python tools/boostdep/depinst/depinst.py $LIBRARY
./bootstrap.sh
./b2 -d0 headers
echo "using $TOOLSET : : $COMPILER ;" > ~/user-config.jam
./b2 -j3 libs/$LIBRARY/test toolset=$TOOLSET cxxstd=$CXXSTD variant=debug,release ${ADDRMD:+address-model=$ADDRMD} ${UBSAN:+undefined-sanitizer=norecover debug-symbols=on} ${ASAN:+address-sanitizer=norecover debug-symbols=on} ${LINKFLAGS:+linkflags=$LINKFLAGS}

662
.github/workflows/ci.yml vendored Normal file
View File

@@ -0,0 +1,662 @@
name: CI
on:
pull_request:
push:
branches:
- master
- develop
- feature/**
env:
UBSAN_OPTIONS: print_stacktrace=1
jobs:
posix:
strategy:
fail-fast: false
matrix:
include:
- toolset: gcc-4.8
cxxstd: "11"
container: ubuntu:18.04
os: ubuntu-latest
install: g++-4.8-multilib
address-model: 32,64
- toolset: gcc-5
cxxstd: "11,14,1z"
container: ubuntu:18.04
os: ubuntu-latest
install: g++-5-multilib
address-model: 32,64
- toolset: gcc-6
cxxstd: "11,14,1z"
container: ubuntu:18.04
os: ubuntu-latest
install: g++-6-multilib
address-model: 32,64
- toolset: gcc-7
cxxstd: "11,14,17"
container: ubuntu:18.04
os: ubuntu-latest
install: g++-7-multilib
address-model: 32,64
- toolset: gcc-8
cxxstd: "11,14,17,2a"
container: ubuntu:20.04
os: ubuntu-latest
install: g++-8-multilib
address-model: 32,64
- toolset: gcc-9
cxxstd: "11,14,17,2a"
container: ubuntu:20.04
os: ubuntu-latest
install: g++-9-multilib
address-model: 32,64
- toolset: gcc-10
cxxstd: "11,14,17,2a"
container: ubuntu:20.04
os: ubuntu-latest
install: g++-10-multilib
address-model: 32,64
- toolset: gcc-11
cxxstd: "11,14,17,20"
os: ubuntu-22.04
install: g++-11-multilib
address-model: 32,64
- toolset: gcc-12
cxxstd: "11,14,17,20,2b"
os: ubuntu-22.04
install: g++-12-multilib
address-model: 32,64
- toolset: gcc-13
cxxstd: "11,14,17,20,2b"
os: ubuntu-latest
container: ubuntu:24.04
install: g++-13-multilib
address-model: 32,64
- toolset: gcc-14
cxxstd: "11,14,17,20,23,2c"
os: ubuntu-latest
container: ubuntu:24.04
install: g++-14-multilib
address-model: 32,64
- toolset: gcc-15
cxxstd: "11,14,17,20,23,2c"
os: ubuntu-latest
container: ubuntu:25.04
install: g++-15-multilib
address-model: 32,64
- toolset: clang
compiler: clang++-3.9
cxxstd: "11,14"
container: ubuntu:18.04
os: ubuntu-latest
install: clang-3.9
- toolset: clang
compiler: clang++-4.0
cxxstd: "11,14"
container: ubuntu:18.04
os: ubuntu-latest
install: clang-4.0
- toolset: clang
compiler: clang++-5.0
cxxstd: "11,14,1z"
container: ubuntu:18.04
os: ubuntu-latest
install: clang-5.0
- toolset: clang
compiler: clang++-6.0
cxxstd: "11,14,17"
container: ubuntu:20.04
os: ubuntu-latest
install: clang-6.0
- toolset: clang
compiler: clang++-7
cxxstd: "11,14,17"
container: ubuntu:20.04
os: ubuntu-latest
install: clang-7
- toolset: clang
compiler: clang++-8
cxxstd: "11,14,17"
container: ubuntu:20.04
os: ubuntu-latest
install: clang-8
- toolset: clang
compiler: clang++-9
cxxstd: "11,14,17,2a"
container: ubuntu:20.04
os: ubuntu-latest
install: clang-9
- toolset: clang
compiler: clang++-10
cxxstd: "11,14,17,2a"
container: ubuntu:20.04
os: ubuntu-latest
install: clang-10
- toolset: clang
compiler: clang++-11
cxxstd: "11,14,17,2a"
container: ubuntu:20.04
os: ubuntu-latest
install: clang-11
- toolset: clang
compiler: clang++-12
cxxstd: "11,14,17,20"
container: ubuntu:20.04
os: ubuntu-latest
install: clang-12
- toolset: clang
compiler: clang++-13
cxxstd: "11,14,17,20,2b"
container: ubuntu:22.04
os: ubuntu-latest
install: clang-13
- toolset: clang
compiler: clang++-14
cxxstd: "11,14,17,20,2b"
container: ubuntu:22.04
os: ubuntu-latest
install: clang-14
- toolset: clang
compiler: clang++-15
cxxstd: "11,14,17,20,2b"
container: ubuntu:22.04
os: ubuntu-latest
install: clang-15
- toolset: clang
compiler: clang++-16
cxxstd: "11,14,17,20,2b"
container: ubuntu:24.04
os: ubuntu-latest
install: clang-16
- toolset: clang
compiler: clang++-17
cxxstd: "11,14,17,20,2b"
container: ubuntu:24.04
os: ubuntu-latest
install: clang-17
- toolset: clang
compiler: clang++-18
cxxstd: "11,14,17,20,2b"
container: ubuntu:24.04
os: ubuntu-latest
install: clang-18
- toolset: clang
compiler: clang++-19
cxxstd: "11,14,17,20,23,2c"
container: ubuntu:24.04
os: ubuntu-latest
install: clang-19
- toolset: clang
compiler: clang++-20
cxxstd: "11,14,17,20,23,2c"
container: ubuntu:25.04
os: ubuntu-latest
install: clang-20
- toolset: clang
cxxstd: "11,14,17,20,2b"
os: macos-13
- toolset: clang
cxxstd: "11,14,17,20,2b"
os: macos-14
- toolset: clang
cxxstd: "11,14,17,20,2b"
os: macos-15
runs-on: ${{matrix.os}}
container:
image: ${{matrix.container}}
volumes:
- /node20217:/node20217:rw,rshared
- ${{ startsWith(matrix.container, 'ubuntu:1') && '/node20217:/__e/node20:ro,rshared' || ' ' }}
defaults:
run:
shell: bash
steps:
- name: Setup container environment
if: matrix.container
run: |
apt-get update
apt-get -y install sudo python3 git g++ curl xz-utils
- name: Install nodejs20glibc2.17
if: ${{ startsWith( matrix.container, 'ubuntu:1' ) }}
run: |
curl -LO https://archives.boost.io/misc/node/node-v20.9.0-linux-x64-glibc-217.tar.xz
tar -xf node-v20.9.0-linux-x64-glibc-217.tar.xz --strip-components 1 -C /node20217
ldd /__e/node20/bin/node
- uses: actions/checkout@v4
- name: Install packages
if: matrix.install
run: |
sudo apt-get update
sudo apt-get -y install ${{matrix.install}}
- name: Setup Boost
run: |
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
LIBRARY=${GITHUB_REPOSITORY#*/}
echo LIBRARY: $LIBRARY
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
echo GITHUB_REF: $GITHUB_REF
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
REF=${REF#refs/heads/}
echo REF: $REF
BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true
echo BOOST_BRANCH: $BOOST_BRANCH
cd ..
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
git submodule update --init tools/boostdep
python3 tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
./bootstrap.sh
./b2 -d0 headers
- name: Create user-config.jam
if: matrix.compiler
run: |
echo "using ${{matrix.toolset}} : : ${{matrix.compiler}} ;" > ~/user-config.jam
- name: Run tests
run: |
cd ../boost-root
./b2 -j3 libs/$LIBRARY/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} ${ADDRMD:+address-model=$ADDRMD} variant=debug,release
windows:
strategy:
fail-fast: false
matrix:
include:
- toolset: msvc-14.3
cxxstd: "14,17,20,latest"
addrmd: 32,64
os: windows-2022
- toolset: clang-win
cxxstd: "14,17,20,latest"
addrmd: 32,64
os: windows-2022
- toolset: gcc
cxxstd: "11,14,17,2a"
addrmd: 64
os: windows-2022
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v4
- name: Setup Boost
shell: cmd
run: |
echo GITHUB_REPOSITORY: %GITHUB_REPOSITORY%
for /f %%i in ("%GITHUB_REPOSITORY%") do set LIBRARY=%%~nxi
echo LIBRARY: %LIBRARY%
echo LIBRARY=%LIBRARY%>>%GITHUB_ENV%
echo GITHUB_BASE_REF: %GITHUB_BASE_REF%
echo GITHUB_REF: %GITHUB_REF%
if "%GITHUB_BASE_REF%" == "" set GITHUB_BASE_REF=%GITHUB_REF%
set BOOST_BRANCH=develop
for /f %%i in ("%GITHUB_BASE_REF%") do if "%%~nxi" == "master" set BOOST_BRANCH=master
echo BOOST_BRANCH: %BOOST_BRANCH%
cd ..
git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
xcopy /s /e /q %GITHUB_WORKSPACE% libs\%LIBRARY%\
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" %LIBRARY%
cmd /c bootstrap
b2 -d0 headers
- name: Run tests
shell: cmd
run: |
cd ../boost-root
b2 -j3 libs/%LIBRARY%/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release embed-manifest-via=linker
posix-cmake-subdir:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-22.04
- os: ubuntu-24.04
- os: macos-13
- os: macos-14
- os: macos-15
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v4
- name: Install packages
if: matrix.install
run: sudo apt-get -y install ${{matrix.install}}
- name: Setup Boost
run: |
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
LIBRARY=${GITHUB_REPOSITORY#*/}
echo LIBRARY: $LIBRARY
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
echo GITHUB_REF: $GITHUB_REF
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
REF=${REF#refs/heads/}
echo REF: $REF
BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true
echo BOOST_BRANCH: $BOOST_BRANCH
cd ..
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
- name: Use library with add_subdirectory
run: |
cd ../boost-root/libs/$LIBRARY/test/cmake_subdir_test
mkdir __build__ && cd __build__
cmake ..
cmake --build .
ctest --output-on-failure --no-tests=error
posix-cmake-install:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-22.04
- os: ubuntu-24.04
- os: macos-13
- os: macos-14
- os: macos-15
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v4
- name: Install packages
if: matrix.install
run: sudo apt-get -y install ${{matrix.install}}
- name: Setup Boost
run: |
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
LIBRARY=${GITHUB_REPOSITORY#*/}
echo LIBRARY: $LIBRARY
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
echo GITHUB_REF: $GITHUB_REF
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
REF=${REF#refs/heads/}
echo REF: $REF
BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true
echo BOOST_BRANCH: $BOOST_BRANCH
cd ..
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
- name: Configure
run: |
cd ../boost-root
mkdir __build__ && cd __build__
cmake -DBOOST_INCLUDE_LIBRARIES=$LIBRARY -DCMAKE_INSTALL_PREFIX=~/.local ..
- name: Install
run: |
cd ../boost-root/__build__
cmake --build . --target install
- name: Use the installed library
run: |
cd ../boost-root/libs/$LIBRARY/test/cmake_install_test && mkdir __build__ && cd __build__
cmake -DCMAKE_INSTALL_PREFIX=~/.local ..
cmake --build .
ctest --output-on-failure --no-tests=error
posix-cmake-test:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-22.04
- os: ubuntu-24.04
- os: macos-13
- os: macos-14
- os: macos-15
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v4
- name: Install packages
if: matrix.install
run: sudo apt-get -y install ${{matrix.install}}
- name: Setup Boost
run: |
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
LIBRARY=${GITHUB_REPOSITORY#*/}
echo LIBRARY: $LIBRARY
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
echo GITHUB_REF: $GITHUB_REF
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
REF=${REF#refs/heads/}
echo REF: $REF
BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true
echo BOOST_BRANCH: $BOOST_BRANCH
cd ..
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
- name: Configure
run: |
cd ../boost-root
mkdir __build__ && cd __build__
cmake -DBOOST_INCLUDE_LIBRARIES=$LIBRARY -DBUILD_TESTING=ON ..
- name: Build tests
run: |
cd ../boost-root/__build__
cmake --build . --target tests
- name: Run tests
run: |
cd ../boost-root/__build__
ctest --output-on-failure --no-tests=error
windows-cmake-subdir:
strategy:
fail-fast: false
matrix:
include:
- os: windows-latest
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v4
- name: Setup Boost
shell: cmd
run: |
echo GITHUB_REPOSITORY: %GITHUB_REPOSITORY%
for /f %%i in ("%GITHUB_REPOSITORY%") do set LIBRARY=%%~nxi
echo LIBRARY: %LIBRARY%
echo LIBRARY=%LIBRARY%>>%GITHUB_ENV%
echo GITHUB_BASE_REF: %GITHUB_BASE_REF%
echo GITHUB_REF: %GITHUB_REF%
if "%GITHUB_BASE_REF%" == "" set GITHUB_BASE_REF=%GITHUB_REF%
set BOOST_BRANCH=develop
for /f %%i in ("%GITHUB_BASE_REF%") do if "%%~nxi" == "master" set BOOST_BRANCH=master
echo BOOST_BRANCH: %BOOST_BRANCH%
cd ..
git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
xcopy /s /e /q %GITHUB_WORKSPACE% libs\%LIBRARY%\
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" %LIBRARY%
- name: Use library with add_subdirectory (Debug)
shell: cmd
run: |
cd ../boost-root/libs/%LIBRARY%/test/cmake_subdir_test
mkdir __build__ && cd __build__
cmake ..
cmake --build . --config Debug
ctest --output-on-failure --no-tests=error -C Debug
- name: Use library with add_subdirectory (Release)
shell: cmd
run: |
cd ../boost-root/libs/%LIBRARY%/test/cmake_subdir_test/__build__
cmake --build . --config Release
ctest --output-on-failure --no-tests=error -C Release
windows-cmake-install:
strategy:
fail-fast: false
matrix:
include:
- os: windows-latest
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v4
- name: Setup Boost
shell: cmd
run: |
echo GITHUB_REPOSITORY: %GITHUB_REPOSITORY%
for /f %%i in ("%GITHUB_REPOSITORY%") do set LIBRARY=%%~nxi
echo LIBRARY: %LIBRARY%
echo LIBRARY=%LIBRARY%>>%GITHUB_ENV%
echo GITHUB_BASE_REF: %GITHUB_BASE_REF%
echo GITHUB_REF: %GITHUB_REF%
if "%GITHUB_BASE_REF%" == "" set GITHUB_BASE_REF=%GITHUB_REF%
set BOOST_BRANCH=develop
for /f %%i in ("%GITHUB_BASE_REF%") do if "%%~nxi" == "master" set BOOST_BRANCH=master
echo BOOST_BRANCH: %BOOST_BRANCH%
cd ..
git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
xcopy /s /e /q %GITHUB_WORKSPACE% libs\%LIBRARY%\
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" %LIBRARY%
- name: Configure
shell: cmd
run: |
cd ../boost-root
mkdir __build__ && cd __build__
cmake -DBOOST_INCLUDE_LIBRARIES=%LIBRARY% -DCMAKE_INSTALL_PREFIX=C:/cmake-prefix ..
- name: Install (Debug)
shell: cmd
run: |
cd ../boost-root/__build__
cmake --build . --target install --config Debug
- name: Install (Release)
shell: cmd
run: |
cd ../boost-root/__build__
cmake --build . --target install --config Release
- name: Use the installed library (Debug)
shell: cmd
run: |
cd ../boost-root/libs/%LIBRARY%/test/cmake_install_test && mkdir __build__ && cd __build__
cmake -DCMAKE_INSTALL_PREFIX=C:/cmake-prefix ..
cmake --build . --config Debug
ctest --output-on-failure --no-tests=error -C Debug
- name: Use the installed library (Release)
shell: cmd
run: |
cd ../boost-root/libs/%LIBRARY%/test/cmake_install_test/__build__
cmake --build . --config Release
ctest --output-on-failure --no-tests=error -C Release
windows-cmake-test:
strategy:
fail-fast: false
matrix:
include:
- os: windows-latest
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v4
- name: Setup Boost
shell: cmd
run: |
echo GITHUB_REPOSITORY: %GITHUB_REPOSITORY%
for /f %%i in ("%GITHUB_REPOSITORY%") do set LIBRARY=%%~nxi
echo LIBRARY: %LIBRARY%
echo LIBRARY=%LIBRARY%>>%GITHUB_ENV%
echo GITHUB_BASE_REF: %GITHUB_BASE_REF%
echo GITHUB_REF: %GITHUB_REF%
if "%GITHUB_BASE_REF%" == "" set GITHUB_BASE_REF=%GITHUB_REF%
set BOOST_BRANCH=develop
for /f %%i in ("%GITHUB_BASE_REF%") do if "%%~nxi" == "master" set BOOST_BRANCH=master
echo BOOST_BRANCH: %BOOST_BRANCH%
cd ..
git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
xcopy /s /e /q %GITHUB_WORKSPACE% libs\%LIBRARY%\
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" %LIBRARY%
- name: Configure
shell: cmd
run: |
cd ../boost-root
mkdir __build__ && cd __build__
cmake -DBOOST_INCLUDE_LIBRARIES=%LIBRARY% -DBUILD_TESTING=ON ..
- name: Build tests (Debug)
shell: cmd
run: |
cd ../boost-root/__build__
cmake --build . --target tests --config Debug
- name: Run tests (Debug)
shell: cmd
run: |
cd ../boost-root/__build__
ctest --output-on-failure --no-tests=error -C Debug
- name: Build tests (Release)
shell: cmd
run: |
cd ../boost-root/__build__
cmake --build . --target tests --config Release
- name: Run tests (Release)
shell: cmd
run: |
cd ../boost-root/__build__
ctest --output-on-failure --no-tests=error -C Release

View File

@@ -1,10 +1,10 @@
# Copyright 2016, 2017, 2018 Peter Dimov
# Copyright 2016-2020 Peter Dimov
# 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)
language: cpp
sudo: false
dist: xenial
branches:
only:
@@ -23,12 +23,47 @@ matrix:
include:
- os: linux
dist: trusty
compiler: g++
env: TOOLSET=gcc COMPILER=g++ CXXSTD=03,11 VARIANT=debug,release
env: TOOLSET=gcc CXXSTD=03,11
- os: linux
dist: xenial
compiler: g++
env: TOOLSET=gcc CXXSTD=03,11,14
- os: linux
dist: bionic
compiler: g++
env: TOOLSET=gcc CXXSTD=03,11,14,17
- os: linux
dist: focal
compiler: g++
env: TOOLSET=gcc CXXSTD=03,11,14,17
- os: linux
arch: arm64
compiler: g++
env: TOOLSET=gcc CXXSTD=03,11,14
- os: linux
arch: ppc64le
compiler: g++
env: TOOLSET=gcc CXXSTD=03,11,14
- os: linux
arch: s390x
compiler: g++
env: TOOLSET=gcc CXXSTD=03,11,14
- os: freebsd
compiler: clang++
env: TOOLSET=clang CXXSTD=03,11,14,17,2a
- os: linux
compiler: g++-4.4
env: TOOLSET=gcc COMPILER=g++-4.4 CXXSTD=98,0x
env: TOOLSET=gcc CXXSTD=98,0x
addons:
apt:
packages:
@@ -38,7 +73,7 @@ matrix:
- os: linux
compiler: g++-4.6
env: TOOLSET=gcc COMPILER=g++-4.6 CXXSTD=03,0x
env: TOOLSET=gcc CXXSTD=03,0x
addons:
apt:
packages:
@@ -47,194 +82,59 @@ matrix:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-4.7
env: TOOLSET=gcc COMPILER=g++-4.7 CXXSTD=03,11
dist: bionic
compiler: g++-10
env: UBSAN=1 TOOLSET=gcc CXXSTD=03,11,14 UBSAN_OPTIONS=print_stacktrace=1 LINKFLAGS=-fuse-ld=gold
addons:
apt:
packages:
- g++-4.7
- g++-10
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-4.8
env: TOOLSET=gcc COMPILER=g++-4.8 CXXSTD=03,11
dist: bionic
compiler: g++-10
env: UBSAN=1 TOOLSET=gcc CXXSTD=17,2a UBSAN_OPTIONS=print_stacktrace=1 LINKFLAGS=-fuse-ld=gold
addons:
apt:
packages:
- g++-4.8
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-4.9
env: TOOLSET=gcc COMPILER=g++-4.9 CXXSTD=03,11
addons:
apt:
packages:
- g++-4.9
- g++-10
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-5
env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- g++-5
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-6
env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- g++-6
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-7
env: TOOLSET=gcc COMPILER=g++-7 CXXSTD=03,11,14,17 VARIANT=release
addons:
apt:
packages:
- g++-7
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-7
env: UBSAN=1 TOOLSET=gcc COMPILER=g++-7 CXXSTD=03,11,14,17 UBSAN_OPTIONS=print_stacktrace=1
addons:
apt:
packages:
- g++-7
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11 VARIANT=debug,release
- os: linux
dist: trusty
compiler: /usr/bin/clang++
env: TOOLSET=clang COMPILER=/usr/bin/clang++ CXXSTD=03,11
env: TOOLSET=clang COMMENT=clang-3.3 CXXSTD=03,11
addons:
apt:
packages:
- clang-3.3
- os: linux
dist: trusty
compiler: /usr/bin/clang++
env: TOOLSET=clang COMPILER=/usr/bin/clang++ CXXSTD=03,11
env: TOOLSET=clang COMMENT=clang-3.4 CXXSTD=03,11
addons:
apt:
packages:
- clang-3.4
- os: linux
compiler: clang++-3.5
env: TOOLSET=clang COMPILER=clang++-3.5 CXXSTD=03,11,14,1z
compiler: clang++-11
env: UBSAN=1 TOOLSET=clang CXXSTD=03,11,14,17,2a UBSAN_OPTIONS=print_stacktrace=1
addons:
apt:
packages:
- clang-3.5
- libstdc++-4.9-dev
- clang-11
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.5
- os: linux
compiler: clang++-3.6
env: TOOLSET=clang COMPILER=clang++-3.6 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-3.6
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.6
- os: linux
compiler: clang++-3.7
env: TOOLSET=clang COMPILER=clang++-3.7 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-3.7
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.7
- os: linux
compiler: clang++-3.8
env: TOOLSET=clang COMPILER=clang++-3.8 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-3.8
- libstdc++-4.9-dev
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.8
- os: linux
compiler: clang++-3.9
env: TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-3.9
- libstdc++-4.9-dev
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.9
- os: linux
compiler: clang++-4.0
env: TOOLSET=clang COMPILER=clang++-4.0 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-4.0
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-4.0
- os: linux
compiler: clang++-5.0
env: TOOLSET=clang COMPILER=clang++-5.0 CXXSTD=03,11,14,1z VARIANT=release
addons:
apt:
packages:
- clang-5.0
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-5.0
- os: linux
compiler: clang++-5.0
env: UBSAN=1 TOOLSET=clang COMPILER=clang++-5.0 CXXSTD=03,11,14,1z UBSAN_OPTIONS=print_stacktrace=1
addons:
apt:
packages:
- clang-5.0
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-5.0
- os: linux
compiler: clang++-libc++
env: TOOLSET=clang COMPILER=clang++-libc++ CXXSTD=03,11,14,1z VARIANT=release
addons:
apt:
packages:
- libc++-dev
- sourceline: 'deb https://apt.llvm.org/xenial/ llvm-toolchain-xenial-11 main'
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
- os: linux
dist: trusty
compiler: clang++-libc++
env: UBSAN=1 TOOLSET=clang COMPILER=clang++-libc++ CXXSTD=03,11,14,1z UBSAN_OPTIONS=print_stacktrace=1
addons:
@@ -242,9 +142,47 @@ matrix:
packages:
- libc++-dev
- os: linux
dist: bionic
compiler: clang++-libc++
env: UBSAN=1 TOOLSET=clang COMPILER=clang++-libc++ CXXSTD=03,11,14,17,2a UBSAN_OPTIONS=print_stacktrace=1
addons:
apt:
packages:
- libc++-dev
- os: osx
compiler: clang++
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z
env: UBSAN=1 TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z UBSAN_OPTIONS=print_stacktrace=1
- os: linux
env: CMAKE_TEST=1
script:
- mkdir __build__ && cd __build__
- cmake -DBOOST_ENABLE_CMAKE=1 -DBoost_VERBOSE=1 -DBOOST_INCLUDE_LIBRARIES=smart_ptr -DBUILD_TESTING=ON ..
- cmake --build . --target tests -- -k
- ctest --output-on-failure -R boost_smart_ptr
- os: linux
compiler: g++
env: CMAKE_SUBDIR_TEST=1
script:
- cd libs/smart_ptr/test/cmake_subdir_test && mkdir __build__ && cd __build__
- cmake ..
- cmake --build .
- cmake --build . --target check
- os: linux
env: CMAKE_INSTALL_TEST=1
script:
- pip install --user cmake
- mkdir __build__ && cd __build__
- cmake -DBOOST_ENABLE_CMAKE=1 -DBoost_VERBOSE=1 -DBOOST_INCLUDE_LIBRARIES=smart_ptr -DBUILD_TESTING=OFF -DCMAKE_INSTALL_PREFIX=~/.local ..
- cmake --build . --target install
- cd ../libs/smart_ptr/test/cmake_install_test && mkdir __build__ && cd __build__
- cmake -DCMAKE_INSTALL_PREFIX=~/.local ..
- cmake --build .
- cmake --build . --target check
install:
- BOOST_BRANCH=develop && [ "$TRAVIS_BRANCH" == "master" ] && BOOST_BRANCH=master || true
@@ -265,15 +203,20 @@ install:
- git submodule init libs/detail
- git submodule init libs/integer
- git submodule init tools/build
- git submodule update
- git submodule init libs/headers
- git submodule init tools/boost_install
- git submodule init tools/cmake
- git submodule init libs/preprocessor
- git submodule init libs/bind
- git submodule update # no --jobs 3 on non-amd64
- cp -r $TRAVIS_BUILD_DIR/* libs/smart_ptr
- ./bootstrap.sh
- ./b2 headers
script:
- |-
echo "using $TOOLSET : : $COMPILER ;" > ~/user-config.jam
- ./b2 -j3 libs/smart_ptr/test toolset=$TOOLSET cxxstd=$CXXSTD ${VARIANT:+variant=$VARIANT} ${UBSAN:+cxxflags=-fsanitize=undefined cxxflags=-fno-sanitize-recover=undefined linkflags=-fsanitize=undefined debug-symbols=on}
echo "using $TOOLSET : : $TRAVIS_COMPILER ;" > ~/user-config.jam
- ./b2 -j3 libs/smart_ptr/test toolset=$TOOLSET cxxstd=$CXXSTD variant=debug,release ${UBSAN:+cxxflags=-fsanitize=undefined cxxflags=-fno-sanitize-recover=undefined linkflags=-fsanitize=undefined debug-symbols=on} ${LINKFLAGS:+linkflags=$LINKFLAGS}
notifications:
email:

29
CMakeLists.txt Normal file
View File

@@ -0,0 +1,29 @@
# Generated by `boostdep --cmake smart_ptr`
# Copyright 2020, 2021 Peter Dimov
# Distributed under the Boost Software License, Version 1.0.
# https://www.boost.org/LICENSE_1_0.txt
cmake_minimum_required(VERSION 3.8...3.20)
project(boost_smart_ptr VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX)
add_library(boost_smart_ptr INTERFACE)
add_library(Boost::smart_ptr ALIAS boost_smart_ptr)
target_include_directories(boost_smart_ptr INTERFACE include)
target_link_libraries(boost_smart_ptr
INTERFACE
Boost::assert
Boost::config
Boost::core
Boost::throw_exception
)
target_compile_features(boost_smart_ptr INTERFACE cxx_std_11)
if(BUILD_TESTING AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/CMakeLists.txt")
add_subdirectory(test)
endif()

View File

@@ -1,4 +1,4 @@
# Copyright 2016, 2017 Peter Dimov
# Copyright 2016-2019 Peter Dimov
# 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)
@@ -14,41 +14,66 @@ branches:
environment:
matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
TOOLSET: msvc-9.0,msvc-10.0,msvc-11.0,msvc-12.0
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
TOOLSET: msvc-14.0
ADDRMD: 32,64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
TOOLSET: msvc-14.1
CXXSTD: 14,17
ADDRMD: 32,64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
TOOLSET: msvc-14.2
CXXSTD: 14
ADDRMD: 32,64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
TOOLSET: msvc-14.2
CXXSTD: 17
ADDRMD: 32,64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
TOOLSET: msvc-14.2
CXXSTD: 20
ADDRMD: 32,64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
TOOLSET: msvc-14.2
CXXSTD: latest
ADDRMD: 32,64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
TOOLSET: clang-win
CXXSTD: 14,17,latest
ADDRMD: 64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
ADDPATH: C:\cygwin\bin;
TOOLSET: gcc
CXXSTD: 11,14,1z
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
ADDPATH: C:\cygwin64\bin;
TOOLSET: gcc
CXXSTD: 11,14,1z
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
ADDPATH: C:\mingw-w64\i686-8.1.0-posix-dwarf-rt_v6-rev0\mingw32\bin;
TOOLSET: gcc
CXXSTD: 11,14,17
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
ADDPATH: C:\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\bin;
TOOLSET: gcc
CXXSTD: 11,14,17
install:
- set BOOST_BRANCH=develop
- if "%APPVEYOR_REPO_BRANCH%" == "master" set BOOST_BRANCH=master
- cd ..
- git clone -b %BOOST_BRANCH% https://github.com/boostorg/boost.git boost-root
- git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
- cd boost-root
- git submodule init libs/align
- git submodule init libs/assert
- git submodule init libs/atomic
- git submodule init libs/config
- git submodule init libs/container_hash
- git submodule init libs/core
- git submodule init libs/move
- git submodule init libs/predef
- git submodule init libs/static_assert
- git submodule init libs/throw_exception
- git submodule init libs/type_traits
- git submodule init libs/detail
- git submodule init libs/integer
- git submodule init tools/build
- git submodule update
- xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\smart_ptr
- xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\smart_ptr\
- git submodule update --init tools/boostdep
- python tools/boostdep/depinst/depinst.py smart_ptr
- cmd /c bootstrap
- b2 -d0 headers
build: off
test_script:
- PATH=%ADDPATH%%PATH%
- if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
- b2 -j3 libs/smart_ptr/test toolset=%TOOLSET% %CXXSTD% variant=debug,release
- if not "%ADDRMD%" == "" set ADDRMD=address-model=%ADDRMD%
- b2 -j3 libs/smart_ptr/test toolset=%TOOLSET% %CXXSTD% %ADDRMD% variant=debug,release embed-manifest-via=linker

23
build.jam Normal file
View File

@@ -0,0 +1,23 @@
# Copyright 2023-2024 René Ferdinand Rivera Morell
# Copyright 2024 Peter Dimov
# Distributed under the Boost Software License, Version 1.0.
# https://www.boost.org/LICENSE_1_0.txt
require-b2 5.2 ;
constant boost_dependencies :
/boost/assert//boost_assert
/boost/config//boost_config
/boost/core//boost_core
/boost/throw_exception//boost_throw_exception
;
project /boost/smart_ptr ;
explicit
[ alias boost_smart_ptr : : : : <include>include <library>$(boost_dependencies) ]
[ alias all : boost_smart_ptr test ]
;
call-if : boost-library smart_ptr
;

View File

@@ -5,8 +5,6 @@
# See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt
project doc/smart_ptr ;
import asciidoctor ;
html smart_ptr.html : smart_ptr.adoc ;

View File

@@ -1,6 +1,7 @@
<style>
*:not(pre)>code { background: none; color: #600000; }
:not(pre):not([class^=L])>code { background: none; color: #600000; }
table tr.even, table tr.alt, table tr:nth-of-type(even) { background: none; }
</style>

View File

@@ -14,38 +14,32 @@ Greg Colvin, Beman Dawes, Peter Dimov, Glen Fernandes
:idprefix:
:listing-caption: Code Example
:docinfo: private-footer
:source-highlighter: rouge
:source-language: c++
:leveloffset: +1
include::smart_ptr/introduction.adoc[]
include::smart_ptr/changelog.adoc[]
include::smart_ptr/scoped_ptr.adoc[]
include::smart_ptr/scoped_array.adoc[]
include::smart_ptr/shared_ptr.adoc[]
include::smart_ptr/weak_ptr.adoc[]
include::smart_ptr/make_shared.adoc[]
include::smart_ptr/enable_shared_from_this.adoc[]
include::smart_ptr/enable_shared_from.adoc[]
include::smart_ptr/make_unique.adoc[]
include::smart_ptr/allocate_unique.adoc[]
include::smart_ptr/intrusive_ptr.adoc[]
include::smart_ptr/intrusive_ref_counter.adoc[]
include::smart_ptr/local_shared_ptr.adoc[]
include::smart_ptr/make_local_shared.adoc[]
include::smart_ptr/pointer_cast.adoc[]
include::smart_ptr/pointer_to_other.adoc[]
include::smart_ptr/atomic_shared_ptr.adoc[]
include::smart_ptr/owner_less.adoc[]
include::smart_ptr/owner_equal_to.adoc[]
include::smart_ptr/owner_hash.adoc[]
// appendix
include::smart_ptr/techniques.adoc[]
@@ -67,7 +61,7 @@ This documentation is
* Copyright 1999 Greg Colvin
* Copyright 1999 Beman Dawes
* Copyright 2002 Darin Adler
* Copyright 2003-2017 Peter Dimov
* Copyright 2003-2020 Peter Dimov
* Copyright 2005, 2006 Ion Gaztañaga
* Copyright 2008 Frank Mori Hess
* Copyright 2012-2017 Glen Fernandes

View File

@@ -0,0 +1,335 @@
////
Copyright 2019-2021 Glen Joseph Fernandes (glenjofe@gmail.com)
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
////
[#allocate_unique]
# allocate_unique: Creating unique_ptr
:toc:
:toc-title:
:idprefix: allocate_unique_
## Description
The `allocate_unique` family of function templates provide convenient and safe
ways to obtain a `std::unique_ptr` that manages a new object created using an
allocator.
## Rationale
The {cpp}14 standard introduced `std::make_unique` which used operator `new` to
create new objects. However, there is no convenient facility in the standard
library to use an allocator for the creation of the objects managed by
`std::unique_ptr`. Users writing allocator aware code have often requested an
`allocate_unique` factory function. This function is to `std::unique_ptr` what
`std::allocate_shared` is to `std::shared_ptr`.
## Synopsis
`allocate_unique` is defined in `<boost/smart_ptr/allocate_unique.hpp>`.
[subs=+quotes]
```
namespace boost {
template<class T, class A>
class alloc_deleter;
template<class T, class A>
using alloc_noinit_deleter = alloc_deleter<T, noinit_adaptor<A>>;
`// T is not an array`
template<class T, class A, class... Args>
std::unique_ptr<T, alloc_deleter<T, A>>
allocate_unique(const A& a, Args&&... args);
`// T is not an array`
template<class T, class A>
std::unique_ptr<T, alloc_deleter<T, A>>
allocate_unique(const A& a, type_identity_t<T>&& v);
`// T is an array of unknown bounds`
template<class T, class A>
std::unique_ptr<T, alloc_deleter<T, A>>
allocate_unique(const A& a, std::size_t n);
`// T is an array of known bounds`
template<class T, class A>
std::unique_ptr<remove_extent_t<T>[], alloc_deleter<T, A>>
allocate_unique(const A& a);
`// T is an array of unknown bounds`
template<class T, class A>
std::unique_ptr<T, alloc_deleter<T, A>>
allocate_unique(const A& a, std::size_t n, const remove_extent_t<T>& v);
`// T is an array of known bounds`
template<class T, class A>
std::unique_ptr<remove_extent_t<T>[], alloc_deleter<T, A>>
allocate_unique(const A& a, const remove_extent_t<T>& v);
`// T is not an array`
template<class T, class A>
std::unique_ptr<T, alloc_noinit_deleter<T, A>>
allocate_unique_noinit(const A& a);
`// T is an array of unknown bounds`
template<class T, class A>
std::unique_ptr<T, alloc_noinit_deleter<T, A>>
allocate_unique_noinit(const A& a, std::size_t n);
`// T is an array of known bounds`
template<class T, class A>
std::unique_ptr<remove_extent_t<T>[], alloc_noinit_deleter<T, A>>
allocate_unique_noinit(const A& a);
template<class T, class U, class A>
allocator_pointer_t<allocator_rebind_t<A, remove_cv_t<remove_extent_t<T>>>>
get_allocator_pointer(const std::unique_ptr<T,
alloc_deleter<U, A>>& p) noexcept;
}
```
## Common Requirements
The common requirements that apply to all `allocate_unique` and
`allocate_unique_noinit` overloads, unless specified otherwise, are described
below.
Requires:: `A` shall be an _allocator_. The copy constructor and destructor
of `A` shall not throw exceptions.
Effects:: Allocates memory for an object of type `T` or `n` objects of `U`
(if `T` is an array type of the form `U[]` and `n` is determined by
arguments, as specified by the concrete overload). The object is initialized
from arguments as specified by the concrete overload. Uses a rebound copy of
`a` (for an unspecified `value_type`) to allocate memory. If an exception is
thrown, the functions have no effect.
Returns:: A `std::unique_ptr` instance that stores and owns the address of the
newly constructed object.
Postconditions:: `r.get() != 0`, where `r` is the return value.
Throws:: An exception thrown from `A::allocate`, or from the initialization of
the object.
Remarks::
* When an object of an array type is specified to be initialized to a value of
the same type `v`, this shall be interpreted to mean that each array element
of the object is initialized to the corresponding element from `v`.
* 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.
* When a (sub)object of non-array type `U` is specified to be initialized to a
value `v`, or constructed from `args\...`, `allocate_unique` shall perform this
initialization via the expression
`std::allocator_traits<A2>::construct(a2, p, expr)` (where `_expr_` is `v` or
`std::forward<Args>(args)\...)` respectively), `p` points to storage suitable
to hold an object of type `U`, and `a2` of type `A2` is a potentially rebound
copy of `a`.
* When a (sub)object of non-array type `U` is specified to be
default-initialized, `allocate_unique_noinit` shall perform this initialization
via the expression `::new(p) U`, where `p` has type `void*` and points to
storage suitable to hold an object of type `U`.
* When a (sub)object of non-array type `U` is specified to be
value-initialized, `allocate_unique` shall perform this initialization via the
expression `std::allocator_traits<A2>::construct(a2, p)`, where `p` points to
storage suitable to hold an object of type `U` and `a2` of type `A2` is a
potentially rebound copy of `a`.
* Array elements are initialized in ascending order of their addresses.
* 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.
## Free Functions
```
template<class T, class A, class... Args>
std::unique_ptr<T, alloc_deleter<T, A>>
allocate_unique(const A& a, Args&&... args);
```
[none]
* {blank}
+
Constraints:: `T` is not an array.
Returns:: A `std::unique_ptr` to an object of type `T`, constructed from
`args\...`.
Examples::
* `auto p = allocate_unique<int>(a);`
* `auto p = allocate_unique<std::vector<int>>(a, 16, 1);`
```
template<class T, class A>
std::unique_ptr<T, alloc_deleter<T, A>>
allocate_unique(const A& a, type_identity_t<T>&& v);
```
[none]
* {blank}
+
Constraints:: `T` is not an array.
Returns:: A `std::unique_ptr` to an object of type `T`, constructed from `v`.
Example:: `auto p = allocate_unique<std::vector<int>>(a, {1, 2});`
```
template<class T, class A>
std::unique_ptr<T, alloc_deleter<T, A>>
allocate_unique(const A& a, std::size_t n);
```
[none]
* {blank}
+
Constraints:: `T` is an array of unknown bounds.
Returns:: A `std::unique_ptr` to a sequence of `n` value-initialized objects of
type `remove_extent_t<T>`.
Examples::
* `auto p = allocate_unique<double[]>(a, 1024);`
* `auto p = allocate_unique<double[][2][2]>(a, 6);`
```
template<class T, class A>
std::unique_ptr<remove_extent_t<T>[], alloc_deleter<T, A>>
allocate_unique(const A& a);
```
[none]
* {blank}
+
Constraints:: `T` is an array of known bounds.
Returns:: A `std::unique_ptr` to a sequence of `extent_v<T>` value-initialized
objects of type `remove_extent_t<T>`.
Examples::
* `auto p = allocate_unique<double[1024]>(a);`
* `auto p = allocate_unique<double[6][2][2]>(a);`
```
template<class T, class A>
std::unique_ptr<T, alloc_deleter<T, A>>
allocate_unique(const A& a, std::size_t n, const remove_extent_t<T>& v);
```
[none]
* {blank}
+
Constraints:: `T` is an array of unknown bounds.
Returns:: A `std::unique_ptr` to a sequence of `n` objects of type
`remove_extent_t<T>`, each initialized to `v`.
Examples::
* `auto p = allocate_unique<double[]>(a, 1024, 1.0);`
* `auto p = allocate_unique<double[][2]>(a, 6, {1.0, 0.0});`
* `auto p = allocate_unique<std::vector<int>[]>(a, 4, {1, 2});`
```
template<class T, class A>
std::unique_ptr<remove_extent_t<T>[], alloc_deleter<T, A>>
allocate_unique(const A& a, const remove_extent_t<T>& v);
```
[none]
* {blank}
+
Constraints:: `T` is an array of known bounds.
Returns:: A `std::unique_ptr` to a sequence of `extent_v<T>` objects of type
`remove_extent_t<T>`, each initialized to `v`.
Examples::
* `auto p = allocate_unique<double[1024]>(a, 1.0);`
* `auto p = allocate_unique<double[6][2]>(a, {1.0, 0.0});`
* `auto p = allocate_unique<std::vector<int>[4]>(a, {1, 2});`
```
template<class T, class A>
std::unique_ptr<T, alloc_noinit_deleter<T, A>>
allocate_unique_noinit(const A& a);
```
[none]
* {blank}
+
Constraints:: `T` is not an array.
Returns:: A `std::unique_ptr` to a default-initialized object of type `T`.
Example:: `auto p = allocate_unique_noinit<double>(a);`
```
template<class T, class A>
std::unique_ptr<T, alloc_noinit_deleter<T, A>>
allocate_unique_noinit(const A& a, std::size_t n);
```
[none]
* {blank}
+
Constraints:: `T` is an array of unknown bounds.
Returns:: A `std::unique_ptr` to a sequence of `n` default-initialized objects
of type `remove_extent_t<T>`.
Example:: `auto p = allocate_unique_noinit<double[]>(a, 1024);`
```
template<class T, class A>
std::unique_ptr<remove_extent_t<T>, alloc_noinit_deleter<T, A>>
allocate_unique_noinit(const A& a);
```
[none]
* {blank}
+
Constraints:: `T` is an array of known bounds.
Returns:: A `std::unique_ptr` to a sequence of `extent_v<T>`
default-initialized objects of type `remove_extent_t<T>`.
Example:: `auto p = allocate_unique_noinit<double[1024]>(a);`
```
template<class T, class U, class A>
allocator_pointer_t<allocator_rebind_t<A, remove_cv_t<remove_extent_t<T>>>>
get_allocator_pointer(const std::unique_ptr<T,
alloc_deleter<U, A>>& p) noexcept;
```
[none]
* {blank}
+
Returns:: The allocator pointer to the allocation.
Example:: `auto r = boost::get_allocator_ptr(p);`
## Deleter
Class template `alloc_deleter` is the deleter used by the `allocate_unique`
functions.
### Synopsis
[subs=+quotes]
```
template<class T, class A>
class alloc_deleter {
public:
using pointer = `unspecified`;
explicit alloc_deleter(const A& a) noexcept;
void operator()(pointer p);
};
```
### Members
[subs=+quotes]
```
using pointer = `unspecified`;
```
[none]
* {blank}
+
A type that satisfies _NullablePointer_.
```
explicit alloc_deleter(const A& a) noexcept;
```
[none]
* {blank}
+
Effects:: Initializes the stored allocator from `a`.
```
void operator()(pointer p);
```
[none]
* {blank}
+
Effects:: Destroys the objects and deallocates the storage referenced by `p`,
using the stored allocator.

View File

@@ -0,0 +1,56 @@
////
Copyright 2019-2025 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
////
[#changelog]
# Revision History
:toc:
:toc-title:
:idprefix: changelog_
## Changes in 1.88.0
* Fix `operator<<` for wide streams (accidentally broken in 1.87.0)
## Changes in 1.87.0
* {cpp}03 is no longer supported, a {cpp}11 compiler is required.
This includes GCC 4.8 or later, and MSVC 14.0 or later.
* The functionality enabled by the macros `BOOST_SP_ENABLE_DEBUG_HOOKS`,
`BOOST_SP_USE_STD_ALLOCATOR`, `BOOST_SP_USE_QUICK_ALLOCATOR`,
`BOOST_AC_USE_SPINLOCK`, `BOOST_AC_USE_PTHREADS`, `BOOST_SP_USE_SPINLOCK`,
and `BOOST_SP_USE_PTHREADS` has been deprecated and support for it
will be removed in a future release.
## Changes in 1.79.0
* Added `get_allocator_pointer`
## Changes in 1.74.0
* Added `owner_equals` to `shared_ptr`, `weak_ptr`, `local_shared_ptr`
* Added `owner_hash_value` to `shared_ptr`, `weak_ptr`
* Added `owner_equal_to`, `owner_hash`
* Added `std::hash` specializations for `shared_ptr`, `local_shared_ptr`
* Added `boost::hash` support to, and `std::hash`, `std::equal_to`
specializations for, `weak_ptr`
## Changes in 1.72.0
* Added `allocate_unique`
## Changes in 1.71.0
* Added aliasing constructors to `weak_ptr`
* Added `weak_ptr<T>::empty()`
* Added `enable_shared_from`, `shared_from`, and `weak_from`
## Changes in 1.65.0
* Added `atomic_shared_ptr`
* Added `local_shared_ptr`, `make_local_shared`

View File

@@ -0,0 +1,89 @@
////
Copyright 2002, 2003, 2015, 2017, 2019 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
////
[#enable_shared_from]
# enable_shared_from
:toc:
:toc-title:
:idprefix: enable_shared_from_
## Description
`enable_shared_from` is used as a base class that allows a `shared_ptr` or a
`weak_ptr` to be obtained given a raw pointer to the object, by using the
functions `shared_from` and `weak_from`.
`enable_shared_from` differs from `enable_shared_from_this<T>` by the fact
that it's not a template, and is its recommended replacement for new code.
## Example
```
#include <boost/smart_ptr/enable_shared_from.hpp>
#include <boost/shared_ptr.hpp>
#include <cassert>
class Y: public boost::enable_shared_from
{
public:
boost::shared_ptr<Y> f()
{
return boost::shared_from( this );
}
};
int main()
{
boost::shared_ptr<Y> p(new Y);
boost::shared_ptr<Y> q = p->f();
assert(p == q);
assert(!(p < q || q < p)); // p and q must share ownership
}
```
## Synopsis
`enable_shared_from` is defined in `<boost/smart_ptr/enable_shared_from.hpp>`.
```
namespace boost {
class enable_shared_from: public enable_shared_from_this<enable_shared_from>
{
};
template<class T> shared_ptr<T> shared_from( T * p );
template<class T> weak_ptr<T> weak_from( T * p ) noexcept;
}
```
## Functions
```
template<class T> shared_ptr<T> shared_from( T * p );
```
[none]
* {blank}
+
Returns:: `shared_ptr<T>( p\->enable_shared_from::shared_from_this(), p )`.
NOTE: Throws `bad_weak_ptr` when `p` is not owned by a `shared_ptr`.
```
template<class T> weak_ptr<T> weak_from( T * p ) noexcept;
```
[none]
* {blank}
+
Returns:: `weak_ptr<T>( p\->enable_shared_from::weak_from_this(), p )`.
NOTE: Unlike `shared_from(this)`, `weak_from(this)` is valid in a destructor
and returns a `weak_ptr` that is `expired()` but still shares ownership
with other `weak_ptr` instances (if any) that refer to the object.

View File

@@ -142,3 +142,7 @@ template<class T> weak_ptr<T const> weak_from_this() const noexcept;
* {blank}
+
Returns:: `weak_this_`.
NOTE: Unlike `shared_from_this()`, `weak_from_this()` is valid in a destructor
and returns a `weak_ptr` that is `expired()` but still shares ownership
with other `weak_ptr` instances (if any) that refer to the object.

View File

@@ -111,3 +111,7 @@ Glen Fernandes rewrote `allocate_shared` and `make_shared` for arrays for a more
Peter Dimov and Glen Fernandes rewrote the documentation in Asciidoc format.
Peter Dimov added `atomic_shared_ptr` and `local_shared_ptr`.
## August 2019
Glen Fernandes implemented `allocate_unique` for scalars and arrays.

View File

@@ -11,7 +11,9 @@ http://www.boost.org/LICENSE_1_0.txt
[#introduction]
# Introduction
:idprefix: intro
:toc:
:toc-title:
:idprefix: intro_
Smart pointers are objects which store pointers to dynamically allocated (heap) objects.
They behave much like built-in {cpp} pointers except that they automatically delete the object
@@ -29,7 +31,7 @@ This library provides six smart pointer class templates:
* `<<scoped_ptr,scoped_ptr>>`, used to contain ownership of a dynamically allocated object to the current scope;
* `<<scoped_array,scoped_array>>`, which provides scoped ownership for a dynamically allocated array;
* `<<shared_ptr,shared_ptr>>`, a versatile tool for managing shared ownership of an object or array;
* `<<weak_ptr,weak_ptr>>`, a non-owning observer to a shared_ptr-managed object that can be promoted temporarily to shared_ptr;
* `<<weak_ptr,weak_ptr>>`, a non-owning observer to a `shared_ptr`-managed object that can be promoted temporarily to `shared_ptr`;
* `<<intrusive_ptr,intrusive_ptr>>`, a pointer to objects with an embedded reference count;
* `<<local_shared_ptr,local_shared_ptr>>`, providing shared ownership within a single thread.
@@ -37,9 +39,11 @@ This library provides six smart pointer class templates:
In addition, the library contains the following supporting utility functions and classes:
* `<<make_shared,make_shared>>`, a factory function for creating objects that returns a `shared_ptr`;
* `<<make_shared,make_shared>>` and `allocate_shared`, factory functions for creating objects that return a `shared_ptr`;
* `<<make_unique,make_unique>>`, a factory function returning `std::unique_ptr`;
* `<<allocate_unique,allocate_unique>>`, a factory function for creating objects using an allocator that returns a `std::unique_ptr`;
* `<<enable_shared_from_this,enable_shared_from_this>>`, a helper base class that enables the acquisition of a `shared_ptr` pointing to `this`;
* `<<enable_shared_from,enable_shared_from>>`, a newer and better replacement for `enable_shared_from_this`;
* `<<pointer_to_other,pointer_to_other>>`, a helper trait for converting one smart pointer type to another;
* `<<pointer_cast,static_pointer_cast>>` and companions, generic smart pointer casts;
* `<<intrusive_ref_counter,intrusive_ref_counter>>`, a helper base class containing a reference count.

View File

@@ -54,12 +54,18 @@ namespace boost {
intrusive_ptr(intrusive_ptr const & r);
template<class Y> intrusive_ptr(intrusive_ptr<Y> const & r);
intrusive_ptr(intrusive_ptr && r);
template<class Y> intrusive_ptr(intrusive_ptr<Y> && r);
~intrusive_ptr();
intrusive_ptr & operator=(intrusive_ptr const & r);
template<class Y> intrusive_ptr & operator=(intrusive_ptr<Y> const & r);
intrusive_ptr & operator=(T * r);
intrusive_ptr & operator=(intrusive_ptr && r);
template<class Y> intrusive_ptr & operator=(intrusive_ptr<Y> && r);
void reset();
void reset(T * r);
void reset(T * r, bool add_ref);
@@ -71,7 +77,7 @@ namespace boost {
explicit operator bool () const noexcept;
void swap(intrusive_ptr & b) noexept;
void swap(intrusive_ptr & b) noexcept;
};
template<class T, class U>
@@ -92,8 +98,8 @@ namespace boost {
template<class T, class U>
bool operator!=(T * a, intrusive_ptr<U> const & b) noexcept;
template<class T, class U>
bool operator<(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b) noexcept;
template<class T>
bool operator<(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b) noexcept;
template<class T> void swap(intrusive_ptr<T> & a, intrusive_ptr<T> & b) noexcept;
@@ -158,6 +164,19 @@ template<class Y> intrusive_ptr(intrusive_ptr<Y> const & r);
Effects:: `T * p = r.get(); if(p != 0) intrusive_ptr_add_ref(p);`.
Postconditions:: `get() == r.get()`.
```
intrusive_ptr(intrusive_ptr && r);
```
```
template<class Y> intrusive_ptr(intrusive_ptr<Y> && r);
```
[none]
* {blank}
+
Postconditions::
`get()` equals the old value of `r.get()`. `r.get() == 0`.
### destructor
```
@@ -167,7 +186,8 @@ Postconditions:: `get() == r.get()`.
[none]
* {blank}
+
Effects:: `if(get() != 0) intrusive_ptr_release(get());`.
Effects::
`if(get() != 0) intrusive_ptr_release(get());`.
### assignment
@@ -187,6 +207,19 @@ intrusive_ptr & operator=(T * r);
Effects:: Equivalent to `intrusive_ptr(r).swap(*this)`.
Returns:: `*this`.
```
intrusive_ptr & operator=(intrusive_ptr && r);
```
```
template<class Y> intrusive_ptr & operator=(intrusive_ptr<Y> && r);
```
[none]
* {blank}
+
Effects:: Equivalent to `intrusive_ptr(std::move(r)).swap(*this)`.
Returns:: `*this`.
### reset
```
@@ -214,7 +247,8 @@ void reset(T * r, bool add_ref);
[none]
* {blank}
+
Effects:: Equivalent to `intrusive_ptr(r, add_ref).swap(*this)`.
Effects::
Equivalent to `intrusive_ptr(r, add_ref).swap(*this)`.
### indirection
@@ -247,7 +281,8 @@ T * get() const noexcept;
[none]
* {blank}
+
Returns:: the stored pointer.
Returns::
the stored pointer.
### detach
@@ -294,7 +329,8 @@ void swap(intrusive_ptr & b) noexcept;
[none]
* {blank}
+
Effects:: Exchanges the contents of the two smart pointers.
Effects::
Exchanges the contents of the two smart pointers.
## Free Functions
@@ -361,8 +397,8 @@ template<class T, class U>
Returns:: `a != b.get()`.
```
template<class T, class U>
bool operator<(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b) noexcept;
template<class T>
bool operator<(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b) noexcept;
```
[none]
@@ -381,7 +417,8 @@ template<class T> void swap(intrusive_ptr<T> & a, intrusive_ptr<T> & b) noexcept
[none]
* {blank}
+
Effects:: Equivalent to `a.swap(b)`.
Effects::
Equivalent to `a.swap(b)`.
### get_pointer
@@ -406,7 +443,8 @@ template<class T, class U>
[none]
* {blank}
+
Returns:: `intrusive_ptr<T>(static_cast<T*>(r.get()))`.
Returns::
`intrusive_ptr<T>(static_cast<T*>(r.get()))`.
### const_pointer_cast
@@ -418,7 +456,8 @@ template<class T, class U>
[none]
* {blank}
+
Returns:: `intrusive_ptr<T>(const_cast<T*>(r.get()))`.
Returns::
`intrusive_ptr<T>(const_cast<T*>(r.get()))`.
### dynamic_pointer_cast
@@ -430,7 +469,8 @@ template<class T, class U>
[none]
* {blank}
+
Returns:: `intrusive_ptr<T>(dynamic_cast<T*>(r.get()))`.
Returns::
`intrusive_ptr<T>(dynamic_cast<T*>(r.get()))`.
### operator<<

View File

@@ -78,12 +78,13 @@ namespace boost {
```
intrusive_ref_counter() noexcept;
```
::
```
intrusive_ref_counter(const intrusive_ref_counter&) noexcept;
```
::
Postconditions::: `use_count() == 0`.
[none]
* {blank}
+
Postconditions:: `use_count() == 0`.
NOTE: The pointer to the constructed object is expected to be passed to
`intrusive_ptr` constructor, assignment operator or `reset` method, which
@@ -94,8 +95,10 @@ would increment the reference counter.
```
~intrusive_ref_counter();
```
::
Effects::: Destroys the counter object.
[none]
* {blank}
+
Effects:: Destroys the counter object.
NOTE: The destructor is protected so that the object can only be destroyed
through the `Derived` class.
@@ -105,16 +108,21 @@ through the `Derived` class.
```
intrusive_ref_counter& operator=(const intrusive_ref_counter& v) noexcept;
```
::
Effects::: Does nothing, reference counter is not modified.
[none]
* {blank}
+
Effects::
Does nothing, reference counter is not modified.
### use_count
```
unsigned int use_count() const noexcept;
```
::
Returns::: The current value of the reference counter.
[none]
* {blank}
+
Returns:: The current value of the reference counter.
NOTE: The returned value may not be actual in multi-threaded applications.
@@ -127,8 +135,11 @@ template<class Derived, class CounterPolicy>
void intrusive_ptr_add_ref(
const intrusive_ref_counter<Derived, CounterPolicy>* p) noexcept;
```
::
Effects::: Increments the reference counter.
[none]
* {blank}
+
Effects::
Increments the reference counter.
### intrusive_ptr_release
@@ -137,6 +148,8 @@ template<class Derived, class CounterPolicy>
void intrusive_ptr_release(
const intrusive_ref_counter<Derived, CounterPolicy>* p) noexcept;
```
::
Effects::: Decrements the reference counter. If the reference counter reaches
[none]
* {blank}
+
Effects:: Decrements the reference counter. If the reference counter reaches
0, calls `delete static_cast<const Derived*>(p)`.

View File

@@ -124,7 +124,7 @@ namespace boost {
template<class Y> void reset(local_shared_ptr<Y> && r, element_type * p) noexcept;
// accessors
T & operator*() const noexcept; // only valid when T is not an array type
T * operator->() const noexcept; // only valid when T is not an array type
@@ -143,12 +143,16 @@ namespace boost {
template<class Y> operator weak_ptr<Y>() const noexcept;
// swap
void swap(local_shared_ptr & b) noexcept;
// owner_before
template<class Y> bool owner_before(local_shared_ptr<Y> const & rhs) const noexcept;
template<class Y> bool owner_before(local_shared_ptr<Y> const & r) const noexcept;
// owner_equals
template<class Y> bool owner_equals(local_shared_ptr<Y> const & r) const noexcept;
};
// comparisons
@@ -459,7 +463,8 @@ template<class Y> void reset(local_shared_ptr<Y> && r, element_type * p) noexcep
[none]
* {blank}
+
Effects:: Equivalent to `local_shared_ptr(std::move(r), p).swap(*this)`.
Effects::
Equivalent to `local_shared_ptr(std::move(r), p).swap(*this)`.
### indirection
```
@@ -497,7 +502,8 @@ element_type * get() const noexcept;
[none]
* {blank}
+
Returns:: The stored pointer.
Returns::
The stored pointer.
### local_use_count
```
@@ -506,7 +512,8 @@ long local_use_count() const noexcept;
[none]
* {blank}
+
Returns:: The number of `local_shared_ptr` objects, `*this` included, that share ownership with `*this`, or 0 when `*this` is empty.
Returns::
The number of `local_shared_ptr` objects, `*this` included, that share ownership with `*this`, or 0 when `*this` is empty.
### conversions
```
@@ -538,16 +545,28 @@ void swap(local_shared_ptr & b) noexcept;
[none]
* {blank}
+
Effects:: Exchanges the contents of the two smart pointers.
Effects::
Exchanges the contents of the two smart pointers.
### owner_before
```
template<class Y> bool owner_before(local_shared_ptr<Y> const & rhs) const noexcept;
template<class Y> bool owner_before(local_shared_ptr<Y> const & r) const noexcept;
```
[none]
* {blank}
+
Effects:: See the description of `operator<`.
Returns::
See the description of `operator<`.
### owner_equals
```
template<class Y> bool owner_equals(local_shared_ptr<Y> const & r) const noexcept;
```
[none]
* {blank}
+
Returns::
`true` if and only if `*this` and `r` share ownership or are both empty.
## Free Functions
@@ -631,7 +650,8 @@ template<class T> void swap(local_shared_ptr<T> & a, local_shared_ptr<T> & b) no
[none]
* {blank}
+
Effects:: Equivalent to `a.swap(b)`.
Effects::
Equivalent to `a.swap(b)`.
### get_pointer
```
@@ -716,4 +736,3 @@ template<class D, class T>
* {blank}
+
Returns:: If `*this` owns a `shared_ptr` instance `p`, `get_deleter<D>( p )`, otherwise 0.

View File

@@ -27,25 +27,25 @@ are analogous to `make_shared` and `allocate_shared` for `shared_ptr`.
[subs=+quotes]
```
namespace boost {
`// only if T is not an array type`
`// T is not an array`
template<class T, class... Args>
local_shared_ptr<T> make_local_shared(Args&&... args);
template<class T, class A, class... Args>
local_shared_ptr<T> allocate_local_shared(const A& a, Args&&... args);
`// only if T is an array type of the form U[]`
`// T is an array of unknown bounds`
template<class T>
local_shared_ptr<T> make_local_shared(std::size_t n);
template<class T, class A>
local_shared_ptr<T> allocate_local_shared(const A& a, std::size_t n);
`// only if T is an array type of the form U[N]`
`// T is an array of known bounds`
template<class T>
local_shared_ptr<T> make_local_shared();
template<class T, class A>
local_shared_ptr<T> allocate_local_shared(const A& a);
`// only if T is an array type of the form U[]`
`// T is an array of unknown bounds`
template<class T>
local_shared_ptr<T> make_local_shared(std::size_t n,
const remove_extent_t<T>& v);
@@ -53,20 +53,20 @@ namespace boost {
local_shared_ptr<T> allocate_local_shared(const A& a, std::size_t n,
const remove_extent_t<T>& v);
`// only if T is an array type of the form U[N]`
`// T is an array of known bounds`
template<class T>
local_shared_ptr<T> make_local_shared(const remove_extent_t<T>& v);
template<class T, class A>
local_shared_ptr<T> allocate_local_shared(const A& a,
const remove_extent_t<T>& v);
`// only if T is not an array type of the form U[]`
`// T is not an array of known bounds`
template<class T>
local_shared_ptr<T> make_local_shared_noinit();
template<class T, class A>
local_shared_ptr<T> allocate_local_shared_noinit(const A& a);
`// only if T is an array type of the form U[N]`
`// T is an array of unknown bounds`
template<class T>
local_shared_ptr<T> make_local_shared_noinit(std::size_t n);
template<class T, class A>

View File

@@ -55,43 +55,43 @@ types.
[subs=+quotes]
```
namespace boost {
`// only if T is not an array type`
`// T is not an array`
template<class T, class... Args>
shared_ptr<T> make_shared(Args&&... args);
template<class T, class A, class... Args>
shared_ptr<T> allocate_shared(const A& a, Args&&... args);
`// only if T is an array type of the form U[]`
`// T is an array of unknown bounds`
template<class T>
shared_ptr<T> make_shared(std::size_t n);
template<class T, class A>
shared_ptr<T> allocate_shared(const A& a, std::size_t n);
`// only if T is an array type of the form U[N]`
`// T is an array of known bounds`
template<class T>
shared_ptr<T> make_shared();
template<class T, class A>
shared_ptr<T> allocate_shared(const A& a);
`// only if T is an array type of the form U[]`
`// T is an array of unknown bounds`
template<class T> shared_ptr<T>
make_shared(std::size_t n, const remove_extent_t<T>& v);
template<class T, class A> shared_ptr<T>
allocate_shared(const A& a, std::size_t n, const remove_extent_t<T>& v);
`// only if T is an array type of the form U[N]`
`// T is an array of known bounds`
template<class T>
shared_ptr<T> make_shared(const remove_extent_t<T>& v);
template<class T, class A>
shared_ptr<T> allocate_shared(const A& a, const remove_extent_t<T>& v);
`// only if T is not an array type of the form U[]`
`// T is not an array of unknown bounds`
template<class T>
shared_ptr<T> make_shared_noinit();
template<class T, class A>
shared_ptr<T> allocate_shared_noinit(const A& a);
`// only if T is an array type of the form U[N]`
`// T is an array of unknown bounds`
template<class T>
shared_ptr<T> make_shared_noinit(std::size_t n);
template<class T, class A>
@@ -144,7 +144,7 @@ perform this initialization via the expression
`std::allocator_traits<A2>::construct(a2, p, expr)` (where
`_expr_` is `v` or `std::forward<Args>(args)\...)` respectively), `p`
points to storage suitable to hold an object of type `U`, and `a2` of
type `A2` is a rebound copy `a` such that its `value_type` is `U`.
type `A2` is a potentially rebound copy of `a`.
* When a (sub)object of non-array type `U` is specified to be
default-initialized, `make_shared_noinit` and `allocate_shared_noinit` shall
perform this initialization via the expression `::new(p) U`, where
@@ -158,7 +158,7 @@ storage suitable to hold an object of type `U`.
value-initialized, `allocate_shared` shall perform this initialization via the
expression `std::allocator_traits<A2>::construct(a2, p)`, where
`p` points to storage suitable to hold an object of type `U` and `a2` of
type `A2` is a rebound copy of `a` such that its value_type is `U`.
type `A2` is a potentially rebound copy of `a`.
* Array elements are initialized in ascending order of their addresses.
* 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
@@ -174,17 +174,17 @@ the reference counts.
template<class T, class... Args>
shared_ptr<T> make_shared(Args&&... args);
```
::
```
template<class T, class A, class... Args>
shared_ptr<T> allocate_shared(const A& a, Args&&... args);
```
::
Remarks::: These overloads shall only participate in overload resolution when
`T` is not an array type.
Returns::: A `shared_ptr` to an object of type `T`, constructed from
[none]
* {blank}
+
Constraints:: `T` is not an array.
Returns:: A `shared_ptr` to an object of type `T`, constructed from
`args\...`.
Examples:::
Examples::
* `auto p = make_shared<int>();`
* `auto p = make_shared<std::vector<int> >(16, 1);`
@@ -192,17 +192,17 @@ Examples:::
template<class T>
shared_ptr<T> make_shared(std::size_t n);
```
::
```
template<class T, class A>
shared_ptr<T> allocate_shared(const A& a, std::size_t n);
```
::
Remarks::: These overloads shall only participate in overload resolution when
`T` is an array type of the form `U[]`.
Returns::: A `shared_ptr` to a sequence of `n` value-initialized objects of
type `U`.
Examples:::
[none]
* {blank}
+
Constraints:: `T` is an array of unknown bounds.
Returns:: A `shared_ptr` to a sequence of `n` value-initialized objects of
type `remove_extent_t<T>`.
Examples::
* `auto p = make_shared<double[]>(1024);`
* `auto p = make_shared<double[][2][2]>(6);`
@@ -210,17 +210,17 @@ Examples:::
template<class T>
shared_ptr<T> make_shared();
```
::
```
template<class T, class A>
shared_ptr<T> allocate_shared(const A& a);
```
::
Remarks::: These overloads shall only participate in overload resolution when
`T` is an array type of the form `U[N]`.
Returns::: A `shared_ptr` to a sequence of `N` value-initialized objects of
type `U`.
Examples:::
[none]
* {blank}
+
Constraints:: `T` is an array of known bounds.
Returns:: A `shared_ptr` to a sequence of `extent_v<T>` value-initialized
objects of type `remove_extent_t<T>`.
Examples::
* `auto p = make_shared<double[1024]>();`
* `auto p = make_shared<double[6][2][2]>();`
@@ -228,17 +228,17 @@ Examples:::
template<class T> shared_ptr<T>
make_shared(std::size_t n, const remove_extent_t<T>& v);
```
::
```
template<class T, class A> shared_ptr<T>
allocate_shared(const A& a, std::size_t n, const remove_extent_t<T>& v);
```
::
Remarks::: These overloads shall only participate in overload resolution when
`T` is an array type of the form `U[]`.
Returns::: A `shared_ptr` to a sequence of `n` objects of type `U`, each
initialized to `v`.
Examples:::
[none]
* {blank}
+
Constraints:: `T` is an array of unknown bounds.
Returns:: A `shared_ptr` to a sequence of `n` objects of type
`remove_extent_t<T>`, each initialized to `v`.
Examples::
* `auto p = make_shared<double[]>(1024, 1.0);`
* `auto p = make_shared<double[][2]>(6, {1.0, 0.0});`
* `auto p = make_shared<std::vector<int>[]>(4, {1, 2});`
@@ -247,17 +247,17 @@ Examples:::
template<class T>
shared_ptr<T> make_shared(const remove_extent_t<T>& v);
```
::
```
template<class T, class A>
shared_ptr<T> allocate_shared(const A& a, const remove_extent_t<T>& v);
```
::
Remarks::: These overloads shall only participate in overload resolution when
`T` is an array type of the form `U[N]`.
Returns::: A `shared_ptr` to a sequence of `N` objects of type `U`, each
initialized to `v`.
Examples:::
[none]
* {blank}
+
Constraints:: `T` is an array of known bounds.
Returns:: A `shared_ptr` to a sequence of `extent_v<T>` objects of type
`remove_extent_t<T>`, each initialized to `v`.
Examples::
* `auto p = make_shared<double[1024]>(1.0);`
* `auto p = make_shared<double[6][2]>({1.0, 0.0});`
* `auto p = make_shared<std::vector<int>[4]>({1, 2});`
@@ -266,30 +266,31 @@ Examples:::
template<class T>
shared_ptr<T> make_shared_noinit();
```
::
```
template<class T, class A>
shared_ptr<T> allocate_shared_noinit(const A& a);
```
::
Remarks::: These overloads shall only participate in overload resolution when
`T` is not an array type, or an array type of the `U[N]`.
Returns::: A `shared_ptr` to a default-initialized object of type `T`, or a
sequence of `N` default-initialized objects of type `U`, respectively.
Example::: `auto p = make_shared_noinit<double[1024]>();`
[none]
* {blank}
+
Constraints:: `T` is not an array, or is an array of known bounds.
Returns:: A `shared_ptr` to a default-initialized object of type `T`, or a
sequence of `extent_v<T>` default-initialized objects of type
`remove_extent_t<T>`, respectively.
Example:: `auto p = make_shared_noinit<double[1024]>();`
```
template<class T>
shared_ptr<T> make_shared_noinit(std::size_t n);
```
::
```
template<class T, class A>
shared_ptr<T> allocate_shared_noinit(const A& a, std::size_t n);
```
::
Remarks::: These overloads shall only participate in overload resolution when
`T` is an array type of the form `U[]`.
Returns::: A `shared_ptr` to a sequence of `_n_` default-initialized objects
of type `U`.
Example::: `auto p = make_shared_noinit<double[]>(1024);`
[none]
* {blank}
+
Constraints:: `T` is an array of unknown bounds.
Returns:: A `shared_ptr` to a sequence of `_n_` default-initialized objects
of type `remove_extent_t<T>`.
Example:: `auto p = make_shared_noinit<double[]>(1024);`

View File

@@ -30,8 +30,8 @@ requests from users.
This library also provides additional overloads of `make_unique` for
default-initialization, when users do not need or want to incur the expense
of value-initialization. The {cpp} standard does not yet provide this
feature with `std::make_unique`.
of value-initialization. The {cpp}20 standard now provides this feature with
`std::make_unique_for_overwrite`.
## Synopsis
@@ -40,23 +40,23 @@ feature with `std::make_unique`.
[subs=+quotes]
```
namespace boost {
`// only if T is not an array type`
`// T is not an array`
template<class T, class... Args>
std::unique_ptr<T> make_unique(Args&&... args);
`// only if T is not an array type`
`// T is not an array`
template<class T>
std::unique_ptr<T> make_unique(remove_reference_t<T>&& v);
std::unique_ptr<T> make_unique(type_identity_t<T>&& v);
`// only if T is an array type of the form U[]`
`// T is an array of unknown bounds`
template<class T>
std::unique_ptr<T> make_unique(std::size_t n);
`// only if T is not an array type`
`// T is not an array`
template<class T>
std::unique_ptr<T> make_unique_noinit();
`// only if T is an array type of the form U[]`
`// T is an array of unknown bounds`
template<class T>
std::unique_ptr<T> make_unique_noinit(std::size_t n);
}
@@ -68,48 +68,53 @@ namespace boost {
template<class T, class... Args>
std::unique_ptr<T> make_unique(Args&&... args);
```
::
Remarks::: These overloads shall only participate in overload resolution when
`T` is not an array type.
Returns::: `std::unique_ptr<T>(new T(std::forward<Args>(args)\...)`.
Example::: `auto p = make_unique<int>();`
[none]
* {blank}
+
Constraints:: `T` is not an array.
Returns:: `std::unique_ptr<T>(new T(std::forward<Args>(args)\...)`.
Example:: `auto p = make_unique<int>();`
```
template<class T>
std::unique_ptr<T> make_unique(remove_reference_t<T>&& v);
std::unique_ptr<T> make_unique(type_identity_t<T>&& v);
```
::
Remarks::: These overloads shall only participate in overload resolution when
`T` is not an array type.
Returns::: `std::unique_ptr<T>(new T(std::move(v))`.
Example::: `auto p = make_unique<std::vector<int> >({1, 2});`
[none]
* {blank}
+
Constraints:: `T` is not an array.
Returns:: `std::unique_ptr<T>(new T(std::move(v))`.
Example:: `auto p = make_unique<std::vector<int> >({1, 2});`
```
template<class T>
std::unique_ptr<T> make_unique(std::size_t n);
```
::
Remarks::: These overloads shall only participate in overload resolution when
`T` is an array type of the form `U[]`.
Returns::: `std::unique_ptr<U[]>(new U[n]())`.
Example::: `auto p = make_unique<double[]>(1024);`
[none]
* {blank}
+
Constraints:: `T` is an array of unknown bounds.
Returns:: `std::unique_ptr<T>(new remove_extent_t<T>[n]())`.
Example:: `auto p = make_unique<double[]>(1024);`
```
template<class T>
std::unique_ptr<T> make_unique_noinit();
```
::
Remarks::: These overloads shall only participate in overload resolution when
`T` is not an array type.
Returns::: `std::unique_ptr<T>(new T)`.
Example::: `auto p = make_unique_noinit<double[1024]>();`
[none]
* {blank}
+
Constraints:: `T` is not an array.
Returns:: `std::unique_ptr<T>(new T)`.
Example:: `auto p = make_unique_noinit<std::array<double, 1024> >();`
```
template<class T>
std::unique_ptr<T> make_unique_noinit(std::size_t n);
```
::
Remarks::: These overloads shall only participate in overload resolution when
`T` is an array type of the form `U[]`.
Returns::: `std::unique_ptr<U[]>(new U[n])`.
Example::: `auto p = make_unique_noinit<double[]>(1024);`
[none]
* {blank}
+
Constraints:: `T` is an array of unknown bounds.
Returns:: `std::unique_ptr<T>(new remove_extent_t<T>[n])`.
Example:: `auto p = make_unique_noinit<double[]>(1024);`

View File

@@ -0,0 +1,45 @@
////
Copyright 2020 Peter Dimov
Distributed under the Boost Software License, Version 1.0.
https://www.boost.org/LICENSE_1_0.txt
////
[#owner_equal_to]
# owner_equal_to
:toc:
:toc-title:
:idprefix: owner_equal_to_
## Description
`owner_equal_to<T>` is a helper function object that compares two smart
pointer objects using `owner_equals`.
## Synopsis
`owner_equal_to` is defined in `<boost/smart_ptr/owner_equal_to.hpp>`.
```
namespace boost {
template<class T = void> struct owner_equal_to
{
typedef bool result_type;
typedef T first_argument_type;
typedef T second_argument_type;
template<class U, class V> bool operator()( U const & u, V const & v ) const noexcept;
};
}
```
## Members
```
template<class U, class V> bool operator()( U const & u, V const & v ) const noexcept;
```
[none]
* {blank}
+
Returns::
`u.owner_equals( v )`.

View File

@@ -0,0 +1,56 @@
////
Copyright 2020 Peter Dimov
Distributed under the Boost Software License, Version 1.0.
https://www.boost.org/LICENSE_1_0.txt
////
[#owner_hash]
# owner_hash
:toc:
:toc-title:
:idprefix: owner_hash_to_
## Description
`owner_hash<T>` is a helper function object that takes a smart pointer `p`
and returns `p.owner_hash_value()`. It's useful for creating unordered
containers of `shared_ptr` that use ownership-based equality, instead of
the default pointer value equality. (It can be used with `weak_ptr` too,
but there's no need, because `boost::hash` and `std::hash` for `weak_ptr`
already use ownership-based equality.)
## Example
```
std::unordered_set< boost::shared_ptr<void>,
boost::owner_hash< boost::shared_ptr<void> >,
boost::owner_equal_to< boost::shared_ptr<void> > > set;
```
## Synopsis
`owner_hash` is defined in `<boost/smart_ptr/owner_hash.hpp>`.
```
namespace boost {
template<class T> struct owner_hash
{
typedef std::size_t result_type;
typedef T argument_type;
std::size_t operator()( T const & p ) const noexcept;
};
}
```
## Members
```
std::size_t operator()( T const & p ) const noexcept;
```
[none]
* {blank}
+
Returns::
`p.owner_hash_value()`.

View File

@@ -0,0 +1,50 @@
////
Copyright 2020 Peter Dimov
Distributed under the Boost Software License, Version 1.0.
https://www.boost.org/LICENSE_1_0.txt
////
[#owner_less]
# owner_less
:toc:
:toc-title:
:idprefix: owner_less_
## Description
`owner_less<T>` is a helper function object that compares two smart
pointer objects using `owner_before`. It is only provided for compatibility
with {cpp}11 and corresponds to the standard component of the same name.
When using Boost smart pointers, the use of `owner_less` is unnecessary, as
the supplied `operator<` overloads (and, correspondingly, `std::less`) return
the same result.
## Synopsis
`owner_less` is defined in `<boost/smart_ptr/owner_less.hpp>`.
```
namespace boost {
template<class T = void> struct owner_less
{
typedef bool result_type;
typedef T first_argument_type;
typedef T second_argument_type;
template<class U, class V> bool operator()( U const & u, V const & v ) const noexcept;
};
}
```
## Members
```
template<class U, class V> bool operator()( U const & u, V const & v ) const noexcept;
```
[none]
* {blank}
+
Returns::
`u.owner_before( v )`.

View File

@@ -78,23 +78,29 @@ namespace boost {
```
template<class T, class U> T* static_pointer_cast(U* p) noexcept;
```
::
Returns::: `static_cast<T*>(p)`
[none]
* {blank}
+
Returns:: `static_cast<T*>(p)`
```
template<class T, class U> std::shared_ptr<T>
static_pointer_cast(const std::shared_ptr<U>& p) noexcept;
```
::
Returns::: `std::static_pointer_cast<T>(p)`
[none]
* {blank}
+
Returns:: `std::static_pointer_cast<T>(p)`
```
template<class T, class U> std::unique_ptr<T>
static_pointer_cast(std::unique_ptr<U>&& p) noexcept;
```
::
Requires::: The expression `static_cast<T*>((U*)0)` must be well-formed.
Returns::: `std::unique_ptr<T>(static_cast<typename
[none]
* {blank}
+
Requires:: The expression `static_cast<T*>((U*)0)` must be well-formed.
Returns:: `std::unique_ptr<T>(static_cast<typename
std::unique_ptr<T>::element_type*>(p.release()))`.
CAUTION: The seemingly equivalent expression
@@ -106,25 +112,31 @@ undefined behavior, attempting to delete the same object twice.
```
template<class T, class U> T* dynamic_pointer_cast(U* p) noexcept;
```
::
Returns::: `dynamic_cast<T*>(p)`
[none]
* {blank}
+
Returns:: `dynamic_cast<T*>(p)`
```
template<class T, class U> std::shared_ptr<T>
dynamic_pointer_cast(const std::shared_ptr<U>& p) noexcept;
```
::
Returns::: `std::dynamic_pointer_cast<T>(p)`
[none]
* {blank}
+
Returns:: `std::dynamic_pointer_cast<T>(p)`
```
template<class T, class U> std::unique_ptr<T>
dynamic_pointer_cast(std::unique_ptr<U>&& p) noexcept;
```
::
Requires:::
[none]
* {blank}
+
Requires::
* The expression `static_cast<T*>((U*)0)` must be well-formed.
* `T` must have a virtual destructor.
Returns:::
Returns::
* When `dynamic_cast<typename std::unique_ptr<T>::element_type*>(p.get())`
returns a non-zero value, `std::unique_ptr<T>(dynamic_cast<typename
std::unique_ptr<T>::element_type*>(p.release()));`.
@@ -135,23 +147,29 @@ std::unique_ptr<T>::element_type*>(p.release()));`.
```
template<class T, class U> T* const_pointer_cast(U* p) noexcept;
```
::
Returns::: `const_cast<T*>(p)`
[none]
* {blank}
+
Returns:: `const_cast<T*>(p)`
```
template<class T, class U> std::shared_ptr<T>
const_pointer_cast(const std::shared_ptr<U>& p) noexcept;
```
::
Returns::: `std::const_pointer_cast<T>(p)`
[none]
* {blank}
+
Returns:: `std::const_pointer_cast<T>(p)`
```
template<class T, class U> std::unique_ptr<T>
const_pointer_cast(std::unique_ptr<U>&& p) noexcept;
```
::
Requires::: The expression `const_cast<T*>((U*)0)` must be well-formed.
Returns::: `std::unique_ptr<T>(const_cast<typename
[none]
* {blank}
+
Requires:: The expression `const_cast<T*>((U*)0)` must be well-formed.
Returns:: `std::unique_ptr<T>(const_cast<typename
std::unique_ptr<T>::element_type*>(p.release()))`.
### reinterpret_pointer_cast
@@ -159,23 +177,29 @@ std::unique_ptr<T>::element_type*>(p.release()))`.
```
template<class T, class U> T* reinterpret_pointer_cast(U* p) noexcept;
```
::
Returns::: `reinterpret_cast<T*>(p)`
[none]
* {blank}
+
Returns:: `reinterpret_cast<T*>(p)`
```
template<class T, class U> std::shared_ptr<T>
reinterpret_pointer_cast(const std::shared_ptr<U>& p) noexcept;
```
::
Returns::: `std::reinterpret_pointer_cast<T>(p)`
[none]
* {blank}
+
Returns:: `std::reinterpret_pointer_cast<T>(p)`
```
template<class T, class U> std::unique_ptr<T>
reinterpret_pointer_cast(std::unique_ptr<U>&& p) noexcept;
```
::
Requires::: The expression `reinterpret_cast<T*>((U*)0)` must be well-formed.
Returns::: `std::unique_ptr<T>(reinterpret_cast<typename
[none]
* {blank}
+
Requires:: The expression `reinterpret_cast<T*>((U*)0)` must be well-formed.
Returns:: `std::unique_ptr<T>(reinterpret_cast<typename
std::unique_ptr<T>::element_type*>(p.release()))`.
## Example
@@ -210,4 +234,4 @@ int main()
delete ptr;
}
```
```

View File

@@ -105,42 +105,50 @@ Type:: Provides the type of the stored pointer.
```
explicit shared_array(T* p = 0);
```
::
Effects::: Constructs a `shared_array`, storing a copy of `p`, which must be a
[none]
* {blank}
+
Effects:: Constructs a `shared_array`, storing a copy of `p`, which must be a
pointer to an array that was allocated via a C++ `new[]` expression or be 0.
Afterwards, the use count is 1 (even if `p == 0`; see `~shared_array`).
Requires::: `T` is a complete type.
Throws::: `std::bad_alloc`. If an exception is thrown, `delete[] p` is called.
Requires:: `T` is a complete type.
Throws:: `std::bad_alloc`. If an exception is thrown, `delete[] p` is called.
```
template<class D> shared_array(T* p, D d);
```
::
Effects::: Constructs a `shared_array`, storing a copy of `p` and of `d`.
[none]
* {blank}
+
Effects:: Constructs a `shared_array`, storing a copy of `p` and of `d`.
Afterwards, the use count is 1. When the the time comes to delete the array
pointed to by `p`, the object `d` is used in the statement `d(p)`.
Requires:::
Requires::
* `T` is a complete type.
* The copy constructor and destructor of `D` must not throw.
* Invoking the object `d` with parameter `p` must not throw.
Throws::: `std::bad_alloc`. If an exception is thrown, `d(p)` is called.
Throws:: `std::bad_alloc`. If an exception is thrown, `d(p)` is called.
```
shared_array(const shared_array& v) noexcept;
```
::
Effects::: Constructs a `shared_array`, as if by storing a copy of the pointer
[none]
* {blank}
+
Effects:: Constructs a `shared_array`, as if by storing a copy of the pointer
stored in `v`. Afterwards, the use count for all copies is 1 more than the
initial use count.
Requires::: `T` is a complete type.
Requires:: `T` is a complete type.
### Destructor
```
~shared_array() noexcept;
```
::
Effects::: Decrements the use count. Then, if the use count is 0, deletes the
[none]
* {blank}
+
Effects:: Decrements the use count. Then, if the use count is 0, deletes the
array pointed to by the stored pointer. Note that `delete[]` on a pointer with
a value of 0 is harmless.
@@ -149,69 +157,82 @@ a value of 0 is harmless.
```
shared_array& operator=(const shared_array& v) noexcept;
```
::
Effects::: Constructs a new `shared_array` as described above, then replaces
[none]
* {blank}
+
Effects:: Constructs a new `shared_array` as described above, then replaces
this `shared_array` with the new one, destroying the replaced object.
Requires::: `T` is a complete type.
Returns::: `*this`.
Requires:: `T` is a complete type.
Returns:: `*this`.
### reset
```
void reset(T* p = 0);
```
::
Effects::: Constructs a new `shared_array` as described above, then replaces
[none]
* {blank}
+
Effects:: Constructs a new `shared_array` as described above, then replaces
this `shared_array` with the new one, destroying the replaced object.
Requires::: `T` is a complete type.
Throws::: `std::bad_alloc`. If an exception is thrown, `delete[] p` is called.
Requires:: `T` is a complete type.
Throws:: `std::bad_alloc`. If an exception is thrown, `delete[] p` is called.
```
template<class D> void reset(T* p, D d);
```
::
Effects::: Constructs a new `shared_array` as described above, then replaces
[none]
* {blank}
+
Effects:: Constructs a new `shared_array` as described above, then replaces
this `shared_array` with the new one, destroying the replaced object.
Requires:::
Requires::
* `T` is a complete type.
* The copy constructor of `D` must not throw.
Throws::: `std::bad_alloc`. If an exception is thrown, `d(p)` is called.
Throws:: `std::bad_alloc`. If an exception is thrown, `d(p)` is called.
### Indexing
```
T& operator[](std::ptrdiff_t n) const noexcept;
```
Returns::: A reference to element `n` of the array pointed to by the stored
Returns:: A reference to element `n` of the array pointed to by the stored
pointer. Behavior is undefined and almost certainly undesirable if the stored
pointer is 0, or if `n` is less than 0 or is greater than or equal to the
number of elements in the array.
Requires::: `T` is a complete type.
Requires:: `T` is a complete type.
### get
```
T* get() const noexcept;
```
::
Returns::: The stored pointer.
[none]
* {blank}
+
Returns::
The stored pointer.
### unique
```
bool unique() const noexcept;
```
::
Returns::: `true` if no other `shared_array` is sharing ownership of the
stored pointer, `false` otherwise.
[none]
* {blank}
+
Returns::
`true` if no other `shared_array` is sharing ownership of the stored pointer, `false` otherwise.
### use_count
```
long use_count() const noexcept;
```
::
Returns::: The number of `shared_array` objects sharing ownership of the
[none]
* {blank}
+
Returns:: The number of `shared_array` objects sharing ownership of the
stored pointer.
### Conversions
@@ -219,17 +240,22 @@ stored pointer.
```
explicit operator bool() const noexcept;
```
::
Returns::: `get() != 0`.
Requires::: `T` is a complete type.
[none]
* {blank}
+
Returns:: `get() != 0`.
Requires:: `T` is a complete type.
### swap
```
void swap(shared_array<T>& b) noexcept;
```
::
Effects::: Exchanges the contents of the two smart pointers.
[none]
* {blank}
+
Effects::
Exchanges the contents of the two smart pointers.
## Free Functions
@@ -247,8 +273,10 @@ template<class T> bool
template<class T> bool
operator<(const shared_array<T>& a, const shared_array<T>& b) noexcept;
```
::
Returns::: The result of comparing the stored pointers of the two smart
[none]
* {blank}
+
Returns:: The result of comparing the stored pointers of the two smart
pointers.
NOTE: The `operator<` overload is provided to define an ordering so that
@@ -265,6 +293,8 @@ mandates that relational operations on pointers are unspecified (5.9
template<class T>
void swap(shared_array<T>& a, shared_array<T>& b) noexcept;
```
::
Returns::: `a.swap(b)`.
Requires::: `T` is a complete type.
[none]
* {blank}
+
Returns:: `a.swap(b)`.
Requires:: `T` is a complete type.

View File

@@ -132,7 +132,6 @@ namespace boost {
template<class Y> shared_ptr(shared_ptr<Y> && r) noexcept;
template<class Y> shared_ptr(shared_ptr<Y> const & r, element_type * p) noexcept;
template<class Y> shared_ptr(shared_ptr<Y> && r, element_type * p) noexcept;
template<class Y> explicit shared_ptr(weak_ptr<Y> const & r);
@@ -179,8 +178,13 @@ namespace boost {
void swap(shared_ptr & b) noexcept;
template<class Y> bool owner_before(shared_ptr<Y> const & rhs) const noexcept;
template<class Y> bool owner_before(weak_ptr<Y> const & rhs) const noexcept;
template<class Y> bool owner_before(shared_ptr<Y> const & r) const noexcept;
template<class Y> bool owner_before(weak_ptr<Y> const & r) const noexcept;
template<class Y> bool owner_equals(shared_ptr<Y> const & r) const noexcept;
template<class Y> bool owner_equals(weak_ptr<Y> const & r) const noexcept;
std::size_t owner_hash_value() const noexcept;
};
template<class T, class U>
@@ -373,7 +377,7 @@ template<class Y> shared_ptr(shared_ptr<Y> const & r, element_type * p) noexcept
[none]
* {blank}
+
Effects:: constructs a `shared_ptr` that shares ownership with `r` and stores `p`.
Effects:: Copy-constructs a `shared_ptr` from `r`, while storing `p` instead.
Postconditions:: `get() == p && use_count() == r.use_count()`.
@@ -561,7 +565,8 @@ template<class Y> void reset(shared_ptr<Y> && r, element_type * p) noexcept;
[none]
* {blank}
+
Effects:: Equivalent to `shared_ptr(std::move(r), p).swap(*this)`.
Effects::
Equivalent to `shared_ptr(std::move(r), p).swap(*this)`.
### indirection
```
@@ -599,7 +604,8 @@ element_type * get() const noexcept;
[none]
* {blank}
+
Returns:: The stored pointer.
Returns::
The stored pointer.
### unique
```
@@ -608,7 +614,8 @@ bool unique() const noexcept;
[none]
* {blank}
+
Returns:: `use_count() == 1`.
Returns::
`use_count() == 1`.
### use_count
```
@@ -617,7 +624,8 @@ long use_count() const noexcept;
[none]
* {blank}
+
Returns:: The number of `shared_ptr` objects, `*this` included, that share ownership with `*this`, or 0 when `*this` is empty.
Returns::
The number of `shared_ptr` objects, `*this` included, that share ownership with `*this`, or 0 when `*this` is empty.
### conversions
```
@@ -642,19 +650,45 @@ void swap(shared_ptr & b) noexcept;
[none]
* {blank}
+
Effects:: Exchanges the contents of the two smart pointers.
Effects::
Exchanges the contents of the two smart pointers.
### owner_before
```
template<class Y> bool owner_before(shared_ptr<Y> const & rhs) const noexcept;
template<class Y> bool owner_before(shared_ptr<Y> const & r) const noexcept;
```
```
template<class Y> bool owner_before(weak_ptr<Y> const & rhs) const noexcept;
template<class Y> bool owner_before(weak_ptr<Y> const & r) const noexcept;
```
[none]
* {blank}
+
Effects:: See the description of `operator<`.
Returns::
See the description of `operator<`.
### owner_equals
```
template<class Y> bool owner_equals(shared_ptr<Y> const & r) const noexcept;
```
```
template<class Y> bool owner_equals(weak_ptr<Y> const & r) const noexcept;
```
[none]
* {blank}
+
Returns::
`true` if and only if `*this` and `r` share ownership or are both empty.
### owner_hash_value
```
std::size_t owner_hash_value() const noexcept;
```
[none]
* {blank}
+
Returns::
An unspecified hash value such that two instances that share ownership
have the same hash value.
## Free Functions
@@ -722,7 +756,8 @@ template<class T> void swap(shared_ptr<T> & a, shared_ptr<T> & b) noexcept;
[none]
* {blank}
+
Effects:: Equivalent to `a.swap(b)`.
Effects::
Equivalent to `a.swap(b)`.
### get_pointer
```
@@ -806,7 +841,8 @@ template<class D, class T>
[none]
* {blank}
+
Returns:: If `*this` owns a deleter `d` of type (cv-unqualified) `D`, returns `&d`; otherwise returns 0.
Returns::
If `*this` owns a deleter `d` of type (cv-unqualified) `D`, returns `&d`; otherwise returns 0.
### Atomic Access

View File

@@ -88,6 +88,10 @@ namespace boost {
weak_ptr(weak_ptr && r) noexcept;
template<class Y> weak_ptr(shared_ptr<Y> const & r, element_type * p) noexcept;
template<class Y> weak_ptr(weak_ptr<Y> const & r, element_type * p) noexcept;
template<class Y> weak_ptr(weak_ptr<Y> && r, element_type * p) noexcept;
~weak_ptr() noexcept;
weak_ptr & operator=(weak_ptr const & r) noexcept;
@@ -98,6 +102,8 @@ namespace boost {
long use_count() const noexcept;
bool expired() const noexcept;
bool empty() const noexcept;
shared_ptr<T> lock() const noexcept;
void reset() noexcept;
@@ -106,6 +112,11 @@ namespace boost {
template<class Y> bool owner_before( weak_ptr<Y> const & r ) const noexcept;
template<class Y> bool owner_before( shared_ptr<Y> const & r ) const noexcept;
template<class Y> bool owner_equals( weak_ptr<Y> const & r ) const noexcept;
template<class Y> bool owner_equals( shared_ptr<Y> const & r ) const noexcept;
std::size_t owner_hash_value() const noexcept;
};
template<class T, class U>
@@ -157,6 +168,21 @@ weak_ptr(weak_ptr && r) noexcept;
Effects:: Constructs a `weak_ptr` that has the value `r` held.
Postconditions:: `r` is empty.
### aliasing constructors
```
template<class Y> weak_ptr(shared_ptr<Y> const & r, element_type * p) noexcept;
```
```
template<class Y> weak_ptr(weak_ptr<Y> const & r, element_type * p) noexcept;
```
```
template<class Y> weak_ptr(weak_ptr<Y> && r, element_type * p) noexcept;
```
Effects:: Constructs a `weak_ptr` from `r` as if by using the corresponding converting/copy/move constructor, but stores `p` instead.
Postconditions:: `use_count() == r.use_count()`. When `!expired()`, `shared_ptr<T>(*this).get() == p`.
NOTE: These constructors are an extension, not present in `std::weak_ptr`.
### destructor
```
~weak_ptr() noexcept;
@@ -164,7 +190,8 @@ Postconditions:: `r` is empty.
[none]
* {blank}
+
Effects:: Destroys this `weak_ptr` but has no effect on the object its stored pointer points to.
Effects::
Destroys this `weak_ptr` but has no effect on the object its stored pointer points to.
### assignment
```
@@ -193,7 +220,8 @@ long use_count() const noexcept;
[none]
* {blank}
+
Returns:: 0 if `*this` is empty; otherwise, the number of `shared_ptr` objects that share ownership with `*this`.
Returns::
0 if `*this` is empty; otherwise, the number of `shared_ptr` objects that share ownership with `*this`.
### expired
```
@@ -202,7 +230,19 @@ bool expired() const noexcept;
[none]
* {blank}
+
Returns:: `use_count() == 0`.
Returns::
`use_count() == 0`.
### empty
```
bool empty() const noexcept;
```
[none]
* {blank}
+
Returns:: `true` when `*this` is empty, `false` otherwise.
NOTE: This function is an extension, not present in `std::weak_ptr`.
### lock
```
@@ -211,7 +251,8 @@ shared_ptr<T> lock() const noexcept;
[none]
* {blank}
+
Returns:: `expired()? shared_ptr<T>(): shared_ptr<T>(*this)`.
Returns::
`expired()? shared_ptr<T>(): shared_ptr<T>(*this)`.
### reset
```
@@ -220,7 +261,8 @@ void reset() noexcept;
[none]
* {blank}
+
Effects:: Equivalent to `weak_ptr().swap(*this)`.
Effects::
Equivalent to `weak_ptr().swap(*this)`.
### swap
```
@@ -229,8 +271,10 @@ void swap(weak_ptr & b) noexcept;
[none]
* {blank}
+
Effects:: Exchanges the contents of the two smart pointers.
Effects::
Exchanges the contents of the two smart pointers.
### owner_before
```
template<class Y> bool owner_before( weak_ptr<Y> const & r ) const noexcept;
```
@@ -240,7 +284,32 @@ template<class Y> bool owner_before( shared_ptr<Y> const & r ) const noexcept;
[none]
* {blank}
+
Returns:: See the description of `operator<`.
Returns::
See the description of `operator<`.
### owner_equals
```
template<class Y> bool owner_equals( weak_ptr<Y> const & r ) const noexcept;
```
```
template<class Y> bool owner_equals( shared_ptr<Y> const & r ) const noexcept;
```
[none]
* {blank}
+
Returns::
`true` if and only if `*this` and `r` share ownership or are both empty.
### owner_hash_value
```
std::size_t owner_hash_value() const noexcept;
```
[none]
* {blank}
+
Returns::
An unspecified hash value such that two instances that share ownership
have the same hash value.
## Free Functions
@@ -266,7 +335,8 @@ template<class T> void swap(weak_ptr<T> & a, weak_ptr<T> & b) noexcept;
[none]
* {blank}
+
Effects:: Equivalent to `a.swap(b)`.
Effects::
Equivalent to `a.swap(b)`.
## Frequently Asked Questions

View File

@@ -12,7 +12,7 @@
#include <boost/assert.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/detail/lightweight_mutex.hpp>
#include <boost/smart_ptr/detail/lightweight_mutex.hpp>
#include <cstdlib>
#include <map>
#include <deque>

View File

@@ -73,15 +73,11 @@ void * operator new(size_t n) throw(bad_alloc)
return p;
}
#if !defined(__BORLANDC__) || (__BORLANDC__ > 0x551)
void * operator new(size_t n, nothrow_t const &) throw()
{
return allocate(n, allocated_scalar);
}
#endif
void * operator new[](size_t n) throw(bad_alloc)
{
void * p = allocate(n, allocated_array);
@@ -95,15 +91,11 @@ void * operator new[](size_t n) throw(bad_alloc)
return p;
}
#if !defined(__BORLANDC__) || (__BORLANDC__ > 0x551)
void * operator new[](size_t n, nothrow_t const &) throw()
{
return allocate(n, allocated_array);
}
#endif
// debug hooks
namespace boost
@@ -205,15 +197,11 @@ void operator delete(void * p) throw()
free(pm);
}
#if !defined(__BORLANDC__) || (__BORLANDC__ > 0x551)
void operator delete(void * p, nothrow_t const &) throw()
{
::operator delete(p);
}
#endif
void operator delete[](void * p) throw()
{
if(p == 0) return;
@@ -231,13 +219,9 @@ void operator delete[](void * p) throw()
free(pm);
}
#if !defined(__BORLANDC__) || (__BORLANDC__ > 0x551)
void operator delete[](void * p, nothrow_t const &) throw()
{
::operator delete[](p);
}
#endif
#endif // defined(BOOST_SP_ENABLE_DEBUG_HOOKS)

View File

@@ -1,12 +1,3 @@
#include <boost/config.hpp>
#if defined(BOOST_MSVC)
#pragma warning(disable: 4786) // identifier truncated in debug info
#pragma warning(disable: 4710) // function not inlined
#pragma warning(disable: 4711) // function selected for automatic inline expansion
#pragma warning(disable: 4514) // unreferenced inline removed
#endif
// shared_ptr_mt_test.cpp - tests shared_ptr with multiple threads
//
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
@@ -18,14 +9,14 @@
#include <boost/shared_ptr.hpp>
#include <boost/bind.hpp>
#include <boost/config.hpp>
#include <boost/smart_ptr/detail/lightweight_thread.hpp>
#include <vector>
#include <cstdio>
#include <ctime>
#include <boost/detail/lightweight_thread.hpp>
//
int const n = 1024 * 1024;
@@ -62,7 +53,7 @@ int main()
clock_t t = clock();
pthread_t a[ m ];
boost::detail::lw_thread_t a[ m ];
for( int i = 0; i < m; ++i )
{
@@ -71,7 +62,7 @@ int main()
for( int j = 0; j < m; ++j )
{
pthread_join( a[j], 0 );
boost::detail::lw_thread_join( a[j] );
}
t = clock() - t;

View File

@@ -1,12 +1,3 @@
#include <boost/config.hpp>
#if defined(BOOST_MSVC)
#pragma warning(disable: 4786) // identifier truncated in debug info
#pragma warning(disable: 4710) // function not inlined
#pragma warning(disable: 4711) // function selected for automatic inline expansion
#pragma warning(disable: 4514) // unreferenced inline removed
#endif
//
// shared_ptr_timing_test.cpp - use to evaluate the impact of thread safety
//

View File

@@ -13,8 +13,8 @@
#include <boost/thread/shared_mutex.hpp>
#include <boost/thread/locks.hpp>
#include <boost/detail/lightweight_mutex.hpp>
#include <boost/detail/lightweight_thread.hpp>
#include <boost/smart_ptr/detail/lightweight_mutex.hpp>
#include <boost/smart_ptr/detail/lightweight_thread.hpp>
#include <vector>
#include <numeric>
@@ -228,7 +228,7 @@ int main( int ac, char const * av[] )
clock_t t = clock();
std::vector<pthread_t> a( m );
std::vector<boost::detail::lw_thread_t> a( m );
for( int i = 0; i < m; ++i )
{
@@ -237,7 +237,7 @@ int main( int ac, char const * av[] )
for( int j = 0; j < m; ++j )
{
pthread_join( a[ j ], 0 );
boost::detail::lw_thread_join( a[ j ] );
}
t = clock() - t;

View File

@@ -18,9 +18,9 @@
#include <boost/thread/locks.hpp>
#endif
#include <boost/detail/lightweight_mutex.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <boost/detail/lightweight_thread.hpp>
#include <boost/smart_ptr/detail/lightweight_mutex.hpp>
#include <boost/smart_ptr/detail/lightweight_thread.hpp>
#include <boost/core/lightweight_test.hpp>
#include <cstdio>
#include <ctime>
@@ -165,7 +165,7 @@ int main()
clock_t t = clock();
pthread_t a[ mr+mw ];
boost::detail::lw_thread_t a[ mr+mw ];
for( int i = 0; i < mr; ++i )
{
@@ -179,7 +179,7 @@ int main()
for( int j = 0; j < mr+mw; ++j )
{
pthread_join( a[ j ], 0 );
boost::detail::lw_thread_join( a[ j ] );
}
t = clock() - t;

View File

@@ -1,12 +1,3 @@
#include <boost/config.hpp>
#if defined(BOOST_MSVC)
#pragma warning(disable: 4786) // identifier truncated in debug info
#pragma warning(disable: 4710) // function not inlined
#pragma warning(disable: 4711) // function selected for automatic inline expansion
#pragma warning(disable: 4514) // unreferenced inline removed
#endif
// weak_ptr_mt_test.cpp
//
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
@@ -19,15 +10,15 @@
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/bind.hpp>
#include <boost/config.hpp>
#include <boost/smart_ptr/detail/lightweight_thread.hpp>
#include <vector>
#include <cstdio>
#include <ctime>
#include <cstdlib>
#include <boost/detail/lightweight_thread.hpp>
//
int const n = 16384;
@@ -100,7 +91,7 @@ int main()
clock_t t = clock();
pthread_t a[ m ];
boost::detail::lw_thread_t a[ m ];
for( int i = 0; i < m; ++i )
{
@@ -111,7 +102,7 @@ int main()
for( int j = 0; j < m; ++j )
{
pthread_join( a[j], 0 );
boost::detail::lw_thread_join( a[j] );
}
t = clock() - t;

View File

@@ -1,12 +1,3 @@
#include <boost/config.hpp>
#if defined(BOOST_MSVC)
#pragma warning(disable: 4786) // identifier truncated in debug info
#pragma warning(disable: 4710) // function not inlined
#pragma warning(disable: 4711) // function selected for automatic inline expansion
#pragma warning(disable: 4514) // unreferenced inline removed
#endif
//
// weak_ptr_timing_test.cpp
//
@@ -20,6 +11,7 @@
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/config.hpp>
#include <vector>
#include <cstdio>

View File

@@ -1,20 +1,13 @@
#ifndef BOOST_DETAIL_ATOMIC_COUNT_HPP_INCLUDED
#define BOOST_DETAIL_ATOMIC_COUNT_HPP_INCLUDED
// MS compatible compilers support #pragma once
// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
#include <boost/config/header_deprecated.hpp>
//
// boost/detail/atomic_count.hpp - thread/SMP safe reference counter
//
// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
//
// 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
BOOST_HEADER_DEPRECATED("<boost/smart_ptr/detail/atomic_count.hpp>")
#include <boost/smart_ptr/detail/atomic_count.hpp>

View File

@@ -1,21 +1,13 @@
#ifndef BOOST_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED
#define BOOST_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED
// MS compatible compilers support #pragma once
// Copyright (c) 2002, 2003 Peter Dimov and Multi Media Ltd.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
#include <boost/config/header_deprecated.hpp>
//
// boost/detail/lightweight_mutex.hpp - lightweight mutex
//
// Copyright (c) 2002, 2003 Peter Dimov and Multi Media Ltd.
//
// 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
//
BOOST_HEADER_DEPRECATED("<boost/smart_ptr/detail/lightweight_mutex.hpp>")
#include <boost/smart_ptr/detail/lightweight_mutex.hpp>

View File

@@ -1,159 +1,15 @@
#ifndef BOOST_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED
#define BOOST_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED
// MS compatible compilers support #pragma once
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
// Copyright (c) 2008, 2018 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
#include <boost/config/header_deprecated.hpp>
// 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
BOOST_HEADER_DEPRECATED("<boost/smart_ptr/detail/lightweight_thread.hpp>")
#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 )
{
#if defined(BOOST_NO_CXX11_SMART_PTR)
std::auto_ptr<lw_abstract_thread> pt( static_cast<lw_abstract_thread *>( pv ) );
#else
std::unique_ptr<lw_abstract_thread> pt( static_cast<lw_abstract_thread *>( pv ) );
#endif
pt->run();
return 0;
}
#else
unsigned __stdcall lw_thread_routine( void * pv )
{
#if defined(BOOST_NO_CXX11_SMART_PTR)
std::auto_ptr<lw_abstract_thread> pt( static_cast<lw_abstract_thread *>( pv ) );
#else
std::unique_ptr<lw_abstract_thread> pt( static_cast<lw_abstract_thread *>( pv ) );
#endif
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 )
{
#if defined(BOOST_NO_CXX11_SMART_PTR)
std::auto_ptr<lw_abstract_thread> p( new lw_thread_impl<F>( f ) );
#else
std::unique_ptr<lw_abstract_thread> p( new lw_thread_impl<F>( f ) );
#endif
int r = pthread_create( &pt, 0, lw_thread_routine, p.get() );
if( r == 0 )
{
p.release();
}
return r;
}
} // namespace detail
} // namespace boost
#include <boost/smart_ptr/detail/lightweight_thread.hpp>
#endif // #ifndef BOOST_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED

View File

@@ -1,22 +1,14 @@
#ifndef BOOST_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED
#define BOOST_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED
// MS compatible compilers support #pragma once
// Copyright (c) 2003 David Abrahams
// Copyright (c) 2003 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
#include <boost/config/header_deprecated.hpp>
//
// 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
//
BOOST_HEADER_DEPRECATED("<boost/smart_ptr/detail/quick_allocator.hpp>")
#include <boost/smart_ptr/detail/quick_allocator.hpp>

View File

@@ -10,49 +10,39 @@
#ifndef BOOST_POINTER_CAST_HPP
#define BOOST_POINTER_CAST_HPP
#include <boost/config.hpp>
#include <boost/smart_ptr/detail/sp_noexcept.hpp>
#include <memory>
#include <type_traits>
namespace boost {
//static_pointer_cast overload for raw pointers
template<class T, class U>
inline T* static_pointer_cast(U *ptr) BOOST_SP_NOEXCEPT
inline T* static_pointer_cast(U *ptr) noexcept
{
return static_cast<T*>(ptr);
}
//dynamic_pointer_cast overload for raw pointers
template<class T, class U>
inline T* dynamic_pointer_cast(U *ptr) BOOST_SP_NOEXCEPT
inline T* dynamic_pointer_cast(U *ptr) noexcept
{
return dynamic_cast<T*>(ptr);
}
//const_pointer_cast overload for raw pointers
template<class T, class U>
inline T* const_pointer_cast(U *ptr) BOOST_SP_NOEXCEPT
inline T* const_pointer_cast(U *ptr) noexcept
{
return const_cast<T*>(ptr);
}
//reinterpret_pointer_cast overload for raw pointers
template<class T, class U>
inline T* reinterpret_pointer_cast(U *ptr) BOOST_SP_NOEXCEPT
inline T* reinterpret_pointer_cast(U *ptr) noexcept
{
return reinterpret_cast<T*>(ptr);
}
} // namespace boost
#if !defined( BOOST_NO_CXX11_SMART_PTR )
#include <boost/type_traits/has_virtual_destructor.hpp>
#include <boost/static_assert.hpp>
#include <memory>
namespace boost {
//static_pointer_cast overload for std::shared_ptr
using std::static_pointer_cast;
@@ -63,7 +53,7 @@ using std::dynamic_pointer_cast;
using std::const_pointer_cast;
//reinterpret_pointer_cast overload for std::shared_ptr
template<class T, class U> std::shared_ptr<T> reinterpret_pointer_cast(const std::shared_ptr<U> & r ) BOOST_SP_NOEXCEPT
template<class T, class U> std::shared_ptr<T> reinterpret_pointer_cast(const std::shared_ptr<U> & r ) noexcept
{
(void) reinterpret_cast< T* >( static_cast< U* >( 0 ) );
@@ -74,7 +64,7 @@ template<class T, class U> std::shared_ptr<T> reinterpret_pointer_cast(const std
}
//static_pointer_cast overload for std::unique_ptr
template<class T, class U> std::unique_ptr<T> static_pointer_cast( std::unique_ptr<U> && r ) BOOST_SP_NOEXCEPT
template<class T, class U> std::unique_ptr<T> static_pointer_cast( std::unique_ptr<U> && r ) noexcept
{
(void) static_cast< T* >( static_cast< U* >( 0 ) );
@@ -84,11 +74,11 @@ template<class T, class U> std::unique_ptr<T> static_pointer_cast( std::unique_p
}
//dynamic_pointer_cast overload for std::unique_ptr
template<class T, class U> std::unique_ptr<T> dynamic_pointer_cast( std::unique_ptr<U> && r ) BOOST_SP_NOEXCEPT
template<class T, class U> std::unique_ptr<T> dynamic_pointer_cast( std::unique_ptr<U> && r ) noexcept
{
(void) dynamic_cast< T* >( static_cast< U* >( 0 ) );
BOOST_STATIC_ASSERT_MSG( boost::has_virtual_destructor<T>::value, "The target of dynamic_pointer_cast must have a virtual destructor." );
static_assert( std::has_virtual_destructor<T>::value, "The target of dynamic_pointer_cast must have a virtual destructor." );
T * p = dynamic_cast<T*>( r.get() );
if( p ) r.release();
@@ -96,7 +86,7 @@ template<class T, class U> std::unique_ptr<T> dynamic_pointer_cast( std::unique_
}
//const_pointer_cast overload for std::unique_ptr
template<class T, class U> std::unique_ptr<T> const_pointer_cast( std::unique_ptr<U> && r ) BOOST_SP_NOEXCEPT
template<class T, class U> std::unique_ptr<T> const_pointer_cast( std::unique_ptr<U> && r ) noexcept
{
(void) const_cast< T* >( static_cast< U* >( 0 ) );
@@ -106,7 +96,7 @@ template<class T, class U> std::unique_ptr<T> const_pointer_cast( std::unique_pt
}
//reinterpret_pointer_cast overload for std::unique_ptr
template<class T, class U> std::unique_ptr<T> reinterpret_pointer_cast( std::unique_ptr<U> && r ) BOOST_SP_NOEXCEPT
template<class T, class U> std::unique_ptr<T> reinterpret_pointer_cast( std::unique_ptr<U> && r ) noexcept
{
(void) reinterpret_cast< T* >( static_cast< U* >( 0 ) );
@@ -117,6 +107,4 @@ template<class T, class U> std::unique_ptr<T> reinterpret_pointer_cast( std::uni
} // namespace boost
#endif // #if !defined( BOOST_NO_CXX11_SMART_PTR )
#endif //BOOST_POINTER_CAST_HPP

View File

@@ -1,5 +1,5 @@
/*
Copyright 2017 Glen Joseph Fernandes
Copyright 2017-2019 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
@@ -10,38 +10,25 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/smart_ptr/allocate_shared_array.hpp>
#include <boost/smart_ptr/local_shared_ptr.hpp>
#include <boost/smart_ptr/detail/sp_type_traits.hpp>
#include <type_traits>
namespace boost {
namespace detail {
template<class>
struct lsp_if_array { };
template<class T>
struct lsp_if_array<T[]> {
typedef boost::local_shared_ptr<T[]> type;
};
template<class>
struct lsp_if_size_array { };
template<class T, std::size_t N>
struct lsp_if_size_array<T[N]> {
typedef boost::local_shared_ptr<T[N]> type;
};
class lsp_array_base
class BOOST_SYMBOL_VISIBLE lsp_array_base
: public local_counted_base {
public:
void set(sp_counted_base* base) BOOST_SP_NOEXCEPT {
void set(sp_counted_base* base) noexcept {
count_ = shared_count(base);
}
virtual void local_cb_destroy() BOOST_SP_NOEXCEPT {
void local_cb_destroy() noexcept override {
shared_count().swap(count_);
}
virtual shared_count local_cb_get_shared_count() const BOOST_SP_NOEXCEPT {
shared_count local_cb_get_shared_count() const
noexcept override {
return count_;
}
@@ -54,10 +41,10 @@ class lsp_array_state
: public sp_array_state<A> {
public:
template<class U>
lsp_array_state(const U& other, std::size_t size) BOOST_SP_NOEXCEPT
lsp_array_state(const U& other, std::size_t size) noexcept
: sp_array_state<A>(other, size) { }
lsp_array_base& base() BOOST_SP_NOEXCEPT {
lsp_array_base& base() noexcept {
return base_;
}
@@ -70,10 +57,10 @@ class lsp_size_array_state
: public sp_size_array_state<A, N> {
public:
template<class U>
lsp_size_array_state(const U& other, std::size_t size) BOOST_SP_NOEXCEPT
lsp_size_array_state(const U& other, std::size_t size) noexcept
: sp_size_array_state<A, N>(other, size) { }
lsp_array_base& base() BOOST_SP_NOEXCEPT {
lsp_array_base& base() noexcept {
return base_;
}
@@ -84,143 +71,108 @@ private:
} /* detail */
template<class T, class A>
inline typename detail::lsp_if_array<T>::type
inline typename std::enable_if<detail::sp_is_unbounded_array<T>::value,
local_shared_ptr<T> >::type
allocate_local_shared(const A& allocator, std::size_t count)
{
typedef typename detail::sp_array_element<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
typedef typename detail::sp_array_element<T>::type element;
typedef typename allocator_rebind<A, element>::type other;
typedef detail::lsp_array_state<other> state;
typedef detail::sp_array_base<state> base;
std::size_t size = count * detail::sp_array_count<type>::value;
detail::sp_array_result<other, base> result(allocator, size);
detail::sp_array_result<other, base> result(allocator, count);
base* node = result.get();
scalar* start = detail::sp_array_start<base, scalar>(node);
::new(static_cast<void*>(node)) base(allocator, size, start);
element* start = detail::sp_array_start<element>(node);
::new(static_cast<void*>(node)) base(allocator, start, count);
detail::lsp_array_base& local = node->state().base();
local.set(node);
result.release();
return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(),
reinterpret_cast<type*>(start), &local);
return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), start,
&local);
}
template<class T, class A>
inline typename detail::lsp_if_size_array<T>::type
inline typename std::enable_if<detail::sp_is_bounded_array<T>::value,
local_shared_ptr<T> >::type
allocate_local_shared(const A& allocator)
{
enum {
size = detail::sp_array_count<T>::value
count = std::extent<T>::value
};
typedef typename detail::sp_array_element<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
typedef detail::lsp_size_array_state<other, size> state;
typedef typename detail::sp_array_element<T>::type element;
typedef typename allocator_rebind<A, element>::type other;
typedef detail::lsp_size_array_state<other, count> state;
typedef detail::sp_array_base<state> base;
detail::sp_array_result<other, base> result(allocator, size);
detail::sp_array_result<other, base> result(allocator, count);
base* node = result.get();
scalar* start = detail::sp_array_start<base, scalar>(node);
::new(static_cast<void*>(node)) base(allocator, size, start);
element* start = detail::sp_array_start<element>(node);
::new(static_cast<void*>(node)) base(allocator, start, count);
detail::lsp_array_base& local = node->state().base();
local.set(node);
result.release();
return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(),
reinterpret_cast<type*>(start), &local);
return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), start,
&local);
}
template<class T, class A>
inline typename detail::lsp_if_array<T>::type
inline typename std::enable_if<detail::sp_is_unbounded_array<T>::value,
local_shared_ptr<T> >::type
allocate_local_shared(const A& allocator, std::size_t count,
const typename detail::sp_array_element<T>::type& value)
const typename std::remove_extent<T>::type& value)
{
typedef typename detail::sp_array_element<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
typedef typename detail::sp_array_element<T>::type element;
typedef typename allocator_rebind<A, element>::type other;
typedef detail::lsp_array_state<other> state;
typedef detail::sp_array_base<state> base;
std::size_t size = count * detail::sp_array_count<type>::value;
detail::sp_array_result<other, base> result(allocator, size);
detail::sp_array_result<other, base> result(allocator, count);
base* node = result.get();
scalar* start = detail::sp_array_start<base, scalar>(node);
::new(static_cast<void*>(node)) base(allocator, size,
reinterpret_cast<const scalar*>(&value),
detail::sp_array_count<type>::value, start);
element* start = detail::sp_array_start<element>(node);
::new(static_cast<void*>(node)) base(allocator, start, count, value);
detail::lsp_array_base& local = node->state().base();
local.set(node);
result.release();
return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(),
reinterpret_cast<type*>(start), &local);
return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), start,
&local);
}
template<class T, class A>
inline typename detail::lsp_if_size_array<T>::type
inline typename std::enable_if<detail::sp_is_bounded_array<T>::value,
local_shared_ptr<T> >::type
allocate_local_shared(const A& allocator,
const typename detail::sp_array_element<T>::type& value)
const typename std::remove_extent<T>::type& value)
{
enum {
size = detail::sp_array_count<T>::value
count = std::extent<T>::value
};
typedef typename detail::sp_array_element<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
typedef detail::lsp_size_array_state<other, size> state;
typedef typename detail::sp_array_element<T>::type element;
typedef typename allocator_rebind<A, element>::type other;
typedef detail::lsp_size_array_state<other, count> state;
typedef detail::sp_array_base<state> base;
detail::sp_array_result<other, base> result(allocator, size);
detail::sp_array_result<other, base> result(allocator, count);
base* node = result.get();
scalar* start = detail::sp_array_start<base, scalar>(node);
::new(static_cast<void*>(node)) base(allocator, size,
reinterpret_cast<const scalar*>(&value),
detail::sp_array_count<type>::value, start);
element* start = detail::sp_array_start<element>(node);
::new(static_cast<void*>(node)) base(allocator, start, count, value);
detail::lsp_array_base& local = node->state().base();
local.set(node);
result.release();
return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(),
reinterpret_cast<type*>(start), &local);
return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), start,
&local);
}
template<class T, class A>
inline typename detail::lsp_if_array<T>::type
inline typename std::enable_if<detail::sp_is_unbounded_array<T>::value,
local_shared_ptr<T> >::type
allocate_local_shared_noinit(const A& allocator, std::size_t count)
{
typedef typename detail::sp_array_element<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
typedef detail::lsp_array_state<other> state;
typedef detail::sp_array_base<state, false> base;
std::size_t size = count * detail::sp_array_count<type>::value;
detail::sp_array_result<other, base> result(allocator, size);
base* node = result.get();
scalar* start = detail::sp_array_start<base, scalar>(node);
::new(static_cast<void*>(node)) base(detail::sp_default(), allocator,
size, start);
detail::lsp_array_base& local = node->state().base();
local.set(node);
result.release();
return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(),
reinterpret_cast<type*>(start), &local);
return boost::allocate_local_shared<T>(boost::noinit_adapt(allocator),
count);
}
template<class T, class A>
inline typename detail::lsp_if_size_array<T>::type
inline typename std::enable_if<detail::sp_is_bounded_array<T>::value,
local_shared_ptr<T> >::type
allocate_local_shared_noinit(const A& allocator)
{
enum {
size = detail::sp_array_count<T>::value
};
typedef typename detail::sp_array_element<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
typedef detail::lsp_size_array_state<other, size> state;
typedef detail::sp_array_base<state, false> base;
detail::sp_array_result<other, base> result(allocator, size);
base* node = result.get();
scalar* start = detail::sp_array_start<base, scalar>(node);
::new(static_cast<void*>(node)) base(detail::sp_default(), allocator,
size, start);
detail::lsp_array_base& local = node->state().base();
local.set(node);
result.release();
return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(),
reinterpret_cast<type*>(start), &local);
return boost::allocate_local_shared<T>(boost::noinit_adapt(allocator));
}
} /* boost */

View File

@@ -1,5 +1,5 @@
/*
Copyright 2012-2017 Glen Joseph Fernandes
Copyright 2012-2019 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
@@ -8,88 +8,20 @@ Distributed under the Boost Software License, Version 1.0.
#ifndef BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP
#define BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP
#include <boost/core/allocator_access.hpp>
#include <boost/core/alloc_construct.hpp>
#include <boost/core/first_scalar.hpp>
#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/type_traits/alignment_of.hpp>
#include <boost/type_traits/has_trivial_assign.hpp>
#include <boost/type_traits/has_trivial_constructor.hpp>
#include <boost/type_traits/has_trivial_destructor.hpp>
#include <boost/type_traits/type_with_alignment.hpp>
#include <boost/smart_ptr/detail/sp_type_traits.hpp>
#include <type_traits>
namespace boost {
namespace detail {
template<class>
struct sp_if_array { };
template<class T>
struct sp_if_array<T[]> {
typedef boost::shared_ptr<T[]> type;
};
template<class>
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;
};
template<class>
struct sp_array_element { };
template<class T>
struct sp_array_element<T[]> {
typedef T type;
};
template<class T, std::size_t N>
struct sp_array_element<T[N]> {
typedef T type;
};
template<class T>
struct sp_array_scalar {
typedef T type;
};
template<class T, std::size_t N>
struct sp_array_scalar<T[N]> {
typedef typename sp_array_scalar<T>::type type;
};
template<class T, std::size_t N>
struct sp_array_scalar<const T[N]> {
typedef typename sp_array_scalar<T>::type type;
};
template<class T, std::size_t N>
struct sp_array_scalar<volatile T[N]> {
typedef typename sp_array_scalar<T>::type type;
};
template<class T, std::size_t N>
struct sp_array_scalar<const volatile T[N]> {
typedef typename sp_array_scalar<T>::type type;
};
template<class T>
struct sp_array_scalar<T[]> {
typedef typename sp_array_scalar<T>::type type;
};
template<class T>
struct sp_array_scalar<const T[]> {
typedef typename sp_array_scalar<T>::type type;
};
template<class T>
struct sp_array_scalar<volatile T[]> {
typedef typename sp_array_scalar<T>::type type;
};
template<class T>
struct sp_array_scalar<const volatile T[]> {
typedef typename sp_array_scalar<T>::type type;
struct sp_array_element {
typedef typename std::remove_cv<typename
std::remove_extent<T>::type>::type type;
};
template<class T>
@@ -120,248 +52,28 @@ struct sp_align_up {
};
};
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
template<class A, class T>
struct sp_bind_allocator {
typedef typename std::allocator_traits<A>::template rebind_alloc<T> type;
};
#else
template<class A, class T>
struct sp_bind_allocator {
typedef typename A::template rebind<T>::other type;
};
#endif
template<class T>
BOOST_CONSTEXPR inline std::size_t
sp_objects(std::size_t size) BOOST_SP_NOEXCEPT
constexpr inline std::size_t
sp_objects(std::size_t size) noexcept
{
return (size + sizeof(T) - 1) / sizeof(T);
}
template<bool, class = void>
struct sp_enable { };
template<class T>
struct sp_enable<true, T> {
typedef T type;
};
template<bool E, class A, class T>
inline typename sp_enable<!E && boost::has_trivial_destructor<T>::value>::type
sp_array_destroy(A&, T*, std::size_t) BOOST_SP_NOEXCEPT { }
template<bool E, class A, class T>
inline typename sp_enable<!E &&
!boost::has_trivial_destructor<T>::value>::type
sp_array_destroy(A&, T* start, std::size_t size)
{
while (size > 0) {
start[--size].~T();
}
}
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
template<bool E, class A, class T>
inline typename sp_enable<E>::type
sp_array_destroy(A& allocator, T* start, std::size_t size)
{
while (size > 0) {
std::allocator_traits<A>::destroy(allocator, start + --size);
}
}
#endif
template<bool E, class A, class T>
inline typename sp_enable<!E &&
boost::has_trivial_constructor<T>::value &&
boost::has_trivial_assign<T>::value &&
boost::has_trivial_destructor<T>::value>::type
sp_array_construct(A&, T* start, std::size_t size)
{
for (std::size_t i = 0; i < size; ++i) {
start[i] = T();
}
}
template<bool E, class A, class T>
inline typename sp_enable<!E &&
boost::has_trivial_constructor<T>::value &&
boost::has_trivial_assign<T>::value &&
boost::has_trivial_destructor<T>::value>::type
sp_array_construct(A&, T* start, std::size_t size, const T* list,
std::size_t count)
{
for (std::size_t i = 0; i < size; ++i) {
start[i] = list[i % count];
}
}
#if !defined(BOOST_NO_EXCEPTIONS)
template<bool E, class A, class T>
inline typename sp_enable<!E &&
!(boost::has_trivial_constructor<T>::value &&
boost::has_trivial_assign<T>::value &&
boost::has_trivial_destructor<T>::value)>::type
sp_array_construct(A& none, T* start, std::size_t size)
{
std::size_t i = 0;
try {
for (; i < size; ++i) {
::new(static_cast<void*>(start + i)) T();
}
} catch (...) {
sp_array_destroy<E>(none, start, i);
throw;
}
}
template<bool E, class A, class T>
inline typename sp_enable<!E &&
!(boost::has_trivial_constructor<T>::value &&
boost::has_trivial_assign<T>::value &&
boost::has_trivial_destructor<T>::value)>::type
sp_array_construct(A& none, T* start, std::size_t size, const T* list,
std::size_t count)
{
std::size_t i = 0;
try {
for (; i < size; ++i) {
::new(static_cast<void*>(start + i)) T(list[i % count]);
}
} catch (...) {
sp_array_destroy<E>(none, start, i);
throw;
}
}
#else
template<bool E, class A, class T>
inline typename sp_enable<!E &&
!(boost::has_trivial_constructor<T>::value &&
boost::has_trivial_assign<T>::value &&
boost::has_trivial_destructor<T>::value)>::type
sp_array_construct(A&, T* start, std::size_t size)
{
for (std::size_t i = 0; i < size; ++i) {
::new(static_cast<void*>(start + i)) T();
}
}
template<bool E, class A, class T>
inline typename sp_enable<!E &&
!(boost::has_trivial_constructor<T>::value &&
boost::has_trivial_assign<T>::value &&
boost::has_trivial_destructor<T>::value)>::type
sp_array_construct(A&, T* start, std::size_t size, const T* list,
std::size_t count)
{
for (std::size_t i = 0; i < size; ++i) {
::new(static_cast<void*>(start + i)) T(list[i % count]);
}
}
#endif
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
#if !defined(BOOST_NO_EXCEPTIONS)
template<bool E, class A, class T>
inline typename sp_enable<E>::type
sp_array_construct(A& allocator, T* start, std::size_t size)
{
std::size_t i = 0;
try {
for (i = 0; i < size; ++i) {
std::allocator_traits<A>::construct(allocator, start + i);
}
} catch (...) {
sp_array_destroy<E>(allocator, start, i);
throw;
}
}
template<bool E, class A, class T>
inline typename sp_enable<E>::type
sp_array_construct(A& allocator, T* start, std::size_t size, const T* list,
std::size_t count)
{
std::size_t i = 0;
try {
for (i = 0; i < size; ++i) {
std::allocator_traits<A>::construct(allocator, start + i,
list[i % count]);
}
} catch (...) {
sp_array_destroy<E>(allocator, start, i);
throw;
}
}
#else
template<bool E, class A, class T>
inline typename sp_enable<E>::type
sp_array_construct(A& allocator, T* start, std::size_t size)
{
for (std::size_t i = 0; i < size; ++i) {
std::allocator_traits<A>::construct(allocator, start + i);
}
}
template<bool E, class A, class T>
inline typename sp_enable<E>::type
sp_array_construct(A& allocator, T* start, std::size_t size, const T* list,
std::size_t count)
{
for (std::size_t i = 0; i < size; ++i) {
std::allocator_traits<A>::construct(allocator, start + i,
list[i % count]);
}
}
#endif
#endif
template<class A, class T>
inline typename sp_enable<boost::has_trivial_constructor<T>::value>::type
sp_array_default(A&, T*, std::size_t) BOOST_SP_NOEXCEPT { }
#if !defined(BOOST_NO_EXCEPTIONS)
template<class A, class T>
inline typename sp_enable<!boost::has_trivial_constructor<T>::value>::type
sp_array_default(A& none, T* start, std::size_t size)
{
std::size_t i = 0;
try {
for (; i < size; ++i) {
::new(static_cast<void*>(start + i)) T;
}
} catch (...) {
sp_array_destroy<false>(none, start, i);
throw;
}
}
#else
template<bool E, class A, class T>
inline typename sp_enable<!boost::has_trivial_constructor<T>::value>::type
sp_array_default(A&, T* start, std::size_t size)
{
for (std::size_t i = 0; i < size; ++i) {
::new(static_cast<void*>(start + i)) T;
}
}
#endif
template<class A>
class sp_array_state {
public:
typedef A type;
template<class U>
sp_array_state(const U& _allocator, std::size_t _size) BOOST_SP_NOEXCEPT
sp_array_state(const U& _allocator, std::size_t _size) noexcept
: allocator_(_allocator),
size_(_size) { }
A& allocator() BOOST_SP_NOEXCEPT {
A& allocator() noexcept {
return allocator_;
}
std::size_t size() const BOOST_SP_NOEXCEPT {
std::size_t size() const noexcept {
return size_;
}
@@ -376,14 +88,14 @@ public:
typedef A type;
template<class U>
sp_size_array_state(const U& _allocator, std::size_t) BOOST_SP_NOEXCEPT
sp_size_array_state(const U& _allocator, std::size_t) noexcept
: allocator_(_allocator) { }
A& allocator() BOOST_SP_NOEXCEPT {
A& allocator() noexcept {
return allocator_;
}
BOOST_CONSTEXPR std::size_t size() const BOOST_SP_NOEXCEPT {
constexpr std::size_t size() const noexcept {
return N;
}
@@ -391,34 +103,11 @@ private:
A allocator_;
};
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
template<class A>
struct sp_use_construct {
enum {
value = true
};
};
template<class T>
struct sp_use_construct<std::allocator<T> > {
enum {
value = false
};
};
#else
template<class>
struct sp_use_construct {
enum {
value = false
};
};
#endif
template<class T, class U>
struct sp_array_alignment {
enum {
value = sp_max_size<boost::alignment_of<T>::value,
boost::alignment_of<U>::value>::value
value = sp_max_size<std::alignment_of<T>::value,
std::alignment_of<U>::value>::value
};
};
@@ -429,39 +118,32 @@ struct sp_array_offset {
};
};
template<class T, class U>
struct sp_array_storage {
enum {
value = sp_array_alignment<T, U>::value
};
typedef typename boost::type_with_alignment<value>::type type;
};
template<class T, class U>
template<class U, class T>
inline U*
sp_array_start(void* base) BOOST_SP_NOEXCEPT
sp_array_start(T* base) noexcept
{
enum {
size = sp_array_offset<T, U>::value
};
return reinterpret_cast<U*>(static_cast<char*>(base) + size);
return reinterpret_cast<U*>(reinterpret_cast<char*>(base) + size);
}
template<class A, class T>
class sp_array_creator {
typedef typename A::value_type scalar;
typedef typename A::value_type element;
enum {
offset = sp_array_offset<T, scalar>::value
offset = sp_array_offset<T, element>::value
};
typedef typename sp_array_storage<T, scalar>::type type;
typedef typename sp_type_with_alignment<sp_array_alignment<T,
element>::value>::type type;
public:
template<class U>
sp_array_creator(const U& other, std::size_t size) BOOST_SP_NOEXCEPT
sp_array_creator(const U& other, std::size_t size) noexcept
: other_(other),
size_(sp_objects<type>(offset + sizeof(scalar) * size)) { }
size_(sp_objects<type>(offset + sizeof(element) * size)) { }
T* create() {
return reinterpret_cast<T*>(other_.allocate(size_));
@@ -472,14 +154,12 @@ public:
}
private:
typename sp_bind_allocator<A, type>::type other_;
typename boost::allocator_rebind<A, type>::type other_;
std::size_t size_;
};
struct sp_default { };
template<class T, bool E = sp_use_construct<T>::value>
class sp_array_base
template<class T>
class BOOST_SYMBOL_VISIBLE sp_array_base
: public sp_counted_base {
typedef typename T::type allocator;
@@ -487,50 +167,51 @@ public:
typedef typename allocator::value_type type;
template<class A>
sp_array_base(const A& other, std::size_t size, type* start)
sp_array_base(const A& other, type* start, std::size_t size)
: state_(other, size) {
sp_array_construct<E>(state_.allocator(), start, state_.size());
boost::alloc_construct_n(state_.allocator(),
boost::first_scalar(start),
state_.size() * sp_array_count<type>::value);
}
template<class A>
sp_array_base(const A& other, std::size_t size, const type* list,
std::size_t count, type* start)
template<class A, class U>
sp_array_base(const A& other, type* start, std::size_t size, const U& list)
: state_(other, size) {
sp_array_construct<E>(state_.allocator(), start, state_.size(), list,
count);
enum {
count = sp_array_count<type>::value
};
boost::alloc_construct_n(state_.allocator(),
boost::first_scalar(start), state_.size() * count,
boost::first_scalar(&list), count);
}
template<class A>
sp_array_base(sp_default, const A& other, std::size_t size, type* start)
: state_(other, size) {
sp_array_default(state_.allocator(), start, state_.size());
}
T& state() BOOST_SP_NOEXCEPT {
T& state() noexcept {
return state_;
}
virtual void dispose() {
sp_array_destroy<E>(state_.allocator(),
sp_array_start<sp_array_base, type>(this), state_.size());
void dispose() noexcept override {
boost::alloc_destroy_n(state_.allocator(),
boost::first_scalar(sp_array_start<type>(this)),
state_.size() * sp_array_count<type>::value);
}
virtual void destroy() {
void destroy() noexcept override {
sp_array_creator<allocator, sp_array_base> other(state_.allocator(),
state_.size());
this->~sp_array_base();
other.destroy(this);
}
virtual void* get_deleter(const sp_typeinfo&) {
void* get_deleter(const sp_typeinfo_&) noexcept override {
return 0;
}
virtual void* get_local_deleter(const sp_typeinfo&) {
void* get_local_deleter(const sp_typeinfo_&)
noexcept override {
return 0;
}
virtual void* get_untyped_deleter() {
void* get_untyped_deleter() noexcept override {
return 0;
}
@@ -552,11 +233,11 @@ public:
}
}
T* get() const {
T* get() const noexcept {
return result_;
}
void release() {
void release() noexcept {
result_ = 0;
}
@@ -571,131 +252,93 @@ private:
} /* detail */
template<class T, class A>
inline typename detail::sp_if_array<T>::type
inline typename std::enable_if<detail::sp_is_unbounded_array<T>::value, shared_ptr<T> >::type
allocate_shared(const A& allocator, std::size_t count)
{
typedef typename detail::sp_array_element<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
typedef typename detail::sp_array_element<T>::type element;
typedef typename allocator_rebind<A, element>::type other;
typedef detail::sp_array_state<other> state;
typedef detail::sp_array_base<state> base;
std::size_t size = count * detail::sp_array_count<type>::value;
detail::sp_array_result<other, base> result(allocator, size);
detail::sp_counted_base* node = result.get();
scalar* start = detail::sp_array_start<base, scalar>(node);
::new(static_cast<void*>(node)) base(allocator, size, start);
detail::sp_array_result<other, base> result(allocator, count);
base* node = result.get();
element* start = detail::sp_array_start<element>(node);
::new(static_cast<void*>(node)) base(allocator, start, count);
result.release();
return shared_ptr<T>(detail::sp_internal_constructor_tag(),
reinterpret_cast<type*>(start), detail::shared_count(node));
return shared_ptr<T>(detail::sp_internal_constructor_tag(), start,
detail::shared_count(static_cast<detail::sp_counted_base*>(node)));
}
template<class T, class A>
inline typename detail::sp_if_size_array<T>::type
inline typename std::enable_if<detail::sp_is_bounded_array<T>::value, shared_ptr<T> >::type
allocate_shared(const A& allocator)
{
enum {
size = detail::sp_array_count<T>::value
count = std::extent<T>::value
};
typedef typename detail::sp_array_element<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
typedef detail::sp_size_array_state<other, size> state;
typedef typename detail::sp_array_element<T>::type element;
typedef typename allocator_rebind<A, element>::type other;
typedef detail::sp_size_array_state<other, std::extent<T>::value> state;
typedef detail::sp_array_base<state> base;
detail::sp_array_result<other, base> result(allocator, size);
detail::sp_counted_base* node = result.get();
scalar* start = detail::sp_array_start<base, scalar>(node);
::new(static_cast<void*>(node)) base(allocator, size, start);
detail::sp_array_result<other, base> result(allocator, count);
base* node = result.get();
element* start = detail::sp_array_start<element>(node);
::new(static_cast<void*>(node)) base(allocator, start, count);
result.release();
return shared_ptr<T>(detail::sp_internal_constructor_tag(),
reinterpret_cast<type*>(start), detail::shared_count(node));
return shared_ptr<T>(detail::sp_internal_constructor_tag(), start,
detail::shared_count(static_cast<detail::sp_counted_base*>(node)));
}
template<class T, class A>
inline typename detail::sp_if_array<T>::type
inline typename std::enable_if<detail::sp_is_unbounded_array<T>::value, shared_ptr<T> >::type
allocate_shared(const A& allocator, std::size_t count,
const typename detail::sp_array_element<T>::type& value)
const typename std::remove_extent<T>::type& value)
{
typedef typename detail::sp_array_element<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
typedef typename detail::sp_array_element<T>::type element;
typedef typename allocator_rebind<A, element>::type other;
typedef detail::sp_array_state<other> state;
typedef detail::sp_array_base<state> base;
std::size_t size = count * detail::sp_array_count<type>::value;
detail::sp_array_result<other, base> result(allocator, size);
detail::sp_counted_base* node = result.get();
scalar* start = detail::sp_array_start<base, scalar>(node);
::new(static_cast<void*>(node)) base(allocator, size,
reinterpret_cast<const scalar*>(&value),
detail::sp_array_count<type>::value, start);
detail::sp_array_result<other, base> result(allocator, count);
base* node = result.get();
element* start = detail::sp_array_start<element>(node);
::new(static_cast<void*>(node)) base(allocator, start, count, value);
result.release();
return shared_ptr<T>(detail::sp_internal_constructor_tag(),
reinterpret_cast<type*>(start), detail::shared_count(node));
return shared_ptr<T>(detail::sp_internal_constructor_tag(), start,
detail::shared_count(static_cast<detail::sp_counted_base*>(node)));
}
template<class T, class A>
inline typename detail::sp_if_size_array<T>::type
inline typename std::enable_if<detail::sp_is_bounded_array<T>::value, shared_ptr<T> >::type
allocate_shared(const A& allocator,
const typename detail::sp_array_element<T>::type& value)
const typename std::remove_extent<T>::type& value)
{
enum {
size = detail::sp_array_count<T>::value
count = std::extent<T>::value
};
typedef typename detail::sp_array_element<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
typedef detail::sp_size_array_state<other, size> state;
typedef typename detail::sp_array_element<T>::type element;
typedef typename allocator_rebind<A, element>::type other;
typedef detail::sp_size_array_state<other, std::extent<T>::value> state;
typedef detail::sp_array_base<state> base;
detail::sp_array_result<other, base> result(allocator, size);
detail::sp_counted_base* node = result.get();
scalar* start = detail::sp_array_start<base, scalar>(node);
::new(static_cast<void*>(node)) base(allocator, size,
reinterpret_cast<const scalar*>(&value),
detail::sp_array_count<type>::value, start);
detail::sp_array_result<other, base> result(allocator, count);
base* node = result.get();
element* start = detail::sp_array_start<element>(node);
::new(static_cast<void*>(node)) base(allocator, start, count, value);
result.release();
return shared_ptr<T>(detail::sp_internal_constructor_tag(),
reinterpret_cast<type*>(start), detail::shared_count(node));
return shared_ptr<T>(detail::sp_internal_constructor_tag(), start,
detail::shared_count(static_cast<detail::sp_counted_base*>(node)));
}
template<class T, class A>
inline typename detail::sp_if_array<T>::type
inline typename std::enable_if<detail::sp_is_unbounded_array<T>::value, shared_ptr<T> >::type
allocate_shared_noinit(const A& allocator, std::size_t count)
{
typedef typename detail::sp_array_element<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
typedef detail::sp_array_state<other> state;
typedef detail::sp_array_base<state, false> base;
std::size_t size = count * detail::sp_array_count<type>::value;
detail::sp_array_result<other, base> result(allocator, size);
detail::sp_counted_base* node = result.get();
scalar* start = detail::sp_array_start<base, scalar>(node);
::new(static_cast<void*>(node)) base(detail::sp_default(), allocator,
size, start);
result.release();
return shared_ptr<T>(detail::sp_internal_constructor_tag(),
reinterpret_cast<type*>(start), detail::shared_count(node));
return boost::allocate_shared<T>(boost::noinit_adapt(allocator), count);
}
template<class T, class A>
inline typename detail::sp_if_size_array<T>::type
inline typename std::enable_if<detail::sp_is_bounded_array<T>::value, shared_ptr<T> >::type
allocate_shared_noinit(const A& allocator)
{
enum {
size = detail::sp_array_count<T>::value
};
typedef typename detail::sp_array_element<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
typedef detail::sp_size_array_state<other, size> state;
typedef detail::sp_array_base<state, false> base;
detail::sp_array_result<other, base> result(allocator, size);
detail::sp_counted_base* node = result.get();
scalar* start = detail::sp_array_start<base, scalar>(node);
::new(static_cast<void*>(node)) base(detail::sp_default(), allocator,
size, start);
result.release();
return shared_ptr<T>(detail::sp_internal_constructor_tag(),
reinterpret_cast<type*>(start), detail::shared_count(node));
return boost::allocate_shared<T>(boost::noinit_adapt(allocator));
}
} /* boost */

View File

@@ -0,0 +1,466 @@
/*
Copyright 2019-2021 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_SMART_PTR_ALLOCATE_UNIQUE_HPP
#define BOOST_SMART_PTR_ALLOCATE_UNIQUE_HPP
#include <boost/core/allocator_access.hpp>
#include <boost/core/alloc_construct.hpp>
#include <boost/core/empty_value.hpp>
#include <boost/core/first_scalar.hpp>
#include <boost/core/noinit_adaptor.hpp>
#include <boost/core/pointer_traits.hpp>
#include <boost/smart_ptr/detail/sp_type_traits.hpp>
#include <boost/config.hpp>
#include <memory>
#include <utility>
#include <cstddef>
#include <type_traits>
namespace boost {
namespace detail {
template<class T>
struct sp_alloc_size {
static constexpr std::size_t value = 1;
};
template<class T>
struct sp_alloc_size<T[]> {
static constexpr std::size_t value = sp_alloc_size<T>::value;
};
template<class T, std::size_t N>
struct sp_alloc_size<T[N]> {
static constexpr std::size_t value = N * sp_alloc_size<T>::value;
};
template<class T>
struct sp_alloc_result {
typedef T type;
};
template<class T, std::size_t N>
struct sp_alloc_result<T[N]> {
typedef T type[];
};
template<class T>
struct sp_alloc_value {
typedef typename std::remove_cv<typename
std::remove_extent<T>::type>::type type;
};
template<class T, class P>
class sp_alloc_ptr {
public:
typedef T element_type;
sp_alloc_ptr() noexcept
: p_() { }
#if defined(BOOST_MSVC) && BOOST_MSVC == 1600
sp_alloc_ptr(T* p) noexcept
: p_(const_cast<typename std::remove_cv<T>::type*>(p)) { }
#endif
sp_alloc_ptr(std::size_t, P p) noexcept
: p_(p) { }
sp_alloc_ptr(std::nullptr_t) noexcept
: p_() { }
T& operator*() const {
return *p_;
}
T* operator->() const noexcept {
return boost::to_address(p_);
}
explicit operator bool() const noexcept {
return !!p_;
}
bool operator!() const noexcept {
return !p_;
}
P ptr() const noexcept {
return p_;
}
static constexpr std::size_t size() noexcept {
return 1;
}
#if defined(BOOST_MSVC) && BOOST_MSVC < 1910
static sp_alloc_ptr pointer_to(T& v) {
return sp_alloc_ptr(1,
std::pointer_traits<P>::pointer_to(const_cast<typename
std::remove_cv<T>::type&>(v)));
}
#endif
private:
P p_;
};
template<class T, class P>
class sp_alloc_ptr<T[], P> {
public:
typedef T element_type;
sp_alloc_ptr() noexcept
: p_() { }
sp_alloc_ptr(std::size_t n, P p) noexcept
: p_(p)
, n_(n) { }
sp_alloc_ptr(std::nullptr_t) noexcept
: p_() { }
T& operator[](std::size_t i) const {
return p_[i];
}
explicit operator bool() const noexcept {
return !!p_;
}
bool operator!() const noexcept {
return !p_;
}
P ptr() const noexcept {
return p_;
}
std::size_t size() const noexcept {
return n_;
}
#if defined(BOOST_MSVC) && BOOST_MSVC < 1910
static sp_alloc_ptr pointer_to(T& v) {
return sp_alloc_ptr(n_,
std::pointer_traits<P>::pointer_to(const_cast<typename
std::remove_cv<T>::type&>(v)));
}
#endif
private:
P p_;
std::size_t n_;
};
template<class T, std::size_t N, class P>
class sp_alloc_ptr<T[N], P> {
public:
typedef T element_type;
sp_alloc_ptr() noexcept
: p_() { }
sp_alloc_ptr(std::size_t, P p) noexcept
: p_(p) { }
sp_alloc_ptr(std::nullptr_t) noexcept
: p_() { }
T& operator[](std::size_t i) const {
return p_[i];
}
explicit operator bool() const noexcept {
return !!p_;
}
bool operator!() const noexcept {
return !p_;
}
P ptr() const noexcept {
return p_;
}
static constexpr std::size_t size() noexcept {
return N;
}
#if defined(BOOST_MSVC) && BOOST_MSVC < 1910
static sp_alloc_ptr pointer_to(T& v) {
return sp_alloc_ptr(N,
std::pointer_traits<P>::pointer_to(const_cast<typename
std::remove_cv<T>::type&>(v)));
}
#endif
private:
P p_;
};
template<class T, class P>
inline bool
operator==(const sp_alloc_ptr<T, P>& lhs, const sp_alloc_ptr<T, P>& rhs)
{
return lhs.ptr() == rhs.ptr();
}
template<class T, class P>
inline bool
operator!=(const sp_alloc_ptr<T, P>& lhs, const sp_alloc_ptr<T, P>& rhs)
{
return !(lhs == rhs);
}
template<class T, class P>
inline bool
operator==(const sp_alloc_ptr<T, P>& lhs,
std::nullptr_t) noexcept
{
return !lhs.ptr();
}
template<class T, class P>
inline bool
operator==(std::nullptr_t,
const sp_alloc_ptr<T, P>& rhs) noexcept
{
return !rhs.ptr();
}
template<class T, class P>
inline bool
operator!=(const sp_alloc_ptr<T, P>& lhs,
std::nullptr_t) noexcept
{
return !!lhs.ptr();
}
template<class T, class P>
inline bool
operator!=(std::nullptr_t,
const sp_alloc_ptr<T, P>& rhs) noexcept
{
return !!rhs.ptr();
}
template<class A>
inline void
sp_alloc_clear(A& a, typename boost::allocator_pointer<A>::type p, std::size_t,
std::false_type)
{
boost::alloc_destroy(a, boost::to_address(p));
}
template<class A>
inline void
sp_alloc_clear(A& a, typename boost::allocator_pointer<A>::type p,
std::size_t n, std::true_type)
{
#if defined(BOOST_MSVC) && BOOST_MSVC < 1800
if (!p) {
return;
}
#endif
boost::alloc_destroy_n(a, boost::first_scalar(boost::to_address(p)),
n * sp_alloc_size<typename A::value_type>::value);
}
} /* detail */
template<class T, class A>
class alloc_deleter
: empty_value<typename allocator_rebind<A,
typename detail::sp_alloc_value<T>::type>::type> {
typedef typename allocator_rebind<A,
typename detail::sp_alloc_value<T>::type>::type allocator;
typedef empty_value<allocator> base;
public:
typedef detail::sp_alloc_ptr<T,
typename allocator_pointer<allocator>::type> pointer;
explicit alloc_deleter(const allocator& a) noexcept
: base(empty_init_t(), a) { }
void operator()(pointer p) {
detail::sp_alloc_clear(base::get(), p.ptr(), p.size(), std::is_array<T>());
base::get().deallocate(p.ptr(), p.size());
}
};
template<class T, class A>
using alloc_noinit_deleter = alloc_deleter<T, noinit_adaptor<A> >;
namespace detail {
template<class T, class A>
class sp_alloc_make {
public:
typedef typename boost::allocator_rebind<A,
typename sp_alloc_value<T>::type>::type allocator;
private:
typedef boost::alloc_deleter<T, A> deleter;
public:
typedef std::unique_ptr<typename sp_alloc_result<T>::type, deleter> type;
sp_alloc_make(const A& a, std::size_t n)
: a_(a)
, n_(n)
, p_(a_.allocate(n)) { }
~sp_alloc_make() {
if (p_) {
a_.deallocate(p_, n_);
}
}
typename allocator::value_type* get() const noexcept {
return boost::to_address(p_);
}
allocator& state() noexcept {
return a_;
}
type release() noexcept {
pointer p = p_;
p_ = pointer();
return type(typename deleter::pointer(n_, p), deleter(a_));
}
private:
typedef typename boost::allocator_pointer<allocator>::type pointer;
allocator a_;
std::size_t n_;
pointer p_;
};
} /* detail */
template<class T, class A>
inline typename std::enable_if<!std::is_array<T>::value,
std::unique_ptr<T, alloc_deleter<T, A> > >::type
allocate_unique(const A& alloc)
{
detail::sp_alloc_make<T, A> c(alloc, 1);
boost::alloc_construct(c.state(), c.get());
return c.release();
}
template<class T, class A, class... Args>
inline typename std::enable_if<!std::is_array<T>::value,
std::unique_ptr<T, alloc_deleter<T, A> > >::type
allocate_unique(const A& alloc, Args&&... args)
{
detail::sp_alloc_make<T, A> c(alloc, 1);
boost::alloc_construct(c.state(), c.get(), std::forward<Args>(args)...);
return c.release();
}
template<class T, class A>
inline typename std::enable_if<!std::is_array<T>::value,
std::unique_ptr<T, alloc_deleter<T, A> > >::type
allocate_unique(const A& alloc, typename detail::sp_type_identity<T>::type&& value)
{
detail::sp_alloc_make<T, A> c(alloc, 1);
boost::alloc_construct(c.state(), c.get(), std::move(value));
return c.release();
}
template<class T, class A>
inline typename std::enable_if<!std::is_array<T>::value,
std::unique_ptr<T, alloc_deleter<T, noinit_adaptor<A> > > >::type
allocate_unique_noinit(const A& alloc)
{
return boost::allocate_unique<T, noinit_adaptor<A> >(alloc);
}
template<class T, class A>
inline typename std::enable_if<detail::sp_is_unbounded_array<T>::value,
std::unique_ptr<T, alloc_deleter<T, A> > >::type
allocate_unique(const A& alloc, std::size_t size)
{
detail::sp_alloc_make<T, A> c(alloc, size);
boost::alloc_construct_n(c.state(), boost::first_scalar(c.get()),
size * detail::sp_alloc_size<T>::value);
return c.release();
}
template<class T, class A>
inline typename std::enable_if<detail::sp_is_bounded_array<T>::value,
std::unique_ptr<typename detail::sp_alloc_result<T>::type,
alloc_deleter<T, A> > >::type
allocate_unique(const A& alloc)
{
detail::sp_alloc_make<T, A> c(alloc, std::extent<T>::value);
boost::alloc_construct_n(c.state(), boost::first_scalar(c.get()),
detail::sp_alloc_size<T>::value);
return c.release();
}
template<class T, class A>
inline typename std::enable_if<detail::sp_is_unbounded_array<T>::value,
std::unique_ptr<T, alloc_deleter<T, noinit_adaptor<A> > > >::type
allocate_unique_noinit(const A& alloc, std::size_t size)
{
return boost::allocate_unique<T, noinit_adaptor<A> >(alloc, size);
}
template<class T, class A>
inline typename std::enable_if<detail::sp_is_bounded_array<T>::value,
std::unique_ptr<typename detail::sp_alloc_result<T>::type,
alloc_deleter<T, noinit_adaptor<A> > > >::type
allocate_unique_noinit(const A& alloc)
{
return boost::allocate_unique<T, noinit_adaptor<A> >(alloc);
}
template<class T, class A>
inline typename std::enable_if<detail::sp_is_unbounded_array<T>::value,
std::unique_ptr<T, alloc_deleter<T, A> > >::type
allocate_unique(const A& alloc, std::size_t size,
const typename std::remove_extent<T>::type& value)
{
detail::sp_alloc_make<T, A> c(alloc, size);
boost::alloc_construct_n(c.state(), boost::first_scalar(c.get()),
size * detail::sp_alloc_size<T>::value, boost::first_scalar(&value),
detail::sp_alloc_size<typename std::remove_extent<T>::type>::value);
return c.release();
}
template<class T, class A>
inline typename std::enable_if<detail::sp_is_bounded_array<T>::value,
std::unique_ptr<typename detail::sp_alloc_result<T>::type,
alloc_deleter<T, A> > >::type
allocate_unique(const A& alloc,
const typename std::remove_extent<T>::type& value)
{
detail::sp_alloc_make<T, A> c(alloc, std::extent<T>::value);
boost::alloc_construct_n(c.state(), boost::first_scalar(c.get()),
detail::sp_alloc_size<T>::value, boost::first_scalar(&value),
detail::sp_alloc_size<typename std::remove_extent<T>::type>::value);
return c.release();
}
template<class T, class U, class A>
inline typename allocator_pointer<typename allocator_rebind<A,
typename detail::sp_alloc_value<T>::type>::type>::type
get_allocator_pointer(const std::unique_ptr<T,
alloc_deleter<U, A> >& p) noexcept
{
return p.get().ptr();
}
} /* boost */
#endif

View File

@@ -33,7 +33,7 @@ private:
private:
bool compare_exchange( shared_ptr<T>& v, shared_ptr<T> w ) BOOST_SP_NOEXCEPT
bool compare_exchange( shared_ptr<T>& v, shared_ptr<T> w ) noexcept
{
l_.lock();
@@ -57,34 +57,16 @@ private:
public:
#if !defined( BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX ) && !defined( BOOST_NO_CXX11_CONSTEXPR )
constexpr atomic_shared_ptr() BOOST_SP_NOEXCEPT: l_ BOOST_DETAIL_SPINLOCK_INIT
constexpr atomic_shared_ptr() noexcept: l_ BOOST_DETAIL_SPINLOCK_INIT
{
}
#else
atomic_shared_ptr() BOOST_SP_NOEXCEPT
atomic_shared_ptr( shared_ptr<T> p ) noexcept
: p_( std::move( p ) ), l_ BOOST_DETAIL_SPINLOCK_INIT
{
boost::detail::spinlock init = BOOST_DETAIL_SPINLOCK_INIT;
std::memcpy( &l_, &init, sizeof( init ) );
}
#endif
atomic_shared_ptr( shared_ptr<T> p ) BOOST_SP_NOEXCEPT
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
: p_( std::move( p ) )
#else
: p_( p )
#endif
{
boost::detail::spinlock init = BOOST_DETAIL_SPINLOCK_INIT;
std::memcpy( &l_, &init, sizeof( init ) );
}
atomic_shared_ptr& operator=( shared_ptr<T> r ) BOOST_SP_NOEXCEPT
atomic_shared_ptr& operator=( shared_ptr<T> r ) noexcept
{
boost::detail::spinlock::scoped_lock lock( l_ );
p_.swap( r );
@@ -92,140 +74,120 @@ public:
return *this;
}
BOOST_CONSTEXPR bool is_lock_free() const BOOST_SP_NOEXCEPT
constexpr bool is_lock_free() const noexcept
{
return false;
}
shared_ptr<T> load() const BOOST_SP_NOEXCEPT
shared_ptr<T> load() const noexcept
{
boost::detail::spinlock::scoped_lock lock( l_ );
return p_;
}
template<class M> shared_ptr<T> load( M ) const BOOST_SP_NOEXCEPT
template<class M> shared_ptr<T> load( M ) const noexcept
{
boost::detail::spinlock::scoped_lock lock( l_ );
return p_;
}
operator shared_ptr<T>() const BOOST_SP_NOEXCEPT
operator shared_ptr<T>() const noexcept
{
boost::detail::spinlock::scoped_lock lock( l_ );
return p_;
}
void store( shared_ptr<T> r ) BOOST_SP_NOEXCEPT
void store( shared_ptr<T> r ) noexcept
{
boost::detail::spinlock::scoped_lock lock( l_ );
p_.swap( r );
}
template<class M> void store( shared_ptr<T> r, M ) BOOST_SP_NOEXCEPT
template<class M> void store( shared_ptr<T> r, M ) noexcept
{
boost::detail::spinlock::scoped_lock lock( l_ );
p_.swap( r );
}
shared_ptr<T> exchange( shared_ptr<T> r ) BOOST_SP_NOEXCEPT
shared_ptr<T> exchange( shared_ptr<T> r ) noexcept
{
{
boost::detail::spinlock::scoped_lock lock( l_ );
p_.swap( r );
}
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
return std::move( r );
#else
return r;
#endif
}
template<class M> shared_ptr<T> exchange( shared_ptr<T> r, M ) BOOST_SP_NOEXCEPT
template<class M> shared_ptr<T> exchange( shared_ptr<T> r, M ) noexcept
{
{
boost::detail::spinlock::scoped_lock lock( l_ );
p_.swap( r );
}
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
return std::move( r );
#else
return r;
#endif
}
template<class M> bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w, M, M ) BOOST_SP_NOEXCEPT
template<class M> bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w, M, M ) noexcept
{
return compare_exchange( v, w );
}
template<class M> bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w, M ) BOOST_SP_NOEXCEPT
template<class M> bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w, M ) noexcept
{
return compare_exchange( v, w );
}
bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w ) BOOST_SP_NOEXCEPT
bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w ) noexcept
{
return compare_exchange( v, w );
}
template<class M> bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w, M, M ) BOOST_SP_NOEXCEPT
template<class M> bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w, M, M ) noexcept
{
return compare_exchange( v, w );
}
template<class M> bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w, M ) BOOST_SP_NOEXCEPT
template<class M> bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w, M ) noexcept
{
return compare_exchange( v, w );
}
bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w ) BOOST_SP_NOEXCEPT
bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w ) noexcept
{
return compare_exchange( v, w );
}
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
template<class M> bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w, M, M ) BOOST_SP_NOEXCEPT
template<class M> bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w, M, M ) noexcept
{
return compare_exchange( v, std::move( w ) );
}
template<class M> bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w, M ) BOOST_SP_NOEXCEPT
template<class M> bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w, M ) noexcept
{
return compare_exchange( v, std::move( w ) );
}
bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w ) BOOST_SP_NOEXCEPT
bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w ) noexcept
{
return compare_exchange( v, std::move( w ) );
}
template<class M> bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w, M, M ) BOOST_SP_NOEXCEPT
template<class M> bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w, M, M ) noexcept
{
return compare_exchange( v, std::move( w ) );
}
template<class M> bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w, M ) BOOST_SP_NOEXCEPT
template<class M> bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w, M ) noexcept
{
return compare_exchange( v, std::move( w ) );
}
bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w ) BOOST_SP_NOEXCEPT
bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w ) noexcept
{
return compare_exchange( v, std::move( w ) );
}
#endif
};
} // namespace boost

View File

@@ -20,23 +20,9 @@
#include <boost/config.hpp>
#include <exception>
#ifdef __BORLANDC__
# pragma warn -8026 // Functions with excep. spec. are not expanded inline
#endif
namespace boost
{
// The standard library that comes with Borland C++ 5.5.1, 5.6.4
// defines std::exception and its members as having C calling
// convention (-pc). When the definition of bad_weak_ptr
// is compiled with -ps, the compiler issues an error.
// Hence, the temporary #pragma option -pc below.
#if defined(__BORLANDC__) && __BORLANDC__ <= 0x564
# pragma option push -pc
#endif
#if defined(BOOST_CLANG)
// Intel C++ on Mac defines __clang__ but doesn't support the pragma
# pragma clang diagnostic push
@@ -47,7 +33,7 @@ class bad_weak_ptr: public std::exception
{
public:
virtual char const * what() const throw()
char const * what() const noexcept override
{
return "tr1::bad_weak_ptr";
}
@@ -57,14 +43,6 @@ public:
# pragma clang diagnostic pop
#endif
#if defined(__BORLANDC__) && __BORLANDC__ <= 0x564
# pragma option pop
#endif
} // namespace boost
#ifdef __BORLANDC__
# pragma warn .8026 // Functions with excep. spec. are not expanded inline
#endif
#endif // #ifndef BOOST_SMART_PTR_BAD_WEAK_PTR_HPP_INCLUDED

View File

@@ -43,8 +43,10 @@
// Memory Ordering: acquire/release
//
#include <boost/smart_ptr/detail/sp_has_gcc_intrinsics.hpp>
#include <boost/smart_ptr/detail/sp_has_sync_intrinsics.hpp>
#include <boost/smart_ptr/detail/deprecated_macros.hpp>
#include <boost/config.hpp>
#include <boost/smart_ptr/detail/sp_has_sync.hpp>
#if defined( BOOST_AC_DISABLE_THREADS )
# include <boost/smart_ptr/detail/atomic_count_nt.hpp>
@@ -73,15 +75,18 @@
#elif defined( BOOST_DISABLE_THREADS ) && !defined( BOOST_SP_ENABLE_THREADS ) && !defined( BOOST_DISABLE_WIN32 )
# include <boost/smart_ptr/detail/atomic_count_nt.hpp>
#elif defined( BOOST_SP_HAS_GCC_INTRINSICS )
# include <boost/smart_ptr/detail/atomic_count_gcc_atomic.hpp>
#elif !defined( BOOST_NO_CXX11_HDR_ATOMIC )
# include <boost/smart_ptr/detail/atomic_count_std_atomic.hpp>
#elif defined( BOOST_SP_HAS_SYNC_INTRINSICS )
# include <boost/smart_ptr/detail/atomic_count_sync.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 )
# 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>

View File

@@ -23,6 +23,13 @@
# include <bits/atomicity.h>
#endif
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using libstdc++ atomic_count")
#endif
namespace boost
{

View File

@@ -0,0 +1,63 @@
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_ATOMIC_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_ATOMIC_HPP_INCLUDED
// boost/detail/atomic_count_gcc_atomic.hpp
//
// atomic_count for g++ 4.7+
//
// Copyright 2007, 2020 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/cstdint.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using __atomic atomic_count")
#endif
namespace boost
{
namespace detail
{
class atomic_count
{
public:
explicit atomic_count( long v ): value_( static_cast< boost::int_least32_t >( v ) )
{
}
long operator++()
{
return __atomic_add_fetch( &value_, +1, __ATOMIC_ACQ_REL );
}
long operator--()
{
return __atomic_add_fetch( &value_, -1, __ATOMIC_ACQ_REL );
}
operator long() const
{
return __atomic_load_n( &value_, __ATOMIC_ACQUIRE );
}
private:
atomic_count(atomic_count const &);
atomic_count & operator=(atomic_count const &);
boost::int_least32_t value_;
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_ATOMIC_HPP_INCLUDED

View File

@@ -13,6 +13,17 @@
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/smart_ptr/detail/sp_obsolete.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using g++/x86 atomic_count")
#endif
BOOST_SP_OBSOLETE()
namespace boost
{

View File

@@ -15,6 +15,13 @@
// http://www.boost.org/LICENSE_1_0.txt
//
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using single-threaded, non-atomic atomic_count")
#endif
namespace boost
{

View File

@@ -14,6 +14,13 @@
#include <boost/assert.hpp>
#include <pthread.h>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using pthread_mutex atomic_count")
#endif
//
// The generic pthread_mutex-based implementation sometimes leads to
// inefficiencies. Example: a class with two atomic_count members

View File

@@ -1,59 +0,0 @@
#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SOLARIS_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SOLARIS_HPP_INCLUDED
//
// boost/detail/atomic_count_solaris.hpp
// based on: boost/detail/atomic_count_win32.hpp
//
// Copyright (c) 2001-2005 Peter Dimov
// Copyright (c) 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)
//
#include <atomic.h>
namespace boost
{
namespace detail
{
class atomic_count
{
public:
explicit atomic_count( uint32_t v ): value_( v )
{
}
long operator++()
{
return atomic_inc_32_nv( &value_ );
}
long operator--()
{
return atomic_dec_32_nv( &value_ );
}
operator uint32_t() const
{
return static_cast<uint32_t const volatile &>( value_ );
}
private:
atomic_count( atomic_count const & );
atomic_count & operator=( atomic_count const & );
uint32_t value_;
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SOLARIS_HPP_INCLUDED

View File

@@ -13,6 +13,13 @@
#include <boost/smart_ptr/detail/spinlock_pool.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using spinlock-based atomic_count")
#endif
namespace boost
{

View File

@@ -16,6 +16,13 @@
#include <atomic>
#include <cstdint>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using std::atomic atomic_count")
#endif
namespace boost
{
@@ -26,7 +33,7 @@ class atomic_count
{
public:
explicit atomic_count( long v ): value_( v )
explicit atomic_count( long v ): value_( static_cast< std::int_least32_t >( v ) )
{
}

View File

@@ -15,10 +15,19 @@
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/cstdint.hpp>
#if defined( __ia64__ ) && defined( __INTEL_COMPILER )
# include <ia64intrin.h>
#endif
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using __sync atomic_count")
#endif
namespace boost
{
@@ -29,7 +38,9 @@ class atomic_count
{
public:
explicit atomic_count( long v ) : value_( v ) {}
explicit atomic_count( long v ): value_( static_cast< boost::int_least32_t >( v ) )
{
}
long operator++()
{
@@ -51,7 +62,7 @@ private:
atomic_count(atomic_count const &);
atomic_count & operator=(atomic_count const &);
mutable long value_;
mutable boost::int_least32_t value_;
};
} // namespace detail

View File

@@ -19,6 +19,13 @@
#include <boost/smart_ptr/detail/sp_interlocked.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using Win32 atomic_count")
#endif
namespace boost
{

View File

@@ -0,0 +1,52 @@
#ifndef BOOST_SMART_PTR_DETAIL_DEPRECATED_MACROS_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_DEPRECATED_MACROS_HPP_INCLUDED
// Copyright 2024 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/config/pragma_message.hpp>
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
BOOST_PRAGMA_MESSAGE("The macro BOOST_SP_ENABLE_DEBUG_HOOKS has been deprecated in 1.87 and support for it will be removed.")
#endif
#if defined(BOOST_SP_USE_STD_ALLOCATOR)
BOOST_PRAGMA_MESSAGE("The macro BOOST_SP_USE_STD_ALLOCATOR has been deprecated in 1.87 and support for it will be removed.")
#endif
#if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
BOOST_PRAGMA_MESSAGE("The macro BOOST_SP_USE_QUICK_ALLOCATOR has been deprecated in 1.87 and support for it will be removed.")
#endif
#if defined(BOOST_AC_USE_SPINLOCK)
BOOST_PRAGMA_MESSAGE("The macro BOOST_AC_USE_SPINLOCK has been deprecated in 1.87 and support for it will be removed.")
#endif
#if defined(BOOST_AC_USE_PTHREADS)
BOOST_PRAGMA_MESSAGE("The macro BOOST_AC_USE_PTHREADS has been deprecated in 1.87 and support for it will be removed.")
#endif
#if defined(BOOST_SP_USE_SPINLOCK)
BOOST_PRAGMA_MESSAGE("The macro BOOST_SP_USE_SPINLOCK has been deprecated in 1.87 and support for it will be removed.")
#endif
#if defined(BOOST_SP_USE_PTHREADS)
BOOST_PRAGMA_MESSAGE("The macro BOOST_SP_USE_PTHREADS has been deprecated in 1.87 and support for it will be removed.")
#endif
#endif // #ifndef BOOST_SMART_PTR_DETAIL_DEPRECATED_MACROS_HPP_INCLUDED

View File

@@ -28,15 +28,12 @@
#include <boost/config.hpp>
#if !defined(BOOST_HAS_THREADS)
# include <boost/smart_ptr/detail/lwm_nop.hpp>
#elif defined(BOOST_HAS_PTHREADS)
# include <boost/smart_ptr/detail/lwm_pthreads.hpp>
#elif defined(BOOST_HAS_WINTHREADS) || defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
#if !defined(BOOST_NO_CXX11_HDR_MUTEX )
# include <boost/smart_ptr/detail/lwm_std_mutex.hpp>
#elif defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
# include <boost/smart_ptr/detail/lwm_win32_cs.hpp>
#else
// Use #define BOOST_DISABLE_THREADS to avoid the error
# error Unrecognized threading platform
# include <boost/smart_ptr/detail/lwm_pthreads.hpp>
#endif
#endif // #ifndef BOOST_SMART_PTR_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED

View File

@@ -0,0 +1,164 @@
#ifndef BOOST_SMART_PTR_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED
#define BOOST_SMART_PTR_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, 2018 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
//
//
// typedef /*...*/ lw_thread_t; // as pthread_t
// template<class F> int lw_thread_create( lw_thread_t & th, F f );
// void lw_thread_join( lw_thread_t th );
#include <boost/config.hpp>
#include <memory>
#include <cerrno>
#if defined( BOOST_HAS_PTHREADS )
#include <pthread.h>
namespace boost
{
namespace detail
{
typedef ::pthread_t lw_thread_t;
inline int lw_thread_create_( lw_thread_t* thread, const pthread_attr_t* attr, void* (*start_routine)( void* ), void* arg )
{
return ::pthread_create( thread, attr, start_routine, arg );
}
inline void lw_thread_join( lw_thread_t th )
{
::pthread_join( th, 0 );
}
} // namespace detail
} // namespace boost
#else // defined( BOOST_HAS_PTHREADS )
#include <windows.h>
#include <process.h>
namespace boost
{
namespace detail
{
typedef HANDLE lw_thread_t;
inline int lw_thread_create_( lw_thread_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;
}
}
inline void lw_thread_join( lw_thread_t thread )
{
::WaitForSingleObject( thread, INFINITE );
::CloseHandle( thread );
}
} // namespace detail
} // namespace boost
#endif // defined( BOOST_HAS_PTHREADS )
namespace boost
{
namespace detail
{
class lw_abstract_thread
{
public:
virtual ~lw_abstract_thread() {}
virtual void run() = 0;
};
#if defined( BOOST_HAS_PTHREADS )
extern "C" inline void * lw_thread_routine( void * pv )
{
std::unique_ptr<lw_abstract_thread> pt( static_cast<lw_abstract_thread *>( pv ) );
pt->run();
return 0;
}
#else
inline unsigned __stdcall lw_thread_routine( void * pv )
{
std::unique_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( lw_thread_t & th, F f )
{
std::unique_ptr<lw_abstract_thread> p( new lw_thread_impl<F>( f ) );
int r = lw_thread_create_( &th, 0, lw_thread_routine, p.get() );
if( r == 0 )
{
p.release();
}
return r;
}
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED

View File

@@ -27,7 +27,7 @@ namespace boost
namespace detail
{
class local_counted_base
class BOOST_SYMBOL_VISIBLE local_counted_base
{
private:
@@ -42,23 +42,23 @@ private:
public:
BOOST_CONSTEXPR local_counted_base() BOOST_SP_NOEXCEPT: local_use_count_( initial_ )
constexpr local_counted_base() noexcept: local_use_count_( initial_ )
{
}
BOOST_CONSTEXPR local_counted_base( local_counted_base const & ) BOOST_SP_NOEXCEPT: local_use_count_( initial_ )
constexpr local_counted_base( local_counted_base const & ) noexcept: local_use_count_( initial_ )
{
}
virtual ~local_counted_base() /*BOOST_SP_NOEXCEPT*/
virtual ~local_counted_base() /*noexcept*/
{
}
virtual void local_cb_destroy() BOOST_SP_NOEXCEPT = 0;
virtual void local_cb_destroy() noexcept = 0;
virtual boost::detail::shared_count local_cb_get_shared_count() const BOOST_SP_NOEXCEPT = 0;
virtual boost::detail::shared_count local_cb_get_shared_count() const noexcept = 0;
void add_ref() BOOST_SP_NOEXCEPT
void add_ref() noexcept
{
#if !defined(__NVCC__)
#if defined( __has_builtin )
@@ -73,7 +73,7 @@ public:
local_use_count_ = static_cast<count_type>( local_use_count_ + 1 );
}
void release() BOOST_SP_NOEXCEPT
void release() noexcept
{
local_use_count_ = static_cast<count_type>( local_use_count_ - 1 );
@@ -83,13 +83,13 @@ public:
}
}
long local_use_count() const BOOST_SP_NOEXCEPT
long local_use_count() const noexcept
{
return local_use_count_;
}
};
class local_counted_impl: public local_counted_base
class BOOST_SYMBOL_VISIBLE local_counted_impl: public local_counted_base
{
private:
@@ -101,41 +101,37 @@ private:
public:
explicit local_counted_impl( shared_count const& pn ): pn_( pn )
explicit local_counted_impl( shared_count const& pn ) noexcept: pn_( pn )
{
}
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
explicit local_counted_impl( shared_count && pn ): pn_( std::move(pn) )
explicit local_counted_impl( shared_count && pn ) noexcept: pn_( std::move(pn) )
{
}
#endif
virtual void local_cb_destroy() BOOST_SP_NOEXCEPT
void local_cb_destroy() noexcept override
{
delete this;
}
virtual boost::detail::shared_count local_cb_get_shared_count() const BOOST_SP_NOEXCEPT
boost::detail::shared_count local_cb_get_shared_count() const noexcept override
{
return pn_;
}
};
class local_counted_impl_em: public local_counted_base
class BOOST_SYMBOL_VISIBLE local_counted_impl_em: public local_counted_base
{
public:
shared_count pn_;
virtual void local_cb_destroy() BOOST_SP_NOEXCEPT
void local_cb_destroy() noexcept override
{
shared_count().swap( pn_ );
}
virtual boost::detail::shared_count local_cb_get_shared_count() const BOOST_SP_NOEXCEPT
boost::detail::shared_count local_cb_get_shared_count() const noexcept override
{
return pn_;
}

View File

@@ -38,48 +38,40 @@ public:
{
}
explicit local_sp_deleter( D const& d ) BOOST_SP_NOEXCEPT: d_( d )
explicit local_sp_deleter( D const& d ) noexcept: d_( d )
{
}
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
explicit local_sp_deleter( D&& d ) BOOST_SP_NOEXCEPT: d_( std::move(d) )
explicit local_sp_deleter( D&& d ) noexcept: d_( std::move(d) )
{
}
#endif
D& deleter()
D& deleter() noexcept
{
return d_;
}
template<class Y> void operator()( Y* p ) BOOST_SP_NOEXCEPT
template<class Y> void operator()( Y* p ) noexcept
{
d_( p );
}
#if !defined( BOOST_NO_CXX11_NULLPTR )
void operator()( boost::detail::sp_nullptr_t p ) BOOST_SP_NOEXCEPT
void operator()( std::nullptr_t p ) noexcept
{
d_( p );
}
#endif
};
template<> class local_sp_deleter<void>
{
};
template<class D> D * get_local_deleter( local_sp_deleter<D> * p )
template<class D> D * get_local_deleter( local_sp_deleter<D> * p ) noexcept
{
return &p->deleter();
}
inline void * get_local_deleter( local_sp_deleter<void> * /*p*/ )
inline void * get_local_deleter( local_sp_deleter<void> * /*p*/ ) noexcept
{
return 0;
}

View File

@@ -1,37 +0,0 @@
#ifndef BOOST_SMART_PTR_DETAIL_LWM_NOP_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_LWM_NOP_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// boost/detail/lwm_nop.hpp
//
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
//
// 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 lightweight_mutex
{
public:
typedef lightweight_mutex scoped_lock;
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_LWM_NOP_HPP_INCLUDED

View File

@@ -0,0 +1,62 @@
#ifndef BOOST_SMART_PTR_DETAIL_LWM_STD_MUTEX_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_LWM_STD_MUTEX_HPP_INCLUDED
// Copyright 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt)
#include <boost/assert.hpp>
#include <mutex>
namespace boost
{
namespace detail
{
class lightweight_mutex
{
private:
std::mutex m_;
lightweight_mutex(lightweight_mutex const &);
lightweight_mutex & operator=(lightweight_mutex const &);
public:
lightweight_mutex()
{
}
class scoped_lock;
friend class scoped_lock;
class scoped_lock
{
private:
std::mutex & m_;
scoped_lock(scoped_lock const &);
scoped_lock & operator=(scoped_lock const &);
public:
scoped_lock( lightweight_mutex & m ): m_( m.m_ )
{
m_.lock();
}
~scoped_lock()
{
m_.unlock();
}
};
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_LWM_STD_MUTEX_HPP_INCLUDED

View File

@@ -11,15 +11,12 @@
// boost/detail/lwm_win32_cs.hpp
//
// Copyright (c) 2002, 2003 Peter Dimov
// Copyright (c) Microsoft Corporation 2014
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/predef.h>
#ifdef BOOST_USE_WINDOWS_H
#include <windows.h>
@@ -52,28 +49,24 @@ struct critical_section
#endif
};
#if BOOST_PLAT_WINDOWS_RUNTIME
extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSectionEx(::_RTL_CRITICAL_SECTION *, unsigned long, unsigned long);
#else
extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSection(::_RTL_CRITICAL_SECTION *);
#endif
extern "C" __declspec(dllimport) void __stdcall EnterCriticalSection(::_RTL_CRITICAL_SECTION *);
extern "C" __declspec(dllimport) void __stdcall LeaveCriticalSection(::_RTL_CRITICAL_SECTION *);
extern "C" __declspec(dllimport) void __stdcall DeleteCriticalSection(::_RTL_CRITICAL_SECTION *);
#else
typedef ::_RTL_CRITICAL_SECTION rtl_critical_section;
#else // #ifndef BOOST_USE_WINDOWS_H
typedef ::CRITICAL_SECTION critical_section;
#if BOOST_PLAT_WINDOWS_RUNTIME
using ::InitializeCriticalSectionEx;
#else
using ::InitializeCriticalSection;
#endif
using ::EnterCriticalSection;
using ::LeaveCriticalSection;
using ::DeleteCriticalSection;
typedef ::CRITICAL_SECTION rtl_critical_section;
#endif // #ifndef BOOST_USE_WINDOWS_H
class lightweight_mutex
@@ -89,16 +82,12 @@ public:
lightweight_mutex()
{
#if BOOST_PLAT_WINDOWS_RUNTIME
boost::detail::InitializeCriticalSectionEx(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&cs_), 4000, 0);
#else
boost::detail::InitializeCriticalSection(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&cs_));
#endif
boost::detail::InitializeCriticalSection(reinterpret_cast< rtl_critical_section* >(&cs_));
}
~lightweight_mutex()
{
boost::detail::DeleteCriticalSection(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&cs_));
boost::detail::DeleteCriticalSection(reinterpret_cast< rtl_critical_section* >(&cs_));
}
class scoped_lock;
@@ -117,12 +106,12 @@ public:
explicit scoped_lock(lightweight_mutex & m): m_(m)
{
boost::detail::EnterCriticalSection(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&m_.cs_));
boost::detail::EnterCriticalSection(reinterpret_cast< rtl_critical_section* >(&m_.cs_));
}
~scoped_lock()
{
boost::detail::LeaveCriticalSection(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&m_.cs_));
boost::detail::LeaveCriticalSection(reinterpret_cast< rtl_critical_section* >(&m_.cs_));
}
};
};

View File

@@ -1,64 +0,0 @@
// This header intentionally has no include guards.
//
// Copyright (c) 2001-2009, 2012 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
#if !defined( BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS ) && !defined( BOOST_NO_CXX11_NULLPTR )\
&& !(defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x5130))
explicit operator bool () const BOOST_SP_NOEXCEPT
{
return px != 0;
}
#elif ( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, < 0x570) ) || defined(__CINT__)
operator bool () const BOOST_SP_NOEXCEPT
{
return px != 0;
}
#elif defined( _MANAGED )
static void unspecified_bool( this_type*** )
{
}
typedef void (*unspecified_bool_type)( this_type*** );
operator unspecified_bool_type() const BOOST_SP_NOEXCEPT
{
return px == 0? 0: unspecified_bool;
}
#elif \
( defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, < 0x3200) ) || \
( defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 304) ) || \
( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x590) )
typedef element_type * (this_type::*unspecified_bool_type)() const;
operator unspecified_bool_type() const BOOST_SP_NOEXCEPT
{
return px == 0? 0: &this_type::get;
}
#else
typedef element_type * this_type::*unspecified_bool_type;
operator unspecified_bool_type() const BOOST_SP_NOEXCEPT
{
return px == 0? 0: &this_type::px;
}
#endif
// operator! is redundant, but some compilers need it
bool operator! () const BOOST_SP_NOEXCEPT
{
return px == 0;
}

View File

@@ -21,21 +21,20 @@
#include <boost/config.hpp>
#include <boost/smart_ptr/detail/lightweight_mutex.hpp>
#include <boost/type_traits/type_with_alignment.hpp>
#include <boost/type_traits/alignment_of.hpp>
#include <boost/smart_ptr/detail/sp_type_traits.hpp>
#include <type_traits>
#include <new> // ::operator new, ::operator delete
#include <cstddef> // std::size_t
namespace boost
{
namespace detail
{
template<unsigned size, unsigned align_> union freeblock
{
typedef typename boost::type_with_alignment<align_>::type aligner_type;
typedef typename sp_type_with_alignment<align_>::type aligner_type;
aligner_type aligner;
char bytes[size];
freeblock * next;
@@ -74,7 +73,7 @@ template<unsigned size, unsigned align_> struct allocator_impl
static lightweight_mutex & mutex()
{
static freeblock< sizeof( lightweight_mutex ), boost::alignment_of< lightweight_mutex >::value > fbm;
static freeblock< sizeof( lightweight_mutex ), std::alignment_of< lightweight_mutex >::value > fbm;
static lightweight_mutex * pm = new( &fbm ) lightweight_mutex;
return *pm;
}
@@ -188,7 +187,7 @@ template<unsigned size, unsigned align_>
unsigned allocator_impl<size, align_>::last = allocator_impl<size, align_>::items_per_page;
template<class T>
struct quick_allocator: public allocator_impl< sizeof(T), boost::alignment_of<T>::value >
struct quick_allocator: public allocator_impl< sizeof(T), std::alignment_of<T>::value >
{
};

View File

@@ -18,31 +18,25 @@
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifdef __BORLANDC__
# pragma warn -8027 // Functions containing try are not expanded inline
#endif
#include <boost/config.hpp>
#include <boost/checked_delete.hpp>
#include <boost/throw_exception.hpp>
#include <boost/smart_ptr/bad_weak_ptr.hpp>
#include <boost/smart_ptr/detail/sp_counted_base.hpp>
#include <boost/smart_ptr/detail/sp_counted_impl.hpp>
#include <boost/smart_ptr/detail/sp_disable_deprecated.hpp>
#include <boost/detail/workaround.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
#include <functional> // std::less
#include <boost/smart_ptr/detail/deprecated_macros.hpp>
#include <boost/core/checked_delete.hpp>
#include <boost/throw_exception.hpp>
#include <boost/core/addressof.hpp>
#include <boost/config.hpp>
#include <boost/config/workaround.hpp>
#include <boost/cstdint.hpp>
#include <memory> // std::auto_ptr
#include <functional> // std::less
#include <cstddef> // std::size_t
#ifdef BOOST_NO_EXCEPTIONS
# include <new> // std::bad_alloc
#endif
#include <boost/core/addressof.hpp>
#if defined( BOOST_SP_DISABLE_DEPRECATED )
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
@@ -102,6 +96,14 @@ template< class D > struct sp_convert_reference< D& >
typedef sp_reference_wrapper< D > type;
};
template<class T> std::size_t sp_hash_pointer( T* p ) noexcept
{
boost::uintptr_t v = reinterpret_cast<boost::uintptr_t>( p );
// match boost::hash<T*>
return static_cast<std::size_t>( v + ( v >> 3 ) );
}
class weak_count;
class shared_count
@@ -118,14 +120,14 @@ private:
public:
BOOST_CONSTEXPR shared_count(): pi_(0) // nothrow
constexpr shared_count() noexcept: pi_(0)
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#endif
{
}
BOOST_CONSTEXPR explicit shared_count( sp_counted_base * pi ): pi_( pi ) // nothrow
constexpr explicit shared_count( sp_counted_base * pi ) noexcept: pi_( pi )
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#endif
@@ -162,18 +164,11 @@ public:
#endif
}
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1200 )
template<class Y, class D> shared_count( Y * p, D d ): pi_(0)
#else
template<class P, class D> shared_count( P p, D d ): pi_(0)
#endif
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#endif
{
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1200 )
typedef Y* P;
#endif
#ifndef BOOST_NO_EXCEPTIONS
try
@@ -199,8 +194,6 @@ public:
#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)
@@ -231,8 +224,6 @@ public:
#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 )
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
@@ -240,16 +231,8 @@ public:
{
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
@@ -288,8 +271,6 @@ public:
#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)
@@ -297,16 +278,8 @@ public:
{
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
@@ -345,8 +318,6 @@ public:
#endif // #ifndef BOOST_NO_EXCEPTIONS
}
#endif // !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
#ifndef BOOST_NO_AUTO_PTR
// auto_ptr<Y> is special cased to provide the strong guarantee
@@ -371,8 +342,6 @@ public:
#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)
@@ -381,7 +350,7 @@ public:
{
typedef typename sp_convert_reference<D>::type D2;
D2 d2( r.get_deleter() );
D2 d2( static_cast<D&&>( r.get_deleter() ) );
pi_ = new sp_counted_impl_pd< typename std::unique_ptr<Y, D>::pointer, D2 >( r.get(), d2 );
#ifdef BOOST_NO_EXCEPTIONS
@@ -396,8 +365,6 @@ public:
r.release();
}
#endif
template<class Y, class D>
explicit shared_count( boost::movelib::unique_ptr<Y, D> & r ): pi_( 0 )
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
@@ -421,7 +388,7 @@ public:
r.release();
}
~shared_count() // nothrow
~shared_count() /*noexcept*/
{
if( pi_ != 0 ) pi_->release();
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
@@ -429,7 +396,7 @@ public:
#endif
}
shared_count(shared_count const & r): pi_(r.pi_) // nothrow
shared_count(shared_count const & r) noexcept: pi_(r.pi_)
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#endif
@@ -437,9 +404,7 @@ public:
if( pi_ != 0 ) pi_->add_ref_copy();
}
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
shared_count(shared_count && r): pi_(r.pi_) // nothrow
shared_count(shared_count && r) noexcept: pi_(r.pi_)
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#endif
@@ -447,12 +412,10 @@ public:
r.pi_ = 0;
}
#endif
explicit shared_count(weak_count const & r); // throws bad_weak_ptr when r.use_count() == 0
shared_count( weak_count const & r, sp_nothrow_tag ); // constructs an empty *this when r.use_count() == 0
shared_count( weak_count const & r, sp_nothrow_tag ) noexcept; // constructs an empty *this when r.use_count() == 0
shared_count & operator= (shared_count const & r) // nothrow
shared_count & operator= (shared_count const & r) noexcept
{
sp_counted_base * tmp = r.pi_;
@@ -466,52 +429,61 @@ public:
return *this;
}
void swap(shared_count & r) // nothrow
void swap(shared_count & r) noexcept
{
sp_counted_base * tmp = r.pi_;
r.pi_ = pi_;
pi_ = tmp;
}
long use_count() const // nothrow
long use_count() const noexcept
{
return pi_ != 0? pi_->use_count(): 0;
}
bool unique() const // nothrow
bool unique() const noexcept
{
return use_count() == 1;
}
bool empty() const // nothrow
bool empty() const noexcept
{
return pi_ == 0;
}
friend inline bool operator==(shared_count const & a, shared_count const & b)
bool operator==( shared_count const & r ) const noexcept
{
return a.pi_ == b.pi_;
return pi_ == r.pi_;
}
friend inline bool operator<(shared_count const & a, shared_count const & b)
bool operator==( weak_count const & r ) const noexcept;
bool operator<( shared_count const & r ) const noexcept
{
return std::less<sp_counted_base *>()( a.pi_, b.pi_ );
return std::less<sp_counted_base *>()( pi_, r.pi_ );
}
void * get_deleter( sp_typeinfo const & ti ) const
bool operator<( weak_count const & r ) const noexcept;
void * get_deleter( sp_typeinfo_ const & ti ) const noexcept
{
return pi_? pi_->get_deleter( ti ): 0;
}
void * get_local_deleter( sp_typeinfo const & ti ) const
void * get_local_deleter( sp_typeinfo_ const & ti ) const noexcept
{
return pi_? pi_->get_local_deleter( ti ): 0;
}
void * get_untyped_deleter() const
void * get_untyped_deleter() const noexcept
{
return pi_? pi_->get_untyped_deleter(): 0;
}
std::size_t hash_value() const noexcept
{
return sp_hash_pointer( pi_ );
}
};
@@ -529,14 +501,14 @@ private:
public:
BOOST_CONSTEXPR weak_count(): pi_(0) // nothrow
constexpr weak_count() noexcept: pi_(0)
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(weak_count_id)
#endif
{
}
weak_count(shared_count const & r): pi_(r.pi_) // nothrow
weak_count(shared_count const & r) noexcept: pi_(r.pi_)
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(weak_count_id)
#endif
@@ -544,7 +516,7 @@ public:
if(pi_ != 0) pi_->weak_add_ref();
}
weak_count(weak_count const & r): pi_(r.pi_) // nothrow
weak_count(weak_count const & r) noexcept: pi_(r.pi_)
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(weak_count_id)
#endif
@@ -554,9 +526,7 @@ public:
// Move support
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
weak_count(weak_count && r): pi_(r.pi_) // nothrow
weak_count(weak_count && r) noexcept: pi_(r.pi_)
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(weak_count_id)
#endif
@@ -564,9 +534,7 @@ public:
r.pi_ = 0;
}
#endif
~weak_count() // nothrow
~weak_count() /*noexcept*/
{
if(pi_ != 0) pi_->weak_release();
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
@@ -574,7 +542,7 @@ public:
#endif
}
weak_count & operator= (shared_count const & r) // nothrow
weak_count & operator= (shared_count const & r) noexcept
{
sp_counted_base * tmp = r.pi_;
@@ -588,7 +556,7 @@ public:
return *this;
}
weak_count & operator= (weak_count const & r) // nothrow
weak_count & operator= (weak_count const & r) noexcept
{
sp_counted_base * tmp = r.pi_;
@@ -602,31 +570,46 @@ public:
return *this;
}
void swap(weak_count & r) // nothrow
void swap(weak_count & r) noexcept
{
sp_counted_base * tmp = r.pi_;
r.pi_ = pi_;
pi_ = tmp;
}
long use_count() const // nothrow
long use_count() const noexcept
{
return pi_ != 0? pi_->use_count(): 0;
}
bool empty() const // nothrow
bool empty() const noexcept
{
return pi_ == 0;
}
friend inline bool operator==(weak_count const & a, weak_count const & b)
bool operator==( weak_count const & r ) const noexcept
{
return a.pi_ == b.pi_;
return pi_ == r.pi_;
}
friend inline bool operator<(weak_count const & a, weak_count const & b)
bool operator==( shared_count const & r ) const noexcept
{
return std::less<sp_counted_base *>()(a.pi_, b.pi_);
return pi_ == r.pi_;
}
bool operator<( weak_count const & r ) const noexcept
{
return std::less<sp_counted_base *>()( pi_, r.pi_ );
}
bool operator<( shared_count const & r ) const noexcept
{
return std::less<sp_counted_base *>()( pi_, r.pi_ );
}
std::size_t hash_value() const noexcept
{
return sp_hash_pointer( pi_ );
}
};
@@ -641,7 +624,7 @@ inline shared_count::shared_count( weak_count const & r ): pi_( r.pi_ )
}
}
inline shared_count::shared_count( weak_count const & r, sp_nothrow_tag ): pi_( r.pi_ )
inline shared_count::shared_count( weak_count const & r, sp_nothrow_tag ) noexcept: pi_( r.pi_ )
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
, id_(shared_count_id)
#endif
@@ -652,6 +635,16 @@ inline shared_count::shared_count( weak_count const & r, sp_nothrow_tag ): pi_(
}
}
inline bool shared_count::operator==( weak_count const & r ) const noexcept
{
return pi_ == r.pi_;
}
inline bool shared_count::operator<( weak_count const & r ) const noexcept
{
return std::less<sp_counted_base *>()( pi_, r.pi_ );
}
} // namespace detail
} // namespace boost
@@ -660,8 +653,4 @@ inline shared_count::shared_count( weak_count const & r, sp_nothrow_tag ): pi_(
#pragma GCC diagnostic pop
#endif
#ifdef __BORLANDC__
# pragma warn .8027 // Functions containing try are not expanded inline
#endif
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED

View File

@@ -18,20 +18,6 @@
#include <boost/config.hpp>
#include <cstddef>
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( BOOST_NO_SFINAE )
# define BOOST_SP_NO_SP_CONVERTIBLE
#endif
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ < 303 )
# define BOOST_SP_NO_SP_CONVERTIBLE
#endif
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( __BORLANDC__ ) && ( __BORLANDC__ < 0x630 )
# define BOOST_SP_NO_SP_CONVERTIBLE
#endif
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
namespace boost
{
@@ -87,6 +73,4 @@ template< class Y, class T > struct sp_enable_if_convertible: public sp_enable_i
} // namespace boost
#endif // !defined( BOOST_SP_NO_SP_CONVERTIBLE )
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_CONVERTIBLE_HPP_INCLUDED

View File

@@ -17,14 +17,10 @@
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/smart_ptr/detail/sp_has_gcc_intrinsics.hpp>
#include <boost/smart_ptr/detail/sp_has_sync_intrinsics.hpp>
#include <boost/smart_ptr/detail/deprecated_macros.hpp>
#include <boost/config.hpp>
#include <boost/smart_ptr/detail/sp_has_sync.hpp>
#if !defined( __c2__ ) && defined( __clang__ ) && defined( __has_extension )
# if __has_extension( __c_atomic__ )
# define BOOST_SP_HAS_CLANG_C11_ATOMICS
# endif
#endif
#if defined( BOOST_SP_DISABLE_THREADS )
# include <boost/smart_ptr/detail/sp_counted_base_nt.hpp>
@@ -41,18 +37,24 @@
#elif defined( BOOST_DISABLE_THREADS ) && !defined( BOOST_SP_ENABLE_THREADS ) && !defined( BOOST_DISABLE_WIN32 )
# include <boost/smart_ptr/detail/sp_counted_base_nt.hpp>
#elif defined( BOOST_SP_HAS_CLANG_C11_ATOMICS )
# include <boost/smart_ptr/detail/sp_counted_base_clang.hpp>
#elif defined( BOOST_SP_HAS_GCC_INTRINSICS )
# include <boost/smart_ptr/detail/sp_counted_base_gcc_atomic.hpp>
#elif !defined( BOOST_NO_CXX11_HDR_ATOMIC )
# include <boost/smart_ptr/detail/sp_counted_base_std_atomic.hpp>
#elif defined( __SNC__ )
# include <boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp>
#elif defined( __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 )
# include <boost/smart_ptr/detail/sp_counted_base_sync.hpp>
#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) && !defined(__PATHSCALE__)
# include <boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp>
#elif defined( BOOST_SP_HAS_SYNC_INTRINSICS )
# include <boost/smart_ptr/detail/sp_counted_base_sync.hpp>
#elif defined( __SNC__ )
# include <boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp>
#elif defined(__HP_aCC) && defined(__ia64)
# include <boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp>
@@ -71,9 +73,6 @@
#elif defined( __GNUC__ ) && ( defined( __mips__ ) || defined( _mips ) ) && !defined(__PATHSCALE__) && !defined( __mips16 )
# include <boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp>
#elif defined( BOOST_SP_HAS_SYNC )
# include <boost/smart_ptr/detail/sp_counted_base_sync.hpp>
#elif defined(__GNUC__) && ( defined( __sparcv9 ) || ( defined( __sparcv8 ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 402 ) ) )
# include <boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp>
@@ -91,6 +90,4 @@
#endif
#undef BOOST_SP_HAS_CLANG_C11_ATOMICS
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED

View File

@@ -15,9 +15,20 @@
// Lock-free algorithm by Alexander Terekhov
//
#include <boost/detail/sp_typeinfo.hpp>
#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/smart_ptr/detail/sp_obsolete.hpp>
#include <boost/config.hpp>
#include <machine/sys/inline.h>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using HP aCC++/HP-UX/IA64 sp_counted_base")
#endif
BOOST_SP_OBSOLETE()
namespace boost
{
@@ -71,7 +82,7 @@ inline int atomic_conditional_increment( int * pw )
}
}
class sp_counted_base
class BOOST_SYMBOL_VISIBLE sp_counted_base
{
private:
@@ -103,8 +114,8 @@ public:
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy()

View File

@@ -20,10 +20,18 @@
// formulation
//
#include <boost/detail/sp_typeinfo.hpp>
#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/config.hpp>
#include <builtins.h>
#include <sys/atomic_op.h>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using AIX sp_counted_base")
#endif
namespace boost
{
@@ -63,7 +71,7 @@ inline int32_t atomic_conditional_increment( int32_t * pw )
}
}
class sp_counted_base
class BOOST_SYMBOL_VISIBLE sp_counted_base
{
private:
@@ -95,8 +103,8 @@ public:
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy()

View File

@@ -1,150 +0,0 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CLANG_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CLANG_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
// detail/sp_counted_base_clang.hpp - __c11 clang intrinsics
//
// Copyright (c) 2007, 2013, 2015 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 <boost/cstdint.hpp>
namespace boost
{
namespace detail
{
typedef _Atomic( boost::int_least32_t ) atomic_int_least32_t;
inline void atomic_increment( atomic_int_least32_t * pw )
{
__c11_atomic_fetch_add( pw, 1, __ATOMIC_RELAXED );
}
inline boost::int_least32_t atomic_decrement( atomic_int_least32_t * pw )
{
return __c11_atomic_fetch_sub( pw, 1, __ATOMIC_ACQ_REL );
}
inline boost::int_least32_t atomic_conditional_increment( atomic_int_least32_t * pw )
{
// long r = *pw;
// if( r != 0 ) ++*pw;
// return r;
boost::int_least32_t r = __c11_atomic_load( pw, __ATOMIC_RELAXED );
for( ;; )
{
if( r == 0 )
{
return r;
}
if( __c11_atomic_compare_exchange_weak( pw, &r, r + 1, __ATOMIC_RELAXED, __ATOMIC_RELAXED ) )
{
return r;
}
}
}
#if defined(__clang__)
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wweak-vtables"
#endif
class sp_counted_base
{
private:
sp_counted_base( sp_counted_base const & );
sp_counted_base & operator= ( sp_counted_base const & );
atomic_int_least32_t use_count_; // #shared
atomic_int_least32_t weak_count_; // #weak + (#shared != 0)
public:
sp_counted_base()
{
__c11_atomic_init( &use_count_, 1 );
__c11_atomic_init( &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_local_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 __c11_atomic_load( const_cast< atomic_int_least32_t* >( &use_count_ ), __ATOMIC_ACQUIRE );
}
};
#if defined(__clang__)
# pragma clang diagnostic pop
#endif
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CLANG_HPP_INCLUDED

View File

@@ -24,7 +24,16 @@
// formulation
//
#include <boost/detail/sp_typeinfo.hpp>
#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/smart_ptr/detail/sp_obsolete.hpp>
#include <boost/config.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using CodeWarrior/PowerPC sp_counted_base")
#endif
namespace boost
{
@@ -53,7 +62,11 @@ inline long atomic_decrement( register long * pw )
asm
{
#if defined(__PPCZen__) || defined(__PPCe500__) || defined(__PPCe500v2__)
msync
#else
sync
#endif
loop:
@@ -91,7 +104,7 @@ store:
return a;
}
class sp_counted_base
class BOOST_SYMBOL_VISIBLE sp_counted_base
{
private:
@@ -123,8 +136,8 @@ public:
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy()

View File

@@ -1,160 +0,0 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_X86_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_X86_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// detail/sp_counted_base_cw_x86.hpp - CodeWarrion on 486+
//
// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
// Copyright 2004-2005 Peter Dimov
// Copyright 2005 Rene Rivera
//
// 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>
namespace boost
{
namespace detail
{
inline int atomic_exchange_and_add( int * pw, int dv )
{
// int r = *pw;
// *pw += dv;
// return r;
asm
{
mov esi, [pw]
mov eax, dv
lock xadd dword ptr [esi], eax
}
}
inline void atomic_increment( int * pw )
{
//atomic_exchange_and_add( pw, 1 );
asm
{
mov esi, [pw]
lock inc dword ptr [esi]
}
}
inline int atomic_conditional_increment( int * pw )
{
// int rv = *pw;
// if( rv != 0 ) ++*pw;
// return rv;
asm
{
mov esi, [pw]
mov eax, dword ptr [esi]
L0:
test eax, eax
je L1
mov ebx, eax
inc ebx
lock cmpxchg dword ptr [esi], ebx
jne L0
L1:
}
}
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)
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_local_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_exchange_and_add( &use_count_, -1 ) == 1 )
{
dispose();
weak_release();
}
}
void weak_add_ref() // nothrow
{
atomic_increment( &weak_count_ );
}
void weak_release() // nothrow
{
if( atomic_exchange_and_add( &weak_count_, -1 ) == 1 )
{
destroy();
}
}
long use_count() const // nothrow
{
return static_cast<int const volatile &>( use_count_ );
}
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_X86_HPP_INCLUDED

View File

@@ -0,0 +1,148 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_ATOMIC_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_ATOMIC_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
// detail/sp_counted_base_gcc_atomic.hpp - g++ 4.7+ __atomic intrinsics
//
// Copyright 2007, 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using __atomic sp_counted_base")
#endif
namespace boost
{
namespace detail
{
inline void atomic_increment( boost::uint_least32_t * pw )
{
__atomic_fetch_add( pw, 1, __ATOMIC_RELAXED );
}
inline boost::uint_least32_t atomic_decrement( boost::uint_least32_t * pw )
{
return __atomic_fetch_sub( pw, 1, __ATOMIC_ACQ_REL );
}
inline boost::uint_least32_t atomic_conditional_increment( boost::uint_least32_t * pw )
{
// long r = *pw;
// if( r != 0 ) ++*pw;
// return r;
boost::uint_least32_t r = __atomic_load_n( pw, __ATOMIC_RELAXED );
for( ;; )
{
if( r == 0 )
{
return r;
}
if( __atomic_compare_exchange_n( pw, &r, r + 1, true, __ATOMIC_RELAXED, __ATOMIC_RELAXED ) )
{
return r;
}
}
}
inline boost::uint_least32_t atomic_load( boost::uint_least32_t const * pw )
{
return __atomic_load_n( pw, __ATOMIC_ACQUIRE );
}
class BOOST_SYMBOL_VISIBLE sp_counted_base
{
private:
sp_counted_base( sp_counted_base const & );
sp_counted_base & operator= ( sp_counted_base const & );
boost::uint_least32_t use_count_; // #shared
boost::uint_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_local_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 static_cast<long>( atomic_load( &use_count_ ) );
}
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED

View File

@@ -16,7 +16,18 @@
// Lock-free algorithm by Alexander Terekhov
//
#include <boost/detail/sp_typeinfo.hpp>
#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/smart_ptr/detail/sp_obsolete.hpp>
#include <boost/config.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using g++/IA64 sp_counted_base")
#endif
BOOST_SP_OBSOLETE()
namespace boost
{
@@ -78,7 +89,7 @@ inline int atomic_conditional_increment( int * pw )
return rv;
}
class sp_counted_base
class BOOST_SYMBOL_VISIBLE sp_counted_base
{
private:
@@ -110,8 +121,8 @@ public:
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy()

View File

@@ -20,7 +20,18 @@
// Lock-free algorithm by Alexander Terekhov
//
#include <boost/detail/sp_typeinfo.hpp>
#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/smart_ptr/detail/sp_obsolete.hpp>
#include <boost/config.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using g++/MIPS sp_counted_base")
#endif
BOOST_SP_OBSOLETE()
namespace boost
{
@@ -108,7 +119,7 @@ inline int atomic_conditional_increment( int * pw )
return rv;
}
class sp_counted_base
class BOOST_SYMBOL_VISIBLE sp_counted_base
{
private:
@@ -140,8 +151,8 @@ public:
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy()

View File

@@ -24,7 +24,18 @@
// formulation
//
#include <boost/detail/sp_typeinfo.hpp>
#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/smart_ptr/detail/sp_obsolete.hpp>
#include <boost/config.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using g++/PowerPC sp_counted_base")
#endif
BOOST_SP_OBSOLETE()
namespace boost
{
@@ -102,7 +113,7 @@ inline int atomic_conditional_increment( int * pw )
return rv;
}
class sp_counted_base
class BOOST_SYMBOL_VISIBLE sp_counted_base
{
private:
@@ -134,8 +145,8 @@ public:
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy()

View File

@@ -19,9 +19,20 @@
//
// Thanks to Michael van der Westhuizen
#include <boost/detail/sp_typeinfo.hpp>
#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/smart_ptr/detail/sp_obsolete.hpp>
#include <boost/config.hpp>
#include <inttypes.h> // int32_t
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using g++/Sparc sp_counted_base")
#endif
BOOST_SP_OBSOLETE()
namespace boost
{
@@ -87,7 +98,7 @@ inline int32_t atomic_conditional_increment( int32_t * pw )
}
}
class sp_counted_base
class BOOST_SYMBOL_VISIBLE sp_counted_base
{
private:
@@ -119,8 +130,8 @@ public:
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy()

View File

@@ -24,7 +24,18 @@
// formulation
//
#include <boost/detail/sp_typeinfo.hpp>
#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/smart_ptr/detail/sp_obsolete.hpp>
#include <boost/config.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using g++/x86 sp_counted_base")
#endif
BOOST_SP_OBSOLETE()
namespace boost
{
@@ -94,7 +105,7 @@ inline int atomic_conditional_increment( int * pw )
return rv;
}
class sp_counted_base
class BOOST_SYMBOL_VISIBLE sp_counted_base
{
private:
@@ -126,8 +137,8 @@ public:
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy()

View File

@@ -18,7 +18,16 @@
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/detail/sp_typeinfo.hpp>
#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using single-threaded, non-atomic sp_counted_base")
#endif
namespace boost
{
@@ -26,55 +35,55 @@ namespace boost
namespace detail
{
class sp_counted_base
class BOOST_SYMBOL_VISIBLE sp_counted_base
{
private:
sp_counted_base( sp_counted_base const & );
sp_counted_base & operator= ( sp_counted_base const & );
long use_count_; // #shared
long weak_count_; // #weak + (#shared != 0)
boost::int_least32_t use_count_; // #shared
boost::int_least32_t weak_count_; // #weak + (#shared != 0)
public:
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
sp_counted_base() noexcept: use_count_( 1 ), weak_count_( 1 )
{
}
virtual ~sp_counted_base() // nothrow
virtual ~sp_counted_base() /*noexcept*/
{
}
// dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this.
virtual void dispose() = 0; // nothrow
virtual void dispose() noexcept = 0; // nothrow
// destroy() is called when weak_count_ drops to zero.
virtual void destroy() // nothrow
virtual void destroy() noexcept // nothrow
{
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
virtual void * get_deleter( sp_typeinfo_ const & ti ) noexcept = 0;
virtual void * get_local_deleter( sp_typeinfo_ const & ti ) noexcept = 0;
virtual void * get_untyped_deleter() noexcept = 0;
void add_ref_copy()
void add_ref_copy() noexcept
{
++use_count_;
}
bool add_ref_lock() // true on success
bool add_ref_lock() noexcept // true on success
{
if( use_count_ == 0 ) return false;
++use_count_;
return true;
}
void release() // nothrow
void release() noexcept
{
if( --use_count_ == 0 )
{
@@ -83,12 +92,12 @@ public:
}
}
void weak_add_ref() // nothrow
void weak_add_ref() noexcept
{
++weak_count_;
}
void weak_release() // nothrow
void weak_release() noexcept
{
if( --weak_count_ == 0 )
{
@@ -96,7 +105,7 @@ public:
}
}
long use_count() const // nothrow
long use_count() const noexcept
{
return use_count_;
}

View File

@@ -18,25 +18,34 @@
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/detail/sp_typeinfo.hpp>
#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#include <pthread.h>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using pthread_mutex sp_counted_base")
#endif
namespace boost
{
namespace detail
{
class sp_counted_base
class BOOST_SYMBOL_VISIBLE sp_counted_base
{
private:
sp_counted_base( sp_counted_base const & );
sp_counted_base & operator= ( sp_counted_base const & );
long use_count_; // #shared
long weak_count_; // #weak + (#shared != 0)
boost::int_least32_t use_count_; // #shared
boost::int_least32_t weak_count_; // #weak + (#shared != 0)
mutable pthread_mutex_t m_;
@@ -70,8 +79,8 @@ public:
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy()
@@ -92,7 +101,7 @@ public:
void release() // nothrow
{
BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
long new_use_count = --use_count_;
boost::int_least32_t new_use_count = --use_count_;
BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
if( new_use_count == 0 )
@@ -112,7 +121,7 @@ public:
void weak_release() // nothrow
{
BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
long new_weak_count = --weak_count_;
boost::int_least32_t new_weak_count = --weak_count_;
BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
if( new_weak_count == 0 )
@@ -124,7 +133,7 @@ public:
long use_count() const // nothrow
{
BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
long r = use_count_;
boost::int_least32_t r = use_count_;
BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
return r;

View File

@@ -6,7 +6,7 @@
# pragma once
#endif
// detail/sp_counted_base_gcc_sparc.hpp - g++ on Sparc V8+
// detail/sp_counted_base_gcc_snc_ps3.hpp - PS3 Cell
//
// Copyright (c) 2006 Piotr Wyderski
// Copyright (c) 2006 Tomas Puverle
@@ -19,9 +19,20 @@
//
// Thanks to Michael van der Westhuizen
#include <boost/detail/sp_typeinfo.hpp>
#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/smart_ptr/detail/sp_obsolete.hpp>
#include <boost/config.hpp>
#include <inttypes.h> // uint32_t
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using PS3 sp_counted_base")
#endif
BOOST_SP_OBSOLETE()
namespace boost
{
@@ -82,7 +93,7 @@ inline uint32_t atomic_conditional_increment( uint32_t * pw )
}
}
class sp_counted_base
class BOOST_SYMBOL_VISIBLE sp_counted_base
{
private:
@@ -114,8 +125,8 @@ public:
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy()

View File

@@ -1,115 +0,0 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED
//
// detail/sp_counted_base_solaris.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 <atomic.h>
namespace boost
{
namespace detail
{
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_local_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy()
{
atomic_inc_32( &use_count_ );
}
bool add_ref_lock() // true on success
{
for( ;; )
{
uint32_t tmp = static_cast< uint32_t const volatile& >( use_count_ );
if( tmp == 0 ) return false;
if( atomic_cas_32( &use_count_, tmp, tmp + 1 ) == tmp ) return true;
}
}
void release() // nothrow
{
if( atomic_dec_32_nv( &use_count_ ) == 0 )
{
dispose();
weak_release();
}
}
void weak_add_ref() // nothrow
{
atomic_inc_32( &weak_count_ );
}
void weak_release() // nothrow
{
if( atomic_dec_32_nv( &weak_count_ ) == 0 )
{
destroy();
}
}
long use_count() const // nothrow
{
return static_cast<long const volatile &>( use_count_ );
}
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED

View File

@@ -18,8 +18,16 @@
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/detail/sp_typeinfo.hpp>
#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/smart_ptr/detail/spinlock_pool.hpp>
#include <boost/config.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using spinlock-based sp_counted_base")
#endif
namespace boost
{
@@ -51,7 +59,7 @@ inline int atomic_conditional_increment( int * pw )
return rv;
}
class sp_counted_base
class BOOST_SYMBOL_VISIBLE sp_counted_base
{
private:
@@ -83,8 +91,8 @@ public:
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy()

View File

@@ -15,27 +15,35 @@
// 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 <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/config.hpp>
#include <atomic>
#include <cstdint>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using std::atomic sp_counted_base")
#endif
namespace boost
{
namespace detail
{
inline void atomic_increment( std::atomic_int_least32_t * pw )
inline void atomic_increment( std::atomic_int_least32_t * pw ) noexcept
{
pw->fetch_add( 1, std::memory_order_relaxed );
}
inline std::int_least32_t atomic_decrement( std::atomic_int_least32_t * pw )
inline std::int_least32_t atomic_decrement( std::atomic_int_least32_t * pw ) noexcept
{
return pw->fetch_sub( 1, std::memory_order_acq_rel );
}
inline std::int_least32_t atomic_conditional_increment( std::atomic_int_least32_t * pw )
inline std::int_least32_t atomic_conditional_increment( std::atomic_int_least32_t * pw ) noexcept
{
// long r = *pw;
// if( r != 0 ) ++*pw;
@@ -57,7 +65,7 @@ inline std::int_least32_t atomic_conditional_increment( std::atomic_int_least32_
}
}
class sp_counted_base
class BOOST_SYMBOL_VISIBLE sp_counted_base
{
private:
@@ -69,41 +77,41 @@ private:
public:
sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
sp_counted_base() noexcept: use_count_( 1 ), weak_count_( 1 )
{
}
virtual ~sp_counted_base() // nothrow
virtual ~sp_counted_base() /*noexcept*/
{
}
// dispose() is called when use_count_ drops to zero, to release
// the resources managed by *this.
virtual void dispose() = 0; // nothrow
virtual void dispose() noexcept = 0;
// destroy() is called when weak_count_ drops to zero.
virtual void destroy() // nothrow
virtual void destroy() noexcept
{
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
virtual void * get_deleter( sp_typeinfo_ const & ti ) noexcept = 0;
virtual void * get_local_deleter( sp_typeinfo_ const & ti ) noexcept = 0;
virtual void * get_untyped_deleter() noexcept = 0;
void add_ref_copy()
void add_ref_copy() noexcept
{
atomic_increment( &use_count_ );
}
bool add_ref_lock() // true on success
bool add_ref_lock() noexcept // true on success
{
return atomic_conditional_increment( &use_count_ ) != 0;
}
void release() // nothrow
void release() noexcept
{
if( atomic_decrement( &use_count_ ) == 1 )
{
@@ -112,12 +120,12 @@ public:
}
}
void weak_add_ref() // nothrow
void weak_add_ref() noexcept
{
atomic_increment( &weak_count_ );
}
void weak_release() // nothrow
void weak_release() noexcept
{
if( atomic_decrement( &weak_count_ ) == 1 )
{
@@ -125,7 +133,7 @@ public:
}
}
long use_count() const // nothrow
long use_count() const noexcept
{
return use_count_.load( std::memory_order_acquire );
}

View File

@@ -15,13 +15,21 @@
// 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 <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/config.hpp>
#include <limits.h>
#if defined( __ia64__ ) && defined( __INTEL_COMPILER )
# include <ia64intrin.h>
#endif
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using __sync sp_counted_base")
#endif
namespace boost
{
@@ -76,7 +84,7 @@ inline sp_int32_t atomic_conditional_increment( sp_int32_t * pw )
}
}
class sp_counted_base
class BOOST_SYMBOL_VISIBLE sp_counted_base
{
private:
@@ -108,8 +116,8 @@ public:
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy()

View File

@@ -21,7 +21,18 @@
// formulation
//
#include <boost/detail/sp_typeinfo.hpp>
#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/smart_ptr/detail/sp_obsolete.hpp>
#include <boost/config.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using xlC/PowerPC sp_counted_base")
#endif
BOOST_SP_OBSOLETE()
extern "builtin" void __lwsync(void);
extern "builtin" void __isync(void);
@@ -70,7 +81,7 @@ inline int atomic_conditional_increment( int *pw )
}
}
class sp_counted_base
class BOOST_SYMBOL_VISIBLE sp_counted_base
{
private:
@@ -103,8 +114,8 @@ public:
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy()

View File

@@ -25,8 +25,16 @@
//
#include <boost/smart_ptr/detail/sp_interlocked.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/detail/sp_typeinfo.hpp>
#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/config/workaround.hpp>
#include <boost/config.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using Win32 sp_counted_base")
#endif
namespace boost
{
@@ -34,7 +42,7 @@ namespace boost
namespace detail
{
class sp_counted_base
class BOOST_SYMBOL_VISIBLE sp_counted_base
{
private:
@@ -66,8 +74,8 @@ public:
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0;
virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0;
virtual void * get_untyped_deleter() = 0;
void add_ref_copy()
@@ -82,18 +90,7 @@ public:
long tmp = static_cast< long const volatile& >( use_count_ );
if( tmp == 0 ) return false;
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1200 )
// work around a code generation bug
long tmp2 = tmp + 1;
if( BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp2, tmp ) == tmp2 - 1 ) return true;
#else
if( BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp + 1, tmp ) == tmp ) return true;
#endif
}
}

View File

@@ -18,24 +18,21 @@
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/config.hpp>
#if defined(BOOST_SP_USE_STD_ALLOCATOR) && defined(BOOST_SP_USE_QUICK_ALLOCATOR)
# error BOOST_SP_USE_STD_ALLOCATOR and BOOST_SP_USE_QUICK_ALLOCATOR are incompatible.
#endif
#include <boost/checked_delete.hpp>
#include <boost/smart_ptr/detail/sp_counted_base.hpp>
#include <boost/smart_ptr/detail/deprecated_macros.hpp>
#include <boost/core/checked_delete.hpp>
#include <boost/core/addressof.hpp>
#include <boost/config.hpp>
#if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
#include <boost/smart_ptr/detail/quick_allocator.hpp>
#endif
#if defined(BOOST_SP_USE_STD_ALLOCATOR)
#include <memory> // std::allocator
#endif
#include <memory> // std::allocator, std::allocator_traits
#include <cstddef> // std::size_t
namespace boost
@@ -55,16 +52,16 @@ namespace detail
template<class D> class local_sp_deleter;
template<class D> D * get_local_deleter( D * /*p*/ )
template<class D> D * get_local_deleter( D * /*p*/ ) noexcept
{
return 0;
}
template<class D> D * get_local_deleter( local_sp_deleter<D> * p );
template<class D> D * get_local_deleter( local_sp_deleter<D> * p ) noexcept;
//
template<class X> class sp_counted_impl_p: public sp_counted_base
template<class X> class BOOST_SYMBOL_VISIBLE sp_counted_impl_p: public sp_counted_base
{
private:
@@ -84,7 +81,7 @@ public:
#endif
}
virtual void dispose() // nothrow
void dispose() noexcept override
{
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
boost::sp_scalar_destructor_hook( px_, sizeof(X), this );
@@ -92,17 +89,17 @@ public:
boost::checked_delete( px_ );
}
virtual void * get_deleter( sp_typeinfo const & )
void * get_deleter( sp_typeinfo_ const & ) noexcept override
{
return 0;
}
virtual void * get_local_deleter( sp_typeinfo const & )
void * get_local_deleter( sp_typeinfo_ const & ) noexcept override
{
return 0;
}
virtual void * get_untyped_deleter()
void * get_untyped_deleter() noexcept override
{
return 0;
}
@@ -136,19 +133,12 @@ public:
#endif
};
//
// Borland's Codeguard trips up over the -Vx- option here:
//
#ifdef __CODEGUARD__
# pragma option push -Vx-
#endif
template<class P, class D> class sp_counted_impl_pd: public sp_counted_base
template<class P, class D> class BOOST_SYMBOL_VISIBLE sp_counted_impl_pd: public sp_counted_base
{
private:
P ptr; // copy constructor must not throw
D del; // copy constructor must not throw
D del; // copy/move constructor must not throw
sp_counted_impl_pd( sp_counted_impl_pd const & );
sp_counted_impl_pd & operator= ( sp_counted_impl_pd const & );
@@ -159,7 +149,7 @@ public:
// 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( static_cast< D&& >( d ) )
{
}
@@ -167,22 +157,22 @@ public:
{
}
virtual void dispose() // nothrow
void dispose() noexcept override
{
del( ptr );
}
virtual void * get_deleter( sp_typeinfo const & ti )
void * get_deleter( sp_typeinfo_ const & ti ) noexcept override
{
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_local_deleter( sp_typeinfo const & ti )
void * get_local_deleter( sp_typeinfo_ const & ti ) noexcept override
{
return ti == BOOST_SP_TYPEID(D)? boost::detail::get_local_deleter( boost::addressof( del ) ): 0;
return ti == BOOST_SP_TYPEID_(D)? boost::detail::get_local_deleter( boost::addressof( del ) ): 0;
}
virtual void * get_untyped_deleter()
void * get_untyped_deleter() noexcept override
{
return &reinterpret_cast<char&>( del );
}
@@ -216,12 +206,12 @@ public:
#endif
};
template<class P, class D, class A> class sp_counted_impl_pda: public sp_counted_base
template<class P, class D, class A> class BOOST_SYMBOL_VISIBLE sp_counted_impl_pda: public sp_counted_base
{
private:
P p_; // copy constructor must not throw
D d_; // copy constructor must not throw
D d_; // copy/move constructor must not throw
A a_; // copy constructor must not throw
sp_counted_impl_pda( sp_counted_impl_pda const & );
@@ -233,7 +223,7 @@ public:
// 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_( static_cast< D&& >( d ) ), a_( a )
{
}
@@ -241,23 +231,15 @@ public:
{
}
virtual void dispose() // nothrow
void dispose() noexcept override
{
d_( p_ );
}
virtual void destroy() // nothrow
void destroy() noexcept override
{
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
typedef typename std::allocator_traits<A>::template rebind_alloc< this_type > A2;
#else
typedef typename A::template rebind< this_type >::other A2;
#endif
A2 a2( a_ );
this->~this_type();
@@ -265,26 +247,22 @@ public:
a2.deallocate( this, 1 );
}
virtual void * get_deleter( sp_typeinfo const & ti )
void * get_deleter( sp_typeinfo_ const & ti ) noexcept override
{
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_local_deleter( sp_typeinfo const & ti )
void * get_local_deleter( sp_typeinfo_ const & ti ) noexcept override
{
return ti == BOOST_SP_TYPEID(D)? boost::detail::get_local_deleter( boost::addressof( d_ ) ): 0;
return ti == BOOST_SP_TYPEID_( D )? boost::detail::get_local_deleter( boost::addressof( d_ ) ): 0;
}
virtual void * get_untyped_deleter()
void * get_untyped_deleter() noexcept override
{
return &reinterpret_cast<char&>( d_ );
}
};
#ifdef __CODEGUARD__
# pragma option pop
#endif
} // namespace detail
} // namespace boost

View File

@@ -0,0 +1,37 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_CXX20_CONSTEXPR_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_CXX20_CONSTEXPR_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
#pragma once
#endif
// detail/sp_noexcept.hpp
//
// Copyright 2025 Mathias Stearn
//
// 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
// This macro is used to mark functions as constexpr if the compiler supports
// constexpr destructors. Since you can't have a constexpr smart pointer object,
// everything except null constructors are guided behind this macro. Because
// this also guards a use of dynamic_cast, we need to check for its availability
// as well. It isn't worth splitting out since all known compilers that support
// constexpr dynamic_cast also support constexpr destructors.
//
// WARNING: This does not check for changing active member of a union in
// constant expressions which is allowed in C++20. If that is needed, we
// need to raise the checked version to 202002L.
#if defined(__cpp_constexpr_dynamic_alloc) && __cpp_constexpr_dynamic_alloc >= 201907L \
&& defined(__cpp_constexpr) && __cpp_constexpr >= 201907L
#define BOOST_SP_CXX20_CONSTEXPR constexpr
#else
#define BOOST_SP_CXX20_CONSTEXPR
#define BOOST_SP_NO_CXX20_CONSTEXPR
#endif
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_CXX20_CONSTEXPR_HPP_INCLUDED

View File

@@ -1,52 +0,0 @@
#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 )
#if defined( BOOST_GCC ) && __GNUC__ * 100 + __GNUC_MINOR__ <= 404
// GCC 4.4 supports an outdated version of rvalue references and creates a copy of the forwarded object.
// This results in warnings 'returning reference to temporary'. Therefore we use a special version similar to std::forward.
template< class T > T&& sp_forward( T && t ) BOOST_NOEXCEPT
{
return t;
}
#else
template< class T > T&& sp_forward( T & t ) BOOST_NOEXCEPT
{
return static_cast< T&& >( t );
}
#endif
#endif
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_FORWARD_HPP_INCLUDED

View File

@@ -0,0 +1,30 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_HAS_GCC_INTRINSICS_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_HAS_GCC_INTRINSICS_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
// boost/smart_ptr/detail/sp_has_gcc_intrinsics.hpp
//
// Copyright 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
//
// Defines the BOOST_SP_HAS_GCC_INTRINSICS macro if the __atomic_*
// intrinsics are available.
// Libraries (e.g. Kokkos) sometimes define the __ATOMIC_RELAXED macros,
// leading to errors under MSVC (https://github.com/boostorg/smart_ptr/pull/112)
#if defined( __ATOMIC_RELAXED ) && defined( __ATOMIC_ACQUIRE ) && defined( __ATOMIC_RELEASE ) && defined( __ATOMIC_ACQ_REL ) \
&& !( defined(_MSC_VER) && !defined(__clang__) )
# define BOOST_SP_HAS_GCC_INTRINSICS
#endif
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_HAS_GCC_INTRINSICS_HPP_INCLUDED

View File

@@ -1,69 +0,0 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// boost/smart_ptr/detail/sp_has_sync.hpp
//
// Copyright (c) 2008, 2009 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Defines the BOOST_SP_HAS_SYNC macro if the __sync_* intrinsics
// are available.
//
#ifndef BOOST_SP_NO_SYNC
#if !defined( __c2__ ) && defined( __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 )
# define BOOST_SP_HAS_SYNC
#elif defined( __IBMCPP__ ) && ( __IBMCPP__ >= 1210 ) && !defined( __COMPILER_VER__ )
# define BOOST_SP_HAS_SYNC
#elif !defined( __c2__ ) && defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 )
#define BOOST_SP_HAS_SYNC
#if defined( __arm__ ) || defined( __armel__ )
#undef BOOST_SP_HAS_SYNC
#endif
#if defined( __hppa ) || defined( __hppa__ )
#undef BOOST_SP_HAS_SYNC
#endif
#if defined( __m68k__ )
#undef BOOST_SP_HAS_SYNC
#endif
#if defined( __sh__ )
#undef BOOST_SP_HAS_SYNC
#endif
#if defined( __sparc__ )
#undef BOOST_SP_HAS_SYNC
#endif
#if defined( __INTEL_COMPILER ) && !defined( __ia64__ ) && ( __INTEL_COMPILER < 1110 )
#undef BOOST_SP_HAS_SYNC
#endif
#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

View File

@@ -0,0 +1,69 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_INTRINSICS_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_INTRINSICS_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// boost/smart_ptr/detail/sp_has_sync_intrinsics.hpp
//
// Copyright (c) 2008, 2009 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Defines the BOOST_SP_HAS_SYNC_INTRINSICS macro if the __sync_* intrinsics
// are available.
//
#if !defined( BOOST_SP_NO_SYNC_INTRINSICS ) && !defined( BOOST_SP_NO_SYNC )
#if defined( __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 ) && !defined( __c2__ )
# define BOOST_SP_HAS_SYNC_INTRINSICS
#elif defined( __IBMCPP__ ) && ( __IBMCPP__ >= 1210 ) && !defined( __COMPILER_VER__ )
# define BOOST_SP_HAS_SYNC_INTRINSICS
#elif defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 ) && !defined( __c2__ )
#define BOOST_SP_HAS_SYNC_INTRINSICS
#if defined( __arm__ ) || defined( __armel__ )
#undef BOOST_SP_HAS_SYNC_INTRINSICS
#endif
#if defined( __hppa ) || defined( __hppa__ )
#undef BOOST_SP_HAS_SYNC_INTRINSICS
#endif
#if defined( __m68k__ )
#undef BOOST_SP_HAS_SYNC_INTRINSICS
#endif
#if defined( __sh__ )
#undef BOOST_SP_HAS_SYNC_INTRINSICS
#endif
#if defined( __sparc__ )
#undef BOOST_SP_HAS_SYNC_INTRINSICS
#endif
#if defined( __INTEL_COMPILER ) && !defined( __ia64__ ) && ( __INTEL_COMPILER < 1110 )
#undef BOOST_SP_HAS_SYNC_INTRINSICS
#endif
#if defined(__PATHSCALE__) && ((__PATHCC__ == 4) && (__PATHCC_MINOR__ < 9))
#undef BOOST_SP_HAS_SYNC_INTRINSICS
#endif
#endif
#endif // #if !defined( BOOST_SP_NO_SYNC_INTRINSICS ) && !defined( BOOST_SP_NO_SYNC )
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_INTRINSICS_HPP_INCLUDED

View File

@@ -32,11 +32,21 @@
// MinGW-w64 provides intrin.h for both 32 and 64-bit targets.
# define BOOST_SP_HAS_INTRIN_H
#elif defined( __LP64__ )
// We have to use intrin.h on Cygwin 64
# 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
// clang-cl on Windows on VC10+ stdlib
#elif defined( __clang__ ) && defined( _MSC_VER ) && defined( _CPPLIB_VER ) && _CPPLIB_VER >= 520
# define BOOST_SP_HAS_INTRIN_H
#endif
#if defined( BOOST_USE_WINDOWS_H )

View File

@@ -15,25 +15,16 @@
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/config.hpp>
// BOOST_SP_NOEXCEPT
// BOOST_SP_NOEXCEPT (obsolete, only retained for compatibility)
#if defined( BOOST_MSVC ) && BOOST_MSVC >= 1700 && BOOST_MSVC < 1900
#define BOOST_SP_NOEXCEPT noexcept
# define BOOST_SP_NOEXCEPT BOOST_NOEXCEPT_OR_NOTHROW
#else
# define BOOST_SP_NOEXCEPT BOOST_NOEXCEPT
#endif
// BOOST_SP_NOEXCEPT_WITH_ASSERT
// BOOST_SP_NOEXCEPT_WITH_ASSERT (noexcept, unless a user assertion handler is present)
#if defined(BOOST_DISABLE_ASSERTS) || ( defined(BOOST_ENABLE_ASSERT_DEBUG_HANDLER) && defined(NDEBUG) )
# define BOOST_SP_NOEXCEPT_WITH_ASSERT BOOST_SP_NOEXCEPT
# define BOOST_SP_NOEXCEPT_WITH_ASSERT noexcept
#elif defined(BOOST_ENABLE_ASSERT_HANDLER) || ( defined(BOOST_ENABLE_ASSERT_DEBUG_HANDLER) && !defined(NDEBUG) )
@@ -41,7 +32,7 @@
#else
# define BOOST_SP_NOEXCEPT_WITH_ASSERT BOOST_SP_NOEXCEPT
# define BOOST_SP_NOEXCEPT_WITH_ASSERT noexcept
#endif

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