Compare commits

...

112 Commits

Author SHA1 Message Date
1c61e54b13 Update documentation 2020-06-05 18:12:59 +03:00
a0fc1e6daa Add wp_unordered_test 2020-06-04 20:52:17 +03:00
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
bc677e9098 Do not require boost::hash in the std::hash specializations 2020-06-03 17:38:03 +03:00
688cfed63e Add Boost::bind to CMake test dependencies 2020-06-03 07:38:07 +03:00
c63dc266b9 Update submodule libs/bind on Travis/Appveyor 2020-06-02 21:51:00 +03:00
6c181a0707 When BOOST_SP_REPORT_IMPLEMENTATION is defined, report what platform-specific atomic implementation is used 2020-06-02 20:51:38 +03:00
4047290b85 Add multithreaded tests 2020-06-02 18:58:45 +03:00
dc6c76d7e9 Move lightweight_thread.hpp to smart_ptr/detail 2020-06-02 17:55:15 +03:00
5a18ffdc56 Add std::hash specializations for shared_ptr, local_shared_ptr, intrusive_ptr 2020-06-02 05:59:23 +03:00
09fdd5ebfd Add FreeBSD to Travis 2020-06-01 18:18:57 +03:00
911874e139 Add gcc-10 to Travis 2020-06-01 18:18:12 +03:00
c7c0eacb74 Add initializers to eq and lt 2020-06-01 15:08:53 +03:00
9ed9f43ca8 Document owner_less, owner_equal_to 2020-06-01 03:53:21 +03:00
0ddf990869 Add noexcept to owner_less, owner_equal_to 2020-06-01 03:44:41 +03:00
a08a5f3d41 Update introduction 2020-06-01 03:26:02 +03:00
77c2d4cad7 Add owner_less_test2 2020-06-01 03:13:42 +03:00
fd612dc114 Add owner_equal_to 2020-06-01 03:05:34 +03:00
e67ebef9a7 Update changelog 2020-06-01 02:01:10 +03:00
6f5b9c7b37 Document local_shared_ptr::owner_equals 2020-06-01 01:59:40 +03:00
91f3aa0386 Add local_shared_ptr::owner_equals 2020-06-01 01:35:25 +03:00
686a354f21 Add lsp_owner_before_test 2020-06-01 01:16:46 +03:00
efceb04665 Asciidoctor 2 fixes 2020-06-01 01:02:09 +03:00
ca57860ae2 Update footer 2020-06-01 00:41:25 +03:00
9dcd05f918 Document owner_equals 2020-06-01 00:40:02 +03:00
4b724ab3f8 Add mixed shared_count/weak_count operator== overloads to avoid refcount manipulation 2020-05-31 22:07:36 +03:00
58915ca2fe Add owner_equals 2020-05-31 21:41:06 +03:00
62b0e5cdf4 Add mixed shared_count/weak_count operator< overloads to avoid refcount manipulation 2020-05-31 21:12:12 +03:00
951ff783b5 Add sp_owner_before_test 2020-05-31 20:33:24 +03:00
6421394e70 Fix msvc-8.0 failures 2020-05-31 20:14:25 +03:00
121312cc22 Use allocator access utilities 2020-05-21 23:14:23 -04:00
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
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
2af343a2cb Fix Clang-tidy modernize-use-override warnings. 2020-05-12 18:01:55 -07:00
c6b3700ef1 Merge branch 'develop' of https://github.com/boostorg/smart_ptr into cppbuilder 2020-05-06 11:32:12 -04:00
2a93d30e73 Change conditions to be the same. 2020-05-06 11:31:57 -04:00
02cc561248 Only use warnings-as-errors on msvc, gcc, clang 2020-04-28 05:05:57 +03:00
066b398114 Disable -Wc11-extensions in sp_counted_base_clang.hpp 2020-04-27 00:50:15 +03:00
9c43c69c14 Add sp_pedantic_test 2020-04-26 19:57:05 +03:00
eb8998cd91 Add Clang 10 to Travis 2020-04-26 18:27:35 +03:00
df06c324a7 Merge branch 'develop' of https://github.com/boostorg/smart_ptr into cppbuilder 2020-04-19 02:49:06 -04:00
0ddfab493c Do not enable -Wsuggest-override in C++03 mode 2020-04-14 07:12:35 +03:00
a2732e207a Add BOOST_OVERRIDE to sp_counted_impl.hpp 2020-04-14 00:55:52 +03:00
5be7523ebe Merge branch 'develop' into feature/suggest-override 2020-04-14 00:45:24 +03:00
2320dafc03 Add BOOST_OVERRIDE to bad_weak_ptr.hpp and local_counted_base.hpp 2020-04-14 00:42:57 +03:00
7ab4093f46 Use shared_ptr and make_shared in sp_override_test 2020-04-14 00:32:25 +03:00
296c203135 Rename sp_warning_test to sp_override_test 2020-04-14 00:15:32 +03:00
2dd35e5fbc Mark functions with BOOST_OVERRIDE 2020-04-13 15:34:13 -04:00
977544feda Add sp_warning_test 2020-04-08 21:25:36 +03:00
54b5498208 Manually convince clang-cl to fail shared_from_fail and weak_from_fail 2020-04-02 04:01:21 +03:00
da81452f1f Make shared_from_this and weak_from_this private in enable_shared_from. Fixes #75. 2020-04-02 02:16:59 +03:00
7b9a969215 Add deduction guides to shared_ptr and weak_ptr. Fixes #73. 2020-04-02 00:28:02 +03:00
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
91cd83e5bf Correct make_unique_noinit example 2020-02-13 21:36:58 -05:00
2fdb8c4b0a Fix Travis issues; remove unnecessary jobs 2020-01-14 19:16:05 +02:00
e806b53433 Update Travis 2020-01-14 17:04:51 +02:00
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
766ab05a12 Update submodule libs/preprocessor on Travis (needed by CMake tests) 2020-01-09 15:53:38 +02:00
05cbefd28e Update submodule tools/cmake on Travis 2020-01-09 01:41:15 +02:00
bfbdf4f45f Add CMake install support, tests 2020-01-08 05:08:37 +02:00
169c0cd52a Remove lwm_nop.hpp; add lwm_std_mutex.hpp 2020-01-08 03:57:13 +02:00
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
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
43d1fe12c5 Include lightweight_test from core and workaround from config 2020-01-01 08:31:25 -05:00
a2749dddb4 Disable 32 bit clang-win to avoid mspdbcore.dll errors 2019-12-05 15:49:48 +02:00
a71e62146c Add VS2019 to Appveyor; separate clang-win into its own job 2019-11-24 00:05:38 +02:00
274ec17836 Even more documentation corrections 2019-09-15 02:06:23 -04:00
a7341070f1 More documentation corrections 2019-09-03 11:53:42 -04:00
a6323354cd Update constraints and synopsis in documentation 2019-09-02 22:10:09 -04:00
f788448101 Document alloc_deleter 2019-08-30 12:52:50 -04:00
283f2d2a11 Simplify synopsis using alias template 2019-08-30 12:04:09 -04:00
034f94617d Workaround for VC10 unique_ptr operator-> 2019-08-30 12:03:36 -04:00
6a5f67b3a2 Disable tests on VC10 which lacks conforming unique_ptr 2019-08-30 10:50:56 -04:00
dcd3c8ef80 In test cases, include allocate_unique first 2019-08-30 08:17:54 -04:00
bb2a453ff6 Add additional test cases 2019-08-30 08:16:11 -04:00
e56eec70ca Call to_address in the scalar destroy case too 2019-08-30 07:39:02 -04:00
60c26acab8 Implement allocate_unique 2019-08-30 00:31:28 -04:00
00f6b5dcb0 Split gcc 8/9 Travis jobs (again) due to log size 2019-08-29 13:20:36 +03:00
6195ae1eb0 Disable -Wdelete-non-virtual-dtor 2019-08-29 12:27:51 +03:00
30291c406a Update .travis.yml 2019-08-29 01:01:52 +03:00
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
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
e4d642c46a Revert Travis to Trusty 2019-05-30 02:42:39 +03:00
3dffa64f58 Bind allocator to element type, not scalar type 2019-05-15 07:33:04 -04:00
af92bd89ef allocation_ptr will be modified, renamed, and moved to detail 2019-05-05 22:21:22 -04:00
4742143605 Support allocation_ptr of const and volatile types 2019-05-04 09:43:11 -04:00
872bf10347 Move construct and destroy from Smart_Ptr to Core 2019-05-03 17:39:25 -04:00
c0ae9b3728 Implement allocation_ptr 2019-05-02 19:26:29 -04:00
1298c2e8e5 Include sp_noexcept.hpp in sp_construct.hpp 2019-05-02 18:00:53 -04:00
d593061b15 Move construct and destroy utilities to common header 2019-05-02 09:48:45 -04:00
5072045f12 Use boost::noinit_adapt free function 2019-04-29 00:37:55 -04:00
442e179920 Simplify implementation in terms of noinit_adaptor 2019-04-28 22:42:37 -04:00
9544a8cb91 Add revision history for 1.65 2019-04-24 17:21:37 +03:00
5823d6bcc9 Document enable_shared_from 2019-04-24 05:16:03 +03:00
f56e609757 Fix mistake in weak_from_this_test 2019-04-24 04:57:37 +03:00
8df63a3d0e Add tests for enable_shared_from 2019-04-24 04:50:59 +03:00
4b6cb1223b Add boost/smart_ptr/enable_shared_from.hpp 2019-04-24 04:50:30 +03:00
719e819570 Under g++ 4.4, <memory> doesn't compile with rtti=off 2019-04-22 15:57:56 +03:00
a571b3a250 Only include core/typeinfo.hpp when needed 2019-04-22 06:07:36 +03:00
f17c5e8e3b Add a few no_rtti tests 2019-04-22 05:43:08 +03:00
e306b30dcf Use a private detail/sp_typeinfo header instead of the deprecated Core one 2019-04-22 05:25:07 +03:00
b6b49ef591 Split g++ 8 Travis job, because log length 2019-04-22 02:19:27 +03:00
2122c7753c Avoid memcpy over a spinlock, because g++ 8 warns 2019-04-22 02:17:28 +03:00
7c76fb385d Add clang-win to Appveyor 2019-04-22 00:59:38 +03:00
372fac679b Remove _internal_aliasing_assign 2019-04-21 23:13:06 +03:00
e3adcaed1e Add revision history 2019-04-21 23:00:24 +03:00
016e682af6 Document weak_ptr aliasing constructors and empty 2019-04-21 22:52:44 +03:00
78e095d761 Disable tests that don't compile on msvc-8.0 2019-04-21 22:50:24 +03:00
eb8a91cb46 Add tests for the weak_ptr aliasing constructors 2019-04-21 22:44:09 +03:00
513cd15378 Add aliasing constructors to weak_ptr. Closes #67. 2019-04-21 22:43:04 +03:00
7bfa6a1f3d Fix typo 2019-04-21 21:33:55 +03:00
8120bb44cb Add rvalue pointer casts (closes #66) 2019-04-21 00:47:36 +03:00
223 changed files with 6916 additions and 1106 deletions

View File

@ -1,10 +1,10 @@
# Copyright 2016-2019 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,8 +23,23 @@ matrix:
include:
- os: linux
arch: arm64
compiler: g++
env: TOOLSET=gcc COMPILER=g++ CXXSTD=03,11
env: TOOLSET=gcc COMPILER=g++ CXXSTD=03,11,14
- os: linux
arch: ppc64le
compiler: g++
env: TOOLSET=gcc COMPILER=g++ CXXSTD=03,11,14
- os: linux
arch: s390x
compiler: g++
env: TOOLSET=gcc COMPILER=g++ CXXSTD=03,11,14
- os: freebsd
compiler: clang++
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,17,2a
- os: linux
compiler: g++-4.4
@ -107,7 +122,7 @@ matrix:
- os: linux
compiler: g++-8
env: TOOLSET=gcc COMPILER=g++-8 CXXSTD=03,11,14,17,2a
env: TOOLSET=gcc COMPILER=g++-8 CXXSTD=03,11,14
addons:
apt:
packages:
@ -115,6 +130,58 @@ matrix:
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-8
env: TOOLSET=gcc COMPILER=g++-8 CXXSTD=17,2a
addons:
apt:
packages:
- g++-8
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-9
env: TOOLSET=gcc COMPILER=g++-9 CXXSTD=03,11,14
addons:
apt:
packages:
- g++-9
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-9
env: TOOLSET=gcc COMPILER=g++-9 CXXSTD=17,2a
addons:
apt:
packages:
- g++-9
sources:
- ubuntu-toolchain-r-test
- os: linux
dist: bionic
compiler: g++-10
env: TOOLSET=gcc COMPILER=g++-10 CXXSTD=03,11,14
addons:
apt:
packages:
- g++-10
sources:
- ubuntu-toolchain-r-test
- os: linux
dist: bionic
compiler: g++-10
env: TOOLSET=gcc COMPILER=g++-10 CXXSTD=17,2a
addons:
apt:
packages:
- g++-10
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 LINKFLAGS=-fuse-ld=gold
@ -126,10 +193,7 @@ matrix:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11
- os: linux
dist: trusty
compiler: /usr/bin/clang++
env: TOOLSET=clang COMPILER=/usr/bin/clang++ CXXSTD=03,11
addons:
@ -138,6 +202,7 @@ matrix:
- clang-3.3
- os: linux
dist: trusty
compiler: /usr/bin/clang++
env: TOOLSET=clang COMPILER=/usr/bin/clang++ CXXSTD=03,11
addons:
@ -147,15 +212,13 @@ matrix:
- os: linux
compiler: clang++-3.5
env: TOOLSET=clang COMPILER=clang++-3.5 CXXSTD=03,11,14,1z
env: TOOLSET=clang COMPILER=clang++-3.5 CXXSTD=03,11
addons:
apt:
packages:
- clang-3.5
- libstdc++-4.9-dev
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.5
- os: linux
compiler: clang++-3.6
@ -166,7 +229,6 @@ matrix:
- clang-3.6
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.6
- os: linux
compiler: clang++-3.7
@ -177,7 +239,6 @@ matrix:
- clang-3.7
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.7
- os: linux
compiler: clang++-3.8
@ -186,10 +247,8 @@ matrix:
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
@ -198,10 +257,8 @@ matrix:
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
@ -212,7 +269,6 @@ matrix:
- clang-4.0
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-4.0
- os: linux
compiler: clang++-5.0
@ -223,7 +279,6 @@ matrix:
- clang-5.0
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-5.0
- os: linux
compiler: clang++-6.0
@ -234,7 +289,6 @@ matrix:
- clang-6.0
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-6.0
- os: linux
compiler: clang++-7
@ -245,21 +299,58 @@ matrix:
- clang-7
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-7
- llvm-toolchain-xenial-7
- os: linux
compiler: clang++-7
env: UBSAN=1 TOOLSET=clang COMPILER=clang++-7 CXXSTD=03,11,14,17,2a UBSAN_OPTIONS=print_stacktrace=1
compiler: clang++-8
env: TOOLSET=clang COMPILER=clang++-8 CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
- clang-7
- libstdc++-5-dev
- clang-8
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-7
- llvm-toolchain-xenial-8
- os: linux
dist: xenial
compiler: clang++-9
env: TOOLSET=clang COMPILER=clang++-9 CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
- clang-9
sources:
- ubuntu-toolchain-r-test
- sourceline: 'deb https://apt.llvm.org/xenial/ llvm-toolchain-xenial-9 main'
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
- os: linux
dist: xenial
compiler: clang++-10
env: TOOLSET=clang COMPILER=clang++-10 CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
- clang-10
sources:
- ubuntu-toolchain-r-test
- sourceline: 'deb https://apt.llvm.org/xenial/ llvm-toolchain-xenial-10 main'
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
- os: linux
compiler: clang++-8
env: UBSAN=1 TOOLSET=clang COMPILER=clang++-8 CXXSTD=03,11,14,17,2a UBSAN_OPTIONS=print_stacktrace=1
addons:
apt:
packages:
- clang-8
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-xenial-8
- os: linux
dist: trusty
compiler: clang++-libc++
env: TOOLSET=clang COMPILER=clang++-libc++ CXXSTD=03,11,14,1z
addons:
@ -268,6 +359,7 @@ matrix:
- libc++-dev
- 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:
@ -279,6 +371,17 @@ matrix:
compiler: clang++
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z
- os: osx
compiler: clang++
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 ..
- ctest --output-on-failure -R boost_smart_ptr
- os: linux
compiler: g++
env: CMAKE_SUBDIR_TEST=1
@ -288,6 +391,17 @@ matrix:
- cmake --build .
- cmake --build . --target check
- os: linux
env: CMAKE_INSTALL_TEST=1
script:
- 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
- cd ..
@ -309,7 +423,10 @@ install:
- git submodule init tools/build
- git submodule init libs/headers
- git submodule init tools/boost_install
- git submodule update --jobs 3
- 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

View File

@ -1,12 +1,10 @@
# Copyright 2018 Mike Dev
# Copyright 2018-2020 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
# Partial (add_subdirectory only) and experimental CMake support
# Subject to change; please do not rely on the contents of this file yet
cmake_minimum_required(VERSION 3.5...3.16)
cmake_minimum_required(VERSION 3.5)
project(BoostSmartPtr LANGUAGES CXX)
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)
@ -14,13 +12,25 @@ 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::move
Boost::predef
Boost::static_assert
Boost::throw_exception
Boost::type_traits
INTERFACE
Boost::assert
Boost::config
Boost::core
Boost::move
Boost::static_assert
Boost::throw_exception
Boost::type_traits
)
if(BOOST_SUPERPROJECT_VERSION)
include(BoostInstall)
boost_install(TARGETS boost_smart_ptr HEADER_DIRECTORY include/)
endif()
if(BUILD_TESTING)
add_subdirectory(test)
endif()

View File

@ -23,6 +23,14 @@ environment:
TOOLSET: msvc-14.1
CXXSTD: 14,17
ADDRMD: 32,64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
TOOLSET: clang-win
CXXSTD: 14,17
ADDRMD: 64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
TOOLSET: msvc-14.2
CXXSTD: 14,17
ADDRMD: 32,64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
ADDPATH: C:\cygwin\bin;
TOOLSET: gcc
@ -62,6 +70,7 @@ install:
- git submodule init tools/build
- git submodule init libs/headers
- git submodule init tools/boost_install
- git submodule init libs/bind
- git submodule update --jobs 3
- xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\smart_ptr\
- cmd /c bootstrap

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

@ -18,34 +18,25 @@ Greg Colvin, Beman Dawes, Peter Dimov, Glen Fernandes
: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[]
// appendix
include::smart_ptr/techniques.adoc[]
@ -67,7 +58,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,318 @@
////
Copyright 2019 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);
}
```
## 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);`
## 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,38 @@
////
Copyright 2019, 2020 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.74.0
* Added `owner_equals` to `shared_ptr`, `weak_ptr`, `local_shared_ptr`
* Added `owner_equal_to`
* Added `std::hash` specializations for `shared_ptr`, `local_shared_ptr`
* Added `owner_hash_value` to `shared_ptr`, `weak_ptr`
* Added `boost::hash` support 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

@ -77,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>
@ -174,7 +174,8 @@ template<class Y> intrusive_ptr(intrusive_ptr<Y> && r);
[none]
* {blank}
+
Postconditions:: `get()` equals the old value of `r.get()`. `r.get() == 0`.
Postconditions::
`get()` equals the old value of `r.get()`. `r.get() == 0`.
### destructor
@ -185,7 +186,8 @@ Postconditions:: `get()` equals the old value of `r.get()`. `r.get() == 0`.
[none]
* {blank}
+
Effects:: `if(get() != 0) intrusive_ptr_release(get());`.
Effects::
`if(get() != 0) intrusive_ptr_release(get());`.
### assignment
@ -245,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
@ -278,7 +281,8 @@ T * get() const noexcept;
[none]
* {blank}
+
Returns:: the stored pointer.
Returns::
the stored pointer.
### detach
@ -325,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
@ -412,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
@ -437,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
@ -449,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
@ -461,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

@ -111,7 +111,8 @@ intrusive_ref_counter& operator=(const intrusive_ref_counter& v) noexcept;
[none]
* {blank}
+
Effects:: Does nothing, reference counter is not modified.
Effects::
Does nothing, reference counter is not modified.
### use_count
@ -137,7 +138,8 @@ template<class Derived, class CounterPolicy>
[none]
* {blank}
+
Effects:: Increments the reference counter.
Effects::
Increments the reference counter.
### intrusive_ptr_release

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

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
@ -181,8 +181,7 @@ template<class T, class A, class... Args>
[none]
* {blank}
+
Remarks:: These overloads shall only participate in overload resolution when
`T` is not an array type.
Constraints:: `T` is not an array.
Returns:: A `shared_ptr` to an object of type `T`, constructed from
`args\...`.
Examples::
@ -200,10 +199,9 @@ template<class T, class A>
[none]
* {blank}
+
Remarks:: These overloads shall only participate in overload resolution when
`T` is an array type of the form `U[]`.
Constraints:: `T` is an array of unknown bounds.
Returns:: A `shared_ptr` to a sequence of `n` value-initialized objects of
type `U`.
type `remove_extent_t<T>`.
Examples::
* `auto p = make_shared<double[]>(1024);`
* `auto p = make_shared<double[][2][2]>(6);`
@ -219,10 +217,9 @@ template<class T, class A>
[none]
* {blank}
+
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`.
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]>();`
@ -238,10 +235,9 @@ template<class T, class A> shared_ptr<T>
[none]
* {blank}
+
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`.
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});`
@ -258,10 +254,9 @@ template<class T, class A>
[none]
* {blank}
+
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`.
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});`
@ -278,10 +273,10 @@ template<class T, class A>
[none]
* {blank}
+
Remarks:: These overloads shall only participate in overload resolution when
`T` is not an array type, or an array type of the `U[N]`.
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 `N` default-initialized objects of type `U`, respectively.
sequence of `extent_v<T>` default-initialized objects of type
`remove_extent_t<T>`, respectively.
Example:: `auto p = make_shared_noinit<double[1024]>();`
```
@ -295,8 +290,7 @@ template<class T, class A>
[none]
* {blank}
+
Remarks:: These overloads shall only participate in overload resolution when
`T` is an array type of the form `U[]`.
Constraints:: `T` is an array of unknown bounds.
Returns:: A `shared_ptr` to a sequence of `_n_` default-initialized objects
of type `U`.
of type `remove_extent_t<T>`.
Example:: `auto p = make_shared_noinit<double[]>(1024);`

View File

@ -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);
}
@ -71,20 +71,18 @@ template<class T, class... Args>
[none]
* {blank}
+
Remarks:: These overloads shall only participate in overload resolution when
`T` is not an array type.
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);
```
[none]
* {blank}
+
Remarks:: These overloads shall only participate in overload resolution when
`T` is not an array type.
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});`
@ -95,9 +93,8 @@ template<class T>
[none]
* {blank}
+
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]())`.
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);`
```
@ -107,10 +104,9 @@ template<class T>
[none]
* {blank}
+
Remarks:: These overloads shall only participate in overload resolution when
`T` is not an array type.
Constraints:: `T` is not an array.
Returns:: `std::unique_ptr<T>(new T)`.
Example:: `auto p = make_unique_noinit<double[1024]>();`
Example:: `auto p = make_unique_noinit<std::array<double, 1024> >();`
```
template<class T>
@ -119,7 +115,6 @@ template<class T>
[none]
* {blank}
+
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])`.
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,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

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

@ -73,7 +73,7 @@ void * operator new(size_t n) throw(bad_alloc)
return p;
}
#if !defined(__BORLANDC__) || (__BORLANDC__ > 0x551)
#if !defined(BOOST_BORLANDC) || (BOOST_BORLANDC > 0x551)
void * operator new(size_t n, nothrow_t const &) throw()
{
@ -95,7 +95,7 @@ void * operator new[](size_t n) throw(bad_alloc)
return p;
}
#if !defined(__BORLANDC__) || (__BORLANDC__ > 0x551)
#if !defined(BOOST_BORLANDC) || (BOOST_BORLANDC > 0x551)
void * operator new[](size_t n, nothrow_t const &) throw()
{
@ -205,7 +205,7 @@ void operator delete(void * p) throw()
free(pm);
}
#if !defined(__BORLANDC__) || (__BORLANDC__ > 0x551)
#if !defined(BOOST_BORLANDC) || (BOOST_BORLANDC > 0x551)
void operator delete(void * p, nothrow_t const &) throw()
{
@ -231,7 +231,7 @@ void operator delete[](void * p) throw()
free(pm);
}
#if !defined(__BORLANDC__) || (__BORLANDC__ > 0x551)
#if !defined(BOOST_BORLANDC) || (BOOST_BORLANDC > 0x551)
void operator delete[](void * p, nothrow_t const &) throw()
{

View File

@ -21,168 +21,6 @@
// 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" 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( lw_thread_t & th, 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 = lw_thread_create_( &th, 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

@ -21,11 +21,12 @@ public:
count_ = shared_count(base);
}
virtual void local_cb_destroy() BOOST_SP_NOEXCEPT {
void local_cb_destroy() BOOST_SP_NOEXCEPT BOOST_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
BOOST_SP_NOEXCEPT BOOST_OVERRIDE {
return count_;
}
@ -72,21 +73,19 @@ inline typename enable_if_<is_unbounded_array<T>::value,
local_shared_ptr<T> >::type
allocate_local_shared(const A& allocator, std::size_t count)
{
typedef typename remove_extent<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, scalar>::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>
@ -94,23 +93,22 @@ inline typename enable_if_<is_bounded_array<T>::value,
local_shared_ptr<T> >::type
allocate_local_shared(const A& allocator)
{
typedef typename remove_extent<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
enum {
size = detail::sp_array_count<T, scalar>::value
count = extent<T>::value
};
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>
@ -119,25 +117,19 @@ inline typename enable_if_<is_unbounded_array<T>::value,
allocate_local_shared(const A& allocator, std::size_t count,
const typename remove_extent<T>::type& value)
{
typedef typename remove_extent<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;
enum {
total = detail::sp_array_count<type, scalar>::value
};
std::size_t size = count * total;
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), total, 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>
@ -146,25 +138,22 @@ inline typename enable_if_<is_bounded_array<T>::value,
allocate_local_shared(const A& allocator,
const typename remove_extent<T>::type& value)
{
typedef typename remove_extent<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
enum {
size = detail::sp_array_count<T, scalar>::value
count = extent<T>::value
};
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, scalar>::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>
@ -172,22 +161,8 @@ inline typename enable_if_<is_unbounded_array<T>::value,
local_shared_ptr<T> >::type
allocate_local_shared_noinit(const A& allocator, std::size_t count)
{
typedef typename remove_extent<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, scalar>::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>
@ -195,24 +170,7 @@ inline typename enable_if_<is_bounded_array<T>::value,
local_shared_ptr<T> >::type
allocate_local_shared_noinit(const A& allocator)
{
typedef typename remove_extent<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
enum {
size = detail::sp_array_count<T, scalar>::value
};
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

@ -8,15 +8,15 @@ 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/enable_if.hpp>
#include <boost/type_traits/extent.hpp>
#include <boost/type_traits/is_bounded_array.hpp>
#include <boost/type_traits/is_unbounded_array.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/remove_all_extents.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/remove_extent.hpp>
#include <boost/type_traits/type_with_alignment.hpp>
@ -25,15 +25,22 @@ namespace boost {
namespace detail {
template<class T>
struct sp_array_scalar {
struct sp_array_element {
typedef typename boost::remove_cv<typename
boost::remove_all_extents<T>::type>::type type;
boost::remove_extent<T>::type>::type type;
};
template<class T, class U>
template<class T>
struct sp_array_count {
enum {
value = sizeof(T) / sizeof(U)
value = 1
};
};
template<class T, std::size_t N>
struct sp_array_count<T[N]> {
enum {
value = N * sp_array_count<T>::value
};
};
@ -51,18 +58,6 @@ 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
@ -70,154 +65,6 @@ sp_objects(std::size_t size) BOOST_SP_NOEXCEPT
return (size + sizeof(T) - 1) / sizeof(T);
}
template<bool E, class A, class T>
inline typename boost::enable_if_<!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 boost::enable_if_<!E &&
!boost::has_trivial_destructor<T>::value>::type
sp_array_destroy(A&, T* ptr, std::size_t size)
{
while (size > 0) {
ptr[--size].~T();
}
}
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
template<bool E, class A, class T>
inline typename boost::enable_if_<E>::type
sp_array_destroy(A& allocator, T* ptr, std::size_t size)
{
while (size > 0) {
std::allocator_traits<A>::destroy(allocator, ptr + --size);
}
}
#endif
template<bool E, class A, class T>
class sp_destroyer {
public:
sp_destroyer(A& allocator, T* ptr) BOOST_SP_NOEXCEPT
: allocator_(allocator),
ptr_(ptr),
size_(0) { }
~sp_destroyer() {
sp_array_destroy<E>(allocator_, ptr_, size_);
}
std::size_t& size() BOOST_SP_NOEXCEPT {
return size_;
}
private:
sp_destroyer(const sp_destroyer&);
sp_destroyer& operator=(const sp_destroyer&);
A& allocator_;
T* ptr_;
std::size_t size_;
};
template<bool E, class A, class T>
inline typename boost::enable_if_<!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* ptr, std::size_t size)
{
for (std::size_t i = 0; i < size; ++i) {
ptr[i] = T();
}
}
template<bool E, class A, class T>
inline typename boost::enable_if_<!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* ptr, std::size_t size, const T* list,
std::size_t count)
{
for (std::size_t i = 0; i < size; ++i) {
ptr[i] = list[i % count];
}
}
template<bool E, class A, class T>
inline typename boost::enable_if_<!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* ptr, std::size_t size)
{
sp_destroyer<E, A, T> hold(none, ptr);
for (std::size_t& i = hold.size(); i < size; ++i) {
::new(static_cast<void*>(ptr + i)) T();
}
hold.size() = 0;
}
template<bool E, class A, class T>
inline typename boost::enable_if_<!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* ptr, std::size_t size, const T* list,
std::size_t count)
{
sp_destroyer<E, A, T> hold(none, ptr);
for (std::size_t& i = hold.size(); i < size; ++i) {
::new(static_cast<void*>(ptr + i)) T(list[i % count]);
}
hold.size() = 0;
}
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
template<bool E, class A, class T>
inline typename boost::enable_if_<E>::type
sp_array_construct(A& allocator, T* ptr, std::size_t size)
{
sp_destroyer<E, A, T> hold(allocator, ptr);
for (std::size_t& i = hold.size(); i < size; ++i) {
std::allocator_traits<A>::construct(allocator, ptr + i);
}
hold.size() = 0;
}
template<bool E, class A, class T>
inline typename boost::enable_if_<E>::type
sp_array_construct(A& allocator, T* ptr, std::size_t size, const T* list,
std::size_t count)
{
sp_destroyer<E, A, T> hold(allocator, ptr);
for (std::size_t& i = hold.size(); i < size; ++i) {
std::allocator_traits<A>::construct(allocator, ptr + i,
list[i % count]);
}
hold.size() = 0;
}
#endif
template<class A, class T>
inline typename
boost::enable_if_<boost::has_trivial_constructor<T>::value>::type
sp_array_default(A&, T*, std::size_t) BOOST_SP_NOEXCEPT { }
template<class A, class T>
inline typename
boost::enable_if_<!boost::has_trivial_constructor<T>::value>::type
sp_array_default(A& none, T* ptr, std::size_t size)
{
sp_destroyer<false, A, T> hold(none, ptr);
for (std::size_t& i = hold.size(); i < size; ++i) {
::new(static_cast<void*>(ptr + i)) T;
}
hold.size() = 0;
}
template<class A>
class sp_array_state {
public:
@ -262,29 +109,6 @@ 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 {
@ -300,39 +124,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) BOOST_SP_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 boost::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
: 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_));
@ -343,13 +160,11 @@ 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>
template<class T>
class BOOST_SYMBOL_VISIBLE sp_array_base
: public sp_counted_base {
typedef typename T::type allocator;
@ -358,50 +173,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);
}
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());
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);
}
T& state() BOOST_SP_NOEXCEPT {
return state_;
}
virtual void dispose() BOOST_SP_NOEXCEPT {
sp_array_destroy<E>(state_.allocator(),
sp_array_start<sp_array_base, type>(this), state_.size());
void dispose() BOOST_SP_NOEXCEPT BOOST_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() BOOST_SP_NOEXCEPT {
void destroy() BOOST_SP_NOEXCEPT BOOST_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&) BOOST_SP_NOEXCEPT {
void* get_deleter(const sp_typeinfo_&) BOOST_SP_NOEXCEPT BOOST_OVERRIDE {
return 0;
}
virtual void* get_local_deleter(const sp_typeinfo&) BOOST_SP_NOEXCEPT {
void* get_local_deleter(const sp_typeinfo_&)
BOOST_SP_NOEXCEPT BOOST_OVERRIDE {
return 0;
}
virtual void* get_untyped_deleter() BOOST_SP_NOEXCEPT {
void* get_untyped_deleter() BOOST_SP_NOEXCEPT BOOST_OVERRIDE {
return 0;
}
@ -423,11 +239,11 @@ public:
}
}
T* get() const {
T* get() const BOOST_SP_NOEXCEPT {
return result_;
}
void release() {
void release() BOOST_SP_NOEXCEPT {
result_ = 0;
}
@ -445,40 +261,37 @@ template<class T, class A>
inline typename enable_if_<is_unbounded_array<T>::value, shared_ptr<T> >::type
allocate_shared(const A& allocator, std::size_t count)
{
typedef typename remove_extent<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, scalar>::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 enable_if_<is_bounded_array<T>::value, shared_ptr<T> >::type
allocate_shared(const A& allocator)
{
typedef typename remove_extent<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
enum {
size = detail::sp_array_count<T, scalar>::value
count = extent<T>::value
};
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, 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>
@ -486,23 +299,17 @@ inline typename enable_if_<is_unbounded_array<T>::value, shared_ptr<T> >::type
allocate_shared(const A& allocator, std::size_t count,
const typename remove_extent<T>::type& value)
{
typedef typename remove_extent<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;
enum {
total = detail::sp_array_count<type, scalar>::value
};
std::size_t size = count * total;
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), total, 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>
@ -510,65 +317,34 @@ inline typename enable_if_<is_bounded_array<T>::value, shared_ptr<T> >::type
allocate_shared(const A& allocator,
const typename remove_extent<T>::type& value)
{
typedef typename remove_extent<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
enum {
size = detail::sp_array_count<T, scalar>::value
count = extent<T>::value
};
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, 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, scalar>::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 enable_if_<is_unbounded_array<T>::value, shared_ptr<T> >::type
allocate_shared_noinit(const A& allocator, std::size_t count)
{
typedef typename remove_extent<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, scalar>::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 enable_if_<is_bounded_array<T>::value, shared_ptr<T> >::type
allocate_shared_noinit(const A& allocator)
{
typedef typename remove_extent<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
enum {
size = detail::sp_array_count<T, scalar>::value
};
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,482 @@
/*
Copyright 2019 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/smart_ptr/detail/sp_noexcept.hpp>
#include <boost/smart_ptr/detail/sp_nullptr_t.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/type_traits/enable_if.hpp>
#include <boost/type_traits/extent.hpp>
#include <boost/type_traits/is_array.hpp>
#include <boost/type_traits/is_bounded_array.hpp>
#include <boost/type_traits/is_unbounded_array.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/remove_extent.hpp>
#include <boost/type_traits/type_identity.hpp>
#include <boost/config.hpp>
#include <memory>
#include <utility>
namespace boost {
namespace detail {
template<class T>
struct sp_alloc_size {
BOOST_STATIC_CONSTEXPR std::size_t value = 1;
};
template<class T>
struct sp_alloc_size<T[]> {
BOOST_STATIC_CONSTEXPR std::size_t value = sp_alloc_size<T>::value;
};
template<class T, std::size_t N>
struct sp_alloc_size<T[N]> {
BOOST_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 boost::remove_cv<typename
boost::remove_extent<T>::type>::type type;
};
template<class T, class P>
class sp_alloc_ptr {
public:
typedef T element_type;
sp_alloc_ptr() BOOST_SP_NOEXCEPT
: p_() { }
#if defined(BOOST_MSVC) && BOOST_MSVC == 1600
sp_alloc_ptr(T* p) BOOST_SP_NOEXCEPT
: p_(const_cast<typename boost::remove_cv<T>::type*>(p)) { }
#endif
sp_alloc_ptr(std::size_t, P p) BOOST_SP_NOEXCEPT
: p_(p) { }
#if !defined(BOOST_NO_CXX11_NULLPTR)
sp_alloc_ptr(detail::sp_nullptr_t) BOOST_SP_NOEXCEPT
: p_() { }
#endif
T& operator*() const {
return *p_;
}
T* operator->() const BOOST_SP_NOEXCEPT {
return boost::to_address(p_);
}
#if !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
explicit operator bool() const BOOST_SP_NOEXCEPT {
return !!p_;
}
#endif
bool operator!() const BOOST_SP_NOEXCEPT {
return !p_;
}
P ptr() const BOOST_SP_NOEXCEPT {
return p_;
}
BOOST_STATIC_CONSTEXPR std::size_t size() BOOST_SP_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
boost::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() BOOST_SP_NOEXCEPT
: p_() { }
sp_alloc_ptr(std::size_t n, P p) BOOST_SP_NOEXCEPT
: p_(p)
, n_(n) { }
#if !defined(BOOST_NO_CXX11_NULLPTR)
sp_alloc_ptr(detail::sp_nullptr_t) BOOST_SP_NOEXCEPT
: p_() { }
#endif
T& operator[](std::size_t i) const {
return p_[i];
}
#if !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
explicit operator bool() const BOOST_SP_NOEXCEPT {
return !!p_;
}
#endif
bool operator!() const BOOST_SP_NOEXCEPT {
return !p_;
}
P ptr() const BOOST_SP_NOEXCEPT {
return p_;
}
std::size_t size() const BOOST_SP_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
boost::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() BOOST_SP_NOEXCEPT
: p_() { }
sp_alloc_ptr(std::size_t, P p) BOOST_SP_NOEXCEPT
: p_(p) { }
#if !defined(BOOST_NO_CXX11_NULLPTR)
sp_alloc_ptr(detail::sp_nullptr_t) BOOST_SP_NOEXCEPT
: p_() { }
#endif
T& operator[](std::size_t i) const {
return p_[i];
}
#if !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
explicit operator bool() const BOOST_SP_NOEXCEPT {
return !!p_;
}
#endif
bool operator!() const BOOST_SP_NOEXCEPT {
return !p_;
}
P ptr() const BOOST_SP_NOEXCEPT {
return p_;
}
BOOST_STATIC_CONSTEXPR std::size_t size() BOOST_SP_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
boost::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);
}
#if !defined(BOOST_NO_CXX11_NULLPTR)
template<class T, class P>
inline bool
operator==(const sp_alloc_ptr<T, P>& lhs,
detail::sp_nullptr_t) BOOST_SP_NOEXCEPT
{
return !lhs.ptr();
}
template<class T, class P>
inline bool
operator==(detail::sp_nullptr_t,
const sp_alloc_ptr<T, P>& rhs) BOOST_SP_NOEXCEPT
{
return !rhs.ptr();
}
template<class T, class P>
inline bool
operator!=(const sp_alloc_ptr<T, P>& lhs,
detail::sp_nullptr_t) BOOST_SP_NOEXCEPT
{
return !!lhs.ptr();
}
template<class T, class P>
inline bool
operator!=(detail::sp_nullptr_t,
const sp_alloc_ptr<T, P>& rhs) BOOST_SP_NOEXCEPT
{
return !!rhs.ptr();
}
#endif
template<class A>
inline void
sp_alloc_clear(A& a, typename boost::allocator_pointer<A>::type p, std::size_t,
boost::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, boost::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) BOOST_SP_NOEXCEPT
: base(empty_init_t(), a) { }
void operator()(pointer p) {
detail::sp_alloc_clear(base::get(), p.ptr(), p.size(), is_array<T>());
base::get().deallocate(p.ptr(), p.size());
}
};
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
template<class T, class A>
using alloc_noinit_deleter = alloc_deleter<T, noinit_adaptor<A> >;
#endif
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 BOOST_SP_NOEXCEPT {
return boost::to_address(p_);
}
allocator& state() BOOST_SP_NOEXCEPT {
return a_;
}
type release() BOOST_SP_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 enable_if_<!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();
}
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<class T, class A, class... Args>
inline typename enable_if_<!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();
}
#endif
template<class T, class A>
inline typename enable_if_<!is_array<T>::value,
std::unique_ptr<T, alloc_deleter<T, A> > >::type
allocate_unique(const A& alloc, typename 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 enable_if_<!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 enable_if_<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 enable_if_<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, 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 enable_if_<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 enable_if_<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 enable_if_<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 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 remove_extent<T>::type>::value);
return c.release();
}
template<class T, class A>
inline typename enable_if_<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 remove_extent<T>::type& value)
{
detail::sp_alloc_make<T, A> c(alloc, 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 remove_extent<T>::type>::value);
return c.release();
}
} /* boost */
#endif

View File

@ -63,6 +63,11 @@ public:
{
}
atomic_shared_ptr( shared_ptr<T> p ) BOOST_SP_NOEXCEPT
: p_( std::move( p ) ), l_ BOOST_DETAIL_SPINLOCK_INIT
{
}
#else
atomic_shared_ptr() BOOST_SP_NOEXCEPT
@ -71,8 +76,6 @@ public:
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 ) )
@ -84,6 +87,8 @@ public:
std::memcpy( &l_, &init, sizeof( init ) );
}
#endif
atomic_shared_ptr& operator=( shared_ptr<T> r ) BOOST_SP_NOEXCEPT
{
boost::detail::spinlock::scoped_lock lock( l_ );

View File

@ -20,7 +20,7 @@
#include <boost/config.hpp>
#include <exception>
#ifdef __BORLANDC__
#ifdef BOOST_BORLANDC
# pragma warn -8026 // Functions with excep. spec. are not expanded inline
#endif
@ -33,7 +33,7 @@ namespace boost
// is compiled with -ps, the compiler issues an error.
// Hence, the temporary #pragma option -pc below.
#if defined(__BORLANDC__) && __BORLANDC__ <= 0x564
#if defined(BOOST_BORLANDC) && BOOST_BORLANDC <= 0x564
# pragma option push -pc
#endif
@ -47,7 +47,7 @@ class bad_weak_ptr: public std::exception
{
public:
virtual char const * what() const BOOST_NOEXCEPT_OR_NOTHROW
char const * what() const BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE
{
return "tr1::bad_weak_ptr";
}
@ -57,13 +57,13 @@ public:
# pragma clang diagnostic pop
#endif
#if defined(__BORLANDC__) && __BORLANDC__ <= 0x564
#if defined(BOOST_BORLANDC) && BOOST_BORLANDC <= 0x564
# pragma option pop
#endif
} // namespace boost
#ifdef __BORLANDC__
#ifdef BOOST_BORLANDC
# pragma warn .8026 // Functions with excep. spec. are not expanded inline
#endif

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

@ -13,6 +13,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 g++/x86 atomic_count")
#endif
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

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

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

@ -19,6 +19,13 @@
# 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
{

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

@ -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,188 @@
#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" 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( lw_thread_t & th, 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 = 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

@ -113,12 +113,12 @@ public:
#endif
virtual void local_cb_destroy() BOOST_SP_NOEXCEPT
void local_cb_destroy() BOOST_SP_NOEXCEPT BOOST_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 BOOST_SP_NOEXCEPT BOOST_OVERRIDE
{
return pn_;
}
@ -130,12 +130,12 @@ public:
shared_count pn_;
virtual void local_cb_destroy() BOOST_SP_NOEXCEPT
void local_cb_destroy() BOOST_SP_NOEXCEPT BOOST_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 BOOST_SP_NOEXCEPT BOOST_OVERRIDE
{
return pn_;
}

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,11 +49,7 @@ 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 *);
@ -67,11 +60,7 @@ typedef ::_RTL_CRITICAL_SECTION rtl_critical_section;
typedef ::CRITICAL_SECTION critical_section;
#if BOOST_PLAT_WINDOWS_RUNTIME
using ::InitializeCriticalSectionEx;
#else
using ::InitializeCriticalSection;
#endif
using ::EnterCriticalSection;
using ::LeaveCriticalSection;
using ::DeleteCriticalSection;
@ -93,11 +82,7 @@ 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
}
~lightweight_mutex()

View File

@ -18,32 +18,29 @@
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifdef __BORLANDC__
#if defined(__BORLANDC__) && !defined(__clang__)
# 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/smart_ptr/detail/sp_noexcept.hpp>
#include <boost/checked_delete.hpp>
#include <boost/throw_exception.hpp>
#include <boost/core/addressof.hpp>
#include <boost/config.hpp>
#include <boost/config/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/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"
@ -103,6 +100,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 ) BOOST_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
@ -489,22 +494,26 @@ public:
return pi_ == 0;
}
friend inline bool operator==(shared_count const & a, shared_count const & b) BOOST_SP_NOEXCEPT
bool operator==( shared_count const & r ) const BOOST_SP_NOEXCEPT
{
return a.pi_ == b.pi_;
return pi_ == r.pi_;
}
friend inline bool operator<(shared_count const & a, shared_count const & b) BOOST_SP_NOEXCEPT
bool operator==( weak_count const & r ) const BOOST_SP_NOEXCEPT;
bool operator<( shared_count const & r ) const BOOST_SP_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 BOOST_SP_NOEXCEPT
bool operator<( weak_count const & r ) const BOOST_SP_NOEXCEPT;
void * get_deleter( sp_typeinfo_ const & ti ) const BOOST_SP_NOEXCEPT
{
return pi_? pi_->get_deleter( ti ): 0;
}
void * get_local_deleter( sp_typeinfo const & ti ) const BOOST_SP_NOEXCEPT
void * get_local_deleter( sp_typeinfo_ const & ti ) const BOOST_SP_NOEXCEPT
{
return pi_? pi_->get_local_deleter( ti ): 0;
}
@ -513,6 +522,11 @@ public:
{
return pi_? pi_->get_untyped_deleter(): 0;
}
std::size_t hash_value() const BOOST_SP_NOEXCEPT
{
return sp_hash_pointer( pi_ );
}
};
@ -620,14 +634,29 @@ public:
return pi_ == 0;
}
friend inline bool operator==(weak_count const & a, weak_count const & b) BOOST_SP_NOEXCEPT
bool operator==( weak_count const & r ) const BOOST_SP_NOEXCEPT
{
return a.pi_ == b.pi_;
return pi_ == r.pi_;
}
friend inline bool operator<(weak_count const & a, weak_count const & b) BOOST_SP_NOEXCEPT
bool operator==( shared_count const & r ) const BOOST_SP_NOEXCEPT
{
return std::less<sp_counted_base *>()(a.pi_, b.pi_);
return pi_ == r.pi_;
}
bool operator<( weak_count const & r ) const BOOST_SP_NOEXCEPT
{
return std::less<sp_counted_base *>()( pi_, r.pi_ );
}
bool operator<( shared_count const & r ) const BOOST_SP_NOEXCEPT
{
return std::less<sp_counted_base *>()( pi_, r.pi_ );
}
std::size_t hash_value() const BOOST_SP_NOEXCEPT
{
return sp_hash_pointer( pi_ );
}
};
@ -653,6 +682,16 @@ inline shared_count::shared_count( weak_count const & r, sp_nothrow_tag ) BOOST_
}
}
inline bool shared_count::operator==( weak_count const & r ) const BOOST_SP_NOEXCEPT
{
return pi_ == r.pi_;
}
inline bool shared_count::operator<( weak_count const & r ) const BOOST_SP_NOEXCEPT
{
return std::less<sp_counted_base *>()( pi_, r.pi_ );
}
} // namespace detail
} // namespace boost
@ -661,7 +700,7 @@ inline shared_count::shared_count( weak_count const & r, sp_nothrow_tag ) BOOST_
#pragma GCC diagnostic pop
#endif
#ifdef __BORLANDC__
#if defined(__BORLANDC__) && !defined(__clang__)
# pragma warn .8027 // Functions containing try are not expanded inline
#endif

View File

@ -26,7 +26,7 @@
# define BOOST_SP_NO_SP_CONVERTIBLE
#endif
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( __BORLANDC__ ) && ( __BORLANDC__ < 0x630 )
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( BOOST_BORLANDC ) && ( BOOST_BORLANDC < 0x630 )
# define BOOST_SP_NO_SP_CONVERTIBLE
#endif

View File

@ -15,10 +15,17 @@
// Lock-free algorithm by Alexander Terekhov
//
#include <boost/detail/sp_typeinfo.hpp>
#include <boost/smart_ptr/detail/sp_typeinfo_.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
namespace boost
{
@ -104,8 +111,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,11 +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
{
@ -96,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

@ -15,17 +15,34 @@
// 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/smart_ptr/detail/sp_noexcept.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 Clang/C11 sp_counted_base")
#endif
namespace boost
{
namespace detail
{
#if defined(__clang__)
# pragma clang diagnostic push
#endif
#if defined(__clang__) && defined(__has_warning)
# if __has_warning( "-Wc11-extensions" )
# pragma clang diagnostic ignored "-Wc11-extensions"
# endif
#endif
typedef _Atomic( boost::int_least32_t ) atomic_int_least32_t;
inline void atomic_increment( atomic_int_least32_t * pw ) BOOST_SP_NOEXCEPT
@ -61,7 +78,6 @@ inline boost::int_least32_t atomic_conditional_increment( atomic_int_least32_t *
}
#if defined(__clang__)
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wweak-vtables"
#endif
@ -99,8 +115,8 @@ public:
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) BOOST_SP_NOEXCEPT = 0;
virtual void * get_local_deleter( sp_typeinfo const & ti ) BOOST_SP_NOEXCEPT = 0;
virtual void * get_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT = 0;
virtual void * get_local_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT = 0;
virtual void * get_untyped_deleter() BOOST_SP_NOEXCEPT = 0;
void add_ref_copy() BOOST_SP_NOEXCEPT

View File

@ -24,9 +24,16 @@
// formulation
//
#include <boost/detail/sp_typeinfo.hpp>
#include <boost/smart_ptr/detail/sp_typeinfo_.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
{
@ -124,8 +131,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,9 +25,16 @@
// formulation
//
#include <boost/detail/sp_typeinfo.hpp>
#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/config.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using CodeWarrior/x86 sp_counted_base")
#endif
namespace boost
{
@ -112,8 +119,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

@ -16,9 +16,16 @@
// Lock-free algorithm by Alexander Terekhov
//
#include <boost/detail/sp_typeinfo.hpp>
#include <boost/smart_ptr/detail/sp_typeinfo_.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
namespace boost
{
@ -111,8 +118,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,9 +20,16 @@
// Lock-free algorithm by Alexander Terekhov
//
#include <boost/detail/sp_typeinfo.hpp>
#include <boost/smart_ptr/detail/sp_typeinfo_.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
namespace boost
{
@ -141,8 +148,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,9 +24,16 @@
// formulation
//
#include <boost/detail/sp_typeinfo.hpp>
#include <boost/smart_ptr/detail/sp_typeinfo_.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
namespace boost
{
@ -135,8 +142,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,10 +19,17 @@
//
// Thanks to Michael van der Westhuizen
#include <boost/detail/sp_typeinfo.hpp>
#include <boost/smart_ptr/detail/sp_typeinfo_.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
namespace boost
{
@ -120,8 +127,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,9 +24,16 @@
// formulation
//
#include <boost/detail/sp_typeinfo.hpp>
#include <boost/smart_ptr/detail/sp_typeinfo_.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
namespace boost
{
@ -127,8 +134,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,11 +18,18 @@
// 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/sp_noexcept.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
{
@ -61,8 +68,8 @@ public:
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) BOOST_SP_NOEXCEPT = 0;
virtual void * get_local_deleter( sp_typeinfo const & ti ) BOOST_SP_NOEXCEPT = 0;
virtual void * get_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT = 0;
virtual void * get_local_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT = 0;
virtual void * get_untyped_deleter() BOOST_SP_NOEXCEPT = 0;
void add_ref_copy() BOOST_SP_NOEXCEPT

View File

@ -18,12 +18,19 @@
// 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
{
@ -72,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()

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,10 +19,17 @@
//
// Thanks to Michael van der Westhuizen
#include <boost/detail/sp_typeinfo.hpp>
#include <boost/smart_ptr/detail/sp_typeinfo_.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
namespace boost
{
@ -115,8 +122,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,17 @@
// formulation
//
#include <boost/detail/sp_typeinfo.hpp>
#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/config.hpp>
#include <atomic.h>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using Solaris sp_counted_base")
#endif
namespace boost
{
@ -62,8 +69,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,10 +18,17 @@
// 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
{
@ -84,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,12 +15,19 @@
// 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/smart_ptr/detail/sp_noexcept.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
{
@ -91,8 +98,8 @@ public:
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) BOOST_SP_NOEXCEPT = 0;
virtual void * get_local_deleter( sp_typeinfo const & ti ) BOOST_SP_NOEXCEPT = 0;
virtual void * get_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT = 0;
virtual void * get_local_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT = 0;
virtual void * get_untyped_deleter() BOOST_SP_NOEXCEPT = 0;
void add_ref_copy() BOOST_SP_NOEXCEPT

View File

@ -15,7 +15,7 @@
// 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>
@ -23,6 +23,13 @@
# 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
{
@ -109,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,9 +21,16 @@
// formulation
//
#include <boost/detail/sp_typeinfo.hpp>
#include <boost/smart_ptr/detail/sp_typeinfo_.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
extern "builtin" void __lwsync(void);
extern "builtin" void __isync(void);
extern "builtin" int __fetch_and_add(volatile int* addr, int val);
@ -104,8 +111,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,10 +25,17 @@
//
#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
{
@ -67,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()

View File

@ -18,25 +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/sp_noexcept.hpp>
#include <boost/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
@ -85,7 +81,7 @@ public:
#endif
}
virtual void dispose() BOOST_SP_NOEXCEPT
void dispose() BOOST_SP_NOEXCEPT BOOST_OVERRIDE
{
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
boost::sp_scalar_destructor_hook( px_, sizeof(X), this );
@ -93,17 +89,17 @@ public:
boost::checked_delete( px_ );
}
virtual void * get_deleter( sp_typeinfo const & ) BOOST_SP_NOEXCEPT
void * get_deleter( sp_typeinfo_ const & ) BOOST_SP_NOEXCEPT BOOST_OVERRIDE
{
return 0;
}
virtual void * get_local_deleter( sp_typeinfo const & ) BOOST_SP_NOEXCEPT
void * get_local_deleter( sp_typeinfo_ const & ) BOOST_SP_NOEXCEPT BOOST_OVERRIDE
{
return 0;
}
virtual void * get_untyped_deleter() BOOST_SP_NOEXCEPT
void * get_untyped_deleter() BOOST_SP_NOEXCEPT BOOST_OVERRIDE
{
return 0;
}
@ -168,22 +164,22 @@ public:
{
}
virtual void dispose() BOOST_SP_NOEXCEPT
void dispose() BOOST_SP_NOEXCEPT BOOST_OVERRIDE
{
del( ptr );
}
virtual void * get_deleter( sp_typeinfo const & ti ) BOOST_SP_NOEXCEPT
void * get_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT BOOST_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 ) BOOST_SP_NOEXCEPT
void * get_local_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT BOOST_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() BOOST_SP_NOEXCEPT
void * get_untyped_deleter() BOOST_SP_NOEXCEPT BOOST_OVERRIDE
{
return &reinterpret_cast<char&>( del );
}
@ -242,12 +238,12 @@ public:
{
}
virtual void dispose() BOOST_SP_NOEXCEPT
void dispose() BOOST_SP_NOEXCEPT BOOST_OVERRIDE
{
d_( p_ );
}
virtual void destroy() BOOST_SP_NOEXCEPT
void destroy() BOOST_SP_NOEXCEPT BOOST_OVERRIDE
{
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
@ -266,17 +262,17 @@ public:
a2.deallocate( this, 1 );
}
virtual void * get_deleter( sp_typeinfo const & ti ) BOOST_SP_NOEXCEPT
void * get_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT BOOST_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 ) BOOST_SP_NOEXCEPT
void * get_local_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT BOOST_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() BOOST_SP_NOEXCEPT
void * get_untyped_deleter() BOOST_SP_NOEXCEPT BOOST_OVERRIDE
{
return &reinterpret_cast<char&>( d_ );
}

View File

@ -0,0 +1,58 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_TYPEINFO_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_TYPEINFO_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
// smart_ptr/detail/sp_typeinfo_.hpp
//
// Copyright 2007, 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)
#include <boost/config.hpp>
#if defined( BOOST_NO_TYPEID ) || defined( BOOST_NO_STD_TYPEINFO )
#include <boost/core/typeinfo.hpp>
namespace boost
{
namespace detail
{
typedef boost::core::typeinfo sp_typeinfo_;
} // namespace detail
} // namespace boost
#define BOOST_SP_TYPEID_(T) BOOST_CORE_TYPEID(T)
#else // defined( BOOST_NO_TYPEID ) || defined( BOOST_NO_STD_TYPEINFO )
#include <typeinfo>
namespace boost
{
namespace detail
{
typedef std::type_info sp_typeinfo_;
} // namespace detail
} // namespace boost
#define BOOST_SP_TYPEID_(T) typeid(T)
#endif // defined( BOOST_NO_TYPEID ) || defined( BOOST_NO_STD_TYPEINFO )
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_TYPEINFO_HPP_INCLUDED

View File

@ -11,6 +11,13 @@
#include <boost/smart_ptr/detail/yield_k.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using g++/ARM spinlock")
#endif
#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_7S__)
# define BOOST_SP_ARM_BARRIER "dmb"

View File

@ -17,6 +17,13 @@
#include <boost/assert.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using single-threaded spinlock emulation")
#endif
namespace boost
{

View File

@ -17,6 +17,13 @@
#include <pthread.h>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using pthread_mutex spinlock emulation")
#endif
namespace boost
{

View File

@ -19,6 +19,13 @@
#include <boost/config.hpp>
#include <atomic>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using std::atomic spinlock")
#endif
namespace boost
{

View File

@ -21,6 +21,13 @@
# include <ia64intrin.h>
#endif
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using __sync spinlock")
#endif
namespace boost
{

View File

@ -18,6 +18,13 @@
#include <boost/smart_ptr/detail/sp_interlocked.hpp>
#include <boost/smart_ptr/detail/yield_k.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using Win32 spinlock")
#endif
// BOOST_COMPILER_FENCE
#if defined(__INTEL_COMPILER)

View File

@ -11,7 +11,6 @@
// yield_k.hpp
//
// Copyright (c) 2008 Peter Dimov
// Copyright (c) Microsoft Corporation 2014
//
// void yield( unsigned k );
//
@ -25,11 +24,6 @@
//
#include <boost/config.hpp>
#include <boost/predef/platform/windows_runtime.h>
#if BOOST_PLAT_WINDOWS_RUNTIME
#include <thread>
#endif
// BOOST_SMT_PAUSE
@ -59,7 +53,7 @@ namespace boost
namespace detail
{
#if !defined( BOOST_USE_WINDOWS_H ) && !BOOST_PLAT_WINDOWS_RUNTIME
#if !defined( BOOST_USE_WINDOWS_H )
#if defined(__clang__) && defined(__x86_64__)
// clang x64 warns that __stdcall is ignored
@ -76,7 +70,7 @@ namespace detail
#undef BOOST_SP_STDCALL
#endif // !defined( BOOST_USE_WINDOWS_H ) && !BOOST_PLAT_WINDOWS_RUNTIME
#endif // !defined( BOOST_USE_WINDOWS_H )
inline void yield( unsigned k ) BOOST_NOEXCEPT
{
@ -89,7 +83,6 @@ inline void yield( unsigned k ) BOOST_NOEXCEPT
BOOST_SMT_PAUSE
}
#endif
#if !BOOST_PLAT_WINDOWS_RUNTIME
else if( k < 32 )
{
Sleep( 0 );
@ -98,13 +91,6 @@ inline void yield( unsigned k ) BOOST_NOEXCEPT
{
Sleep( 1 );
}
#else
else
{
// Sleep isn't supported on the Windows Runtime.
std::this_thread::yield();
}
#endif
}
} // namespace detail

View File

@ -0,0 +1,41 @@
#ifndef BOOST_SMART_PTR_ENABLE_SHARED_FROM_HPP_INCLUDED
#define BOOST_SMART_PTR_ENABLE_SHARED_FROM_HPP_INCLUDED
// enable_shared_from.hpp
//
// Copyright 2019, 2020 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
// See http://www.boost.org/libs/smart_ptr/ for documentation.
#include <boost/smart_ptr/enable_shared_from_this.hpp>
#include <boost/smart_ptr/detail/sp_noexcept.hpp>
namespace boost
{
class enable_shared_from: public enable_shared_from_this<enable_shared_from>
{
private:
using enable_shared_from_this<enable_shared_from>::shared_from_this;
using enable_shared_from_this<enable_shared_from>::weak_from_this;
};
template<class T> shared_ptr<T> shared_from( T * p )
{
return shared_ptr<T>( p->enable_shared_from_this<enable_shared_from>::shared_from_this(), p );
}
template<class T> weak_ptr<T> weak_from( T * p ) BOOST_SP_NOEXCEPT
{
return weak_ptr<T>( p->enable_shared_from_this<enable_shared_from>::weak_from_this(), p );
}
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_ENABLE_SHARED_FROM_HPP_INCLUDED

View File

@ -16,7 +16,7 @@
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/assert.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/config/workaround.hpp>
namespace boost
{
@ -144,8 +144,7 @@ template<typename T>
boost::weak_ptr<T> weak_from_raw(T *p)
{
BOOST_ASSERT(p != 0);
boost::weak_ptr<T> result;
result._internal_aliasing_assign(p->enable_shared_from_raw::weak_from_this(), p);
boost::weak_ptr<T> result(p->enable_shared_from_raw::weak_from_this(), p);
return result;
}

View File

@ -16,7 +16,7 @@
#include <boost/config.hpp>
#include <boost/assert.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/config/workaround.hpp>
#include <boost/smart_ptr/detail/sp_convertible.hpp>
#include <boost/smart_ptr/detail/sp_nullptr_t.hpp>
#include <boost/smart_ptr/detail/sp_noexcept.hpp>
@ -297,6 +297,8 @@ template<class T> T * get_pointer(intrusive_ptr<T> const & p) BOOST_SP_NOEXCEPT
return p.get();
}
// pointer casts
template<class T, class U> intrusive_ptr<T> static_pointer_cast(intrusive_ptr<U> const & p)
{
return static_cast<T *>(p.get());
@ -312,6 +314,31 @@ template<class T, class U> intrusive_ptr<T> dynamic_pointer_cast(intrusive_ptr<U
return dynamic_cast<T *>(p.get());
}
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
template<class T, class U> intrusive_ptr<T> static_pointer_cast( intrusive_ptr<U> && p ) BOOST_SP_NOEXCEPT
{
return intrusive_ptr<T>( static_cast<T*>( p.detach() ), false );
}
template<class T, class U> intrusive_ptr<T> const_pointer_cast( intrusive_ptr<U> && p ) BOOST_SP_NOEXCEPT
{
return intrusive_ptr<T>( const_cast<T*>( p.detach() ), false );
}
template<class T, class U> intrusive_ptr<T> dynamic_pointer_cast( intrusive_ptr<U> && p ) BOOST_SP_NOEXCEPT
{
T * p2 = dynamic_cast<T*>( p.get() );
intrusive_ptr<T> r( p2, false );
if( p2 ) p.detach();
return r;
}
#endif // defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
// operator<<
#if !defined(BOOST_NO_IOSTREAM)
@ -358,4 +385,23 @@ template< class T > std::size_t hash_value( boost::intrusive_ptr<T> const & p )
} // namespace boost
// std::hash
#if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
namespace std
{
template<class T> struct hash< ::boost::intrusive_ptr<T> >
{
std::size_t operator()( ::boost::intrusive_ptr<T> const & p ) const BOOST_SP_NOEXCEPT
{
return std::hash< T* >()( p.get() );
}
};
} // namespace std
#endif // #if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
#endif // #ifndef BOOST_SMART_PTR_INTRUSIVE_PTR_HPP_INCLUDED

View File

@ -494,6 +494,13 @@ public:
{
return std::less< boost::detail::local_counted_base* >()( pn, r.pn );
}
// owner_equals
template<class Y> bool owner_equals( local_shared_ptr<Y> const & r ) const BOOST_SP_NOEXCEPT
{
return pn == r.pn;
}
};
template<class T, class U> inline bool operator==( local_shared_ptr<T> const & a, local_shared_ptr<U> const & b ) BOOST_SP_NOEXCEPT
@ -681,4 +688,23 @@ template< class T > std::size_t hash_value( local_shared_ptr<T> const & p ) BOOS
} // namespace boost
// std::hash
#if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
namespace std
{
template<class T> struct hash< ::boost::local_shared_ptr<T> >
{
std::size_t operator()( ::boost::local_shared_ptr<T> const & p ) const BOOST_SP_NOEXCEPT
{
return std::hash< typename ::boost::local_shared_ptr<T>::element_type* >()( p.get() );
}
};
} // namespace std
#endif // #if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
#endif // #ifndef BOOST_SMART_PTR_LOCAL_SHARED_PTR_HPP_INCLUDED

View File

@ -9,6 +9,7 @@ Distributed under the Boost Software License, Version 1.0.
#ifndef BOOST_SMART_PTR_MAKE_LOCAL_SHARED_ARRAY_HPP
#define BOOST_SMART_PTR_MAKE_LOCAL_SHARED_ARRAY_HPP
#include <boost/core/default_allocator.hpp>
#include <boost/smart_ptr/allocate_local_shared_array.hpp>
namespace boost {
@ -18,8 +19,8 @@ inline typename enable_if_<is_bounded_array<T>::value,
local_shared_ptr<T> >::type
make_local_shared()
{
return boost::allocate_local_shared<T>(std::allocator<typename
detail::sp_array_scalar<T>::type>());
return boost::allocate_local_shared<T>(boost::default_allocator<typename
detail::sp_array_element<T>::type>());
}
template<class T>
@ -27,8 +28,8 @@ inline typename enable_if_<is_bounded_array<T>::value,
local_shared_ptr<T> >::type
make_local_shared(const typename remove_extent<T>::type& value)
{
return boost::allocate_local_shared<T>(std::allocator<typename
detail::sp_array_scalar<T>::type>(), value);
return boost::allocate_local_shared<T>(boost::default_allocator<typename
detail::sp_array_element<T>::type>(), value);
}
template<class T>
@ -36,8 +37,8 @@ inline typename enable_if_<is_unbounded_array<T>::value,
local_shared_ptr<T> >::type
make_local_shared(std::size_t size)
{
return boost::allocate_local_shared<T>(std::allocator<typename
detail::sp_array_scalar<T>::type>(), size);
return boost::allocate_local_shared<T>(boost::default_allocator<typename
detail::sp_array_element<T>::type>(), size);
}
template<class T>
@ -46,8 +47,8 @@ inline typename enable_if_<is_unbounded_array<T>::value,
make_local_shared(std::size_t size,
const typename remove_extent<T>::type& value)
{
return boost::allocate_local_shared<T>(std::allocator<typename
detail::sp_array_scalar<T>::type>(), size, value);
return boost::allocate_local_shared<T>(boost::default_allocator<typename
detail::sp_array_element<T>::type>(), size, value);
}
template<class T>
@ -55,8 +56,8 @@ inline typename enable_if_<is_bounded_array<T>::value,
local_shared_ptr<T> >::type
make_local_shared_noinit()
{
return boost::allocate_local_shared_noinit<T>(std::allocator<typename
detail::sp_array_scalar<T>::type>());
return boost::allocate_local_shared_noinit<T>(boost::
default_allocator<typename detail::sp_array_element<T>::type>());
}
template<class T>
@ -64,8 +65,8 @@ inline typename enable_if_<is_unbounded_array<T>::value,
local_shared_ptr<T> >::type
make_local_shared_noinit(std::size_t size)
{
return boost::allocate_local_shared_noinit<T>(std::allocator<typename
detail::sp_array_scalar<T>::type>(), size);
return boost::allocate_local_shared_noinit<T>(boost::
default_allocator<typename detail::sp_array_element<T>::type>(), size);
}
} /* boost */

View File

@ -8,6 +8,7 @@ Distributed under the Boost Software License, Version 1.0.
#ifndef BOOST_SMART_PTR_MAKE_SHARED_ARRAY_HPP
#define BOOST_SMART_PTR_MAKE_SHARED_ARRAY_HPP
#include <boost/core/default_allocator.hpp>
#include <boost/smart_ptr/allocate_shared_array.hpp>
namespace boost {
@ -16,48 +17,48 @@ template<class T>
inline typename enable_if_<is_bounded_array<T>::value, shared_ptr<T> >::type
make_shared()
{
return boost::allocate_shared<T>(std::allocator<typename
detail::sp_array_scalar<T>::type>());
return boost::allocate_shared<T>(boost::default_allocator<typename
detail::sp_array_element<T>::type>());
}
template<class T>
inline typename enable_if_<is_bounded_array<T>::value, shared_ptr<T> >::type
make_shared(const typename remove_extent<T>::type& value)
{
return boost::allocate_shared<T>(std::allocator<typename
detail::sp_array_scalar<T>::type>(), value);
return boost::allocate_shared<T>(boost::default_allocator<typename
detail::sp_array_element<T>::type>(), value);
}
template<class T>
inline typename enable_if_<is_unbounded_array<T>::value, shared_ptr<T> >::type
make_shared(std::size_t size)
{
return boost::allocate_shared<T>(std::allocator<typename
detail::sp_array_scalar<T>::type>(), size);
return boost::allocate_shared<T>(boost::default_allocator<typename
detail::sp_array_element<T>::type>(), size);
}
template<class T>
inline typename enable_if_<is_unbounded_array<T>::value, shared_ptr<T> >::type
make_shared(std::size_t size, const typename remove_extent<T>::type& value)
{
return boost::allocate_shared<T>(std::allocator<typename
detail::sp_array_scalar<T>::type>(), size, value);
return boost::allocate_shared<T>(boost::default_allocator<typename
detail::sp_array_element<T>::type>(), size, value);
}
template<class T>
inline typename enable_if_<is_bounded_array<T>::value, shared_ptr<T> >::type
make_shared_noinit()
{
return boost::allocate_shared_noinit<T>(std::allocator<typename
detail::sp_array_scalar<T>::type>());
return boost::allocate_shared_noinit<T>(boost::default_allocator<typename
detail::sp_array_element<T>::type>());
}
template<class T>
inline typename enable_if_<is_unbounded_array<T>::value, shared_ptr<T> >::type
make_shared_noinit(std::size_t size)
{
return boost::allocate_shared_noinit<T>(std::allocator<typename
detail::sp_array_scalar<T>::type>(), size);
return boost::allocate_shared_noinit<T>(boost::default_allocator<typename
detail::sp_array_element<T>::type>(), size);
}
} /* boost */

View File

@ -187,7 +187,7 @@ template< class T > struct sp_if_not_array< T[] >
{
};
#if !defined( __BORLANDC__ ) || !BOOST_WORKAROUND( __BORLANDC__, < 0x600 )
#if !defined( BOOST_BORLANDC ) || !BOOST_WORKAROUND( BOOST_BORLANDC, < 0x600 )
template< class T, std::size_t N > struct sp_if_not_array< T[N] >
{

View File

@ -0,0 +1,27 @@
#ifndef BOOST_SMART_PTR_OWNER_EQUAL_TO_HPP_INCLUDED
#define BOOST_SMART_PTR_OWNER_EQUAL_TO_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/config.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 BOOST_NOEXCEPT
{
return u.owner_equals( v );
}
};
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_OWNER_EQUAL_TO_HPP_INCLUDED

View File

@ -14,6 +14,8 @@
// See http://www.boost.org/libs/smart_ptr/ for documentation.
//
#include <boost/config.hpp>
namespace boost
{
@ -23,7 +25,7 @@ template<class T = void> struct owner_less
typedef T first_argument_type;
typedef T second_argument_type;
template<class U, class V> bool operator()( U const & u, V const & v ) const
template<class U, class V> bool operator()( U const & u, V const & v ) const BOOST_NOEXCEPT
{
return u.owner_before( v );
}

View File

@ -16,7 +16,7 @@
#include <boost/smart_ptr/detail/sp_nullptr_t.hpp>
#include <boost/smart_ptr/detail/sp_noexcept.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/config/workaround.hpp>
#include <cstddef> // for std::ptrdiff_t

View File

@ -16,7 +16,7 @@
#include <boost/smart_ptr/detail/sp_nullptr_t.hpp>
#include <boost/smart_ptr/detail/sp_disable_deprecated.hpp>
#include <boost/smart_ptr/detail/sp_noexcept.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/config/workaround.hpp>
#ifndef BOOST_NO_AUTO_PTR
# include <memory> // for std::auto_ptr

View File

@ -25,7 +25,7 @@
#include <boost/smart_ptr/detail/shared_count.hpp>
#include <boost/smart_ptr/detail/sp_nullptr_t.hpp>
#include <boost/smart_ptr/detail/sp_noexcept.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/config/workaround.hpp>
#include <cstddef> // for std::ptrdiff_t
#include <algorithm> // for std::swap
@ -225,7 +225,7 @@ public:
pn.swap(other.pn);
}
void * _internal_get_deleter( boost::detail::sp_typeinfo const & ti ) const BOOST_SP_NOEXCEPT
void * _internal_get_deleter( boost::detail::sp_typeinfo_ const & ti ) const BOOST_SP_NOEXCEPT
{
return pn.get_deleter( ti );
}
@ -285,7 +285,7 @@ template<class T> void swap(shared_array<T> & a, shared_array<T> & b) BOOST_SP_N
template< class D, class T > D * get_deleter( shared_array<T> const & p ) BOOST_SP_NOEXCEPT
{
return static_cast< D * >( p._internal_get_deleter( BOOST_SP_TYPEID(D) ) );
return static_cast< D * >( p._internal_get_deleter( BOOST_SP_TYPEID_(D) ) );
}
} // namespace boost

View File

@ -14,23 +14,16 @@
// See http://www.boost.org/libs/smart_ptr/ for documentation.
//
#include <boost/config.hpp> // for broken compiler workarounds
// 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 <boost/assert.hpp>
#include <boost/checked_delete.hpp>
#include <boost/throw_exception.hpp>
#include <boost/smart_ptr/detail/shared_count.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/smart_ptr/detail/sp_convertible.hpp>
#include <boost/smart_ptr/detail/sp_nullptr_t.hpp>
#include <boost/smart_ptr/detail/sp_disable_deprecated.hpp>
#include <boost/smart_ptr/detail/sp_noexcept.hpp>
#include <boost/checked_delete.hpp>
#include <boost/throw_exception.hpp>
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/config/workaround.hpp>
#if !defined(BOOST_SP_NO_ATOMIC_ACCESS)
#include <boost/smart_ptr/detail/spinlock_pool.hpp>
@ -40,6 +33,7 @@
#include <functional> // for std::less
#include <typeinfo> // for std::bad_cast
#include <cstddef> // for std::size_t
#include <memory> // for std::auto_ptr
#if !defined(BOOST_NO_IOSTREAM)
#if !defined(BOOST_NO_IOSFWD)
@ -86,7 +80,7 @@ template< class T > struct sp_element< T[] >
typedef T type;
};
#if !defined( __BORLANDC__ ) || !BOOST_WORKAROUND( __BORLANDC__, < 0x600 )
#if !defined( BOOST_BORLANDC ) || !BOOST_WORKAROUND( BOOST_BORLANDC, < 0x600 )
template< class T, std::size_t N > struct sp_element< T[N] >
{
@ -135,7 +129,7 @@ template< class T > struct sp_dereference< T[] >
typedef void type;
};
#if !defined( __BORLANDC__ ) || !BOOST_WORKAROUND( __BORLANDC__, < 0x600 )
#if !defined( BOOST_BORLANDC ) || !BOOST_WORKAROUND( BOOST_BORLANDC, < 0x600 )
template< class T, std::size_t N > struct sp_dereference< T[N] >
{
@ -160,7 +154,7 @@ template< class T > struct sp_member_access< T[] >
typedef void type;
};
#if !defined( __BORLANDC__ ) || !BOOST_WORKAROUND( __BORLANDC__, < 0x600 )
#if !defined( BOOST_BORLANDC ) || !BOOST_WORKAROUND( BOOST_BORLANDC, < 0x600 )
template< class T, std::size_t N > struct sp_member_access< T[N] >
{
@ -185,7 +179,7 @@ template< class T > struct sp_array_access< T[] >
typedef T & type;
};
#if !defined( __BORLANDC__ ) || !BOOST_WORKAROUND( __BORLANDC__, < 0x600 )
#if !defined( BOOST_BORLANDC ) || !BOOST_WORKAROUND( BOOST_BORLANDC, < 0x600 )
template< class T, std::size_t N > struct sp_array_access< T[N] >
{
@ -777,12 +771,27 @@ public:
return pn < rhs.pn;
}
void * _internal_get_deleter( boost::detail::sp_typeinfo const & ti ) const BOOST_SP_NOEXCEPT
template<class Y> bool owner_equals( shared_ptr<Y> const & rhs ) const BOOST_SP_NOEXCEPT
{
return pn == rhs.pn;
}
template<class Y> bool owner_equals( weak_ptr<Y> const & rhs ) const BOOST_SP_NOEXCEPT
{
return pn == rhs.pn;
}
std::size_t owner_hash_value() const BOOST_SP_NOEXCEPT
{
return pn.hash_value();
}
void * _internal_get_deleter( boost::detail::sp_typeinfo_ const & ti ) const BOOST_SP_NOEXCEPT
{
return pn.get_deleter( ti );
}
void * _internal_get_local_deleter( boost::detail::sp_typeinfo const & ti ) const BOOST_SP_NOEXCEPT
void * _internal_get_local_deleter( boost::detail::sp_typeinfo_ const & ti ) const BOOST_SP_NOEXCEPT
{
return pn.get_local_deleter( ti );
}
@ -1008,7 +1017,7 @@ namespace detail
template<class D, class T> D * basic_get_deleter( shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT
{
return static_cast<D *>( p._internal_get_deleter(BOOST_SP_TYPEID(D)) );
return static_cast<D *>( p._internal_get_deleter(BOOST_SP_TYPEID_(D)) );
}
template<class D, class T> D * basic_get_local_deleter( D *, shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT;
@ -1155,6 +1164,25 @@ template< class T > std::size_t hash_value( boost::shared_ptr<T> const & p ) BOO
} // namespace boost
// std::hash
#if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
namespace std
{
template<class T> struct hash< ::boost::shared_ptr<T> >
{
std::size_t operator()( ::boost::shared_ptr<T> const & p ) const BOOST_SP_NOEXCEPT
{
return std::hash< typename ::boost::shared_ptr<T>::element_type* >()( p.get() );
}
};
} // namespace std
#endif // #if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
#include <boost/smart_ptr/detail/local_sp_deleter.hpp>
namespace boost
@ -1165,16 +1193,23 @@ namespace detail
template<class D, class T> D * basic_get_local_deleter( D *, shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT
{
return static_cast<D *>( p._internal_get_local_deleter( BOOST_SP_TYPEID(local_sp_deleter<D>) ) );
return static_cast<D *>( p._internal_get_local_deleter( BOOST_SP_TYPEID_(local_sp_deleter<D>) ) );
}
template<class D, class T> D const * basic_get_local_deleter( D const *, shared_ptr<T> const & p ) BOOST_SP_NOEXCEPT
{
return static_cast<D *>( p._internal_get_local_deleter( BOOST_SP_TYPEID(local_sp_deleter<D>) ) );
return static_cast<D *>( p._internal_get_local_deleter( BOOST_SP_TYPEID_(local_sp_deleter<D>) ) );
}
} // namespace detail
#if defined(__cpp_deduction_guides)
template<class T> shared_ptr( weak_ptr<T> ) -> shared_ptr<T>;
template<class T, class D> shared_ptr( std::unique_ptr<T, D> ) -> shared_ptr<T>;
#endif
} // namespace boost
#if defined( BOOST_SP_DISABLE_DEPRECATED )

View File

@ -13,10 +13,11 @@
// See http://www.boost.org/libs/smart_ptr/ for documentation.
//
#include <memory> // boost.TR1 include order fix
#include <boost/smart_ptr/detail/shared_count.hpp>
#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/smart_ptr/detail/sp_noexcept.hpp>
#include <memory>
#include <cstddef>
namespace boost
{
@ -137,6 +138,23 @@ public:
boost::detail::sp_assert_convertible< Y, T >();
}
// aliasing
template<class Y> weak_ptr(shared_ptr<Y> const & r, element_type * p) BOOST_SP_NOEXCEPT: px( p ), pn( r.pn )
{
}
template<class Y> weak_ptr(weak_ptr<Y> const & r, element_type * p) BOOST_SP_NOEXCEPT: px( p ), pn( r.pn )
{
}
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
template<class Y> weak_ptr(weak_ptr<Y> && r, element_type * p) BOOST_SP_NOEXCEPT: px( p ), pn( std::move( r.pn ) )
{
}
#endif
#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300)
template<class Y>
@ -194,6 +212,11 @@ public:
return pn.empty();
}
bool empty() const BOOST_SP_NOEXCEPT // extension, not in std::weak_ptr
{
return pn.empty();
}
void reset() BOOST_SP_NOEXCEPT
{
this_type().swap(*this);
@ -205,13 +228,6 @@ public:
pn.swap(other.pn);
}
template<typename Y>
void _internal_aliasing_assign(weak_ptr<Y> const & r, element_type * px2) BOOST_SP_NOEXCEPT
{
px = px2;
pn = r.pn;
}
template<class Y> bool owner_before( weak_ptr<Y> const & rhs ) const BOOST_SP_NOEXCEPT
{
return pn < rhs.pn;
@ -222,6 +238,21 @@ public:
return pn < rhs.pn;
}
template<class Y> bool owner_equals( weak_ptr<Y> const & rhs ) const BOOST_SP_NOEXCEPT
{
return pn == rhs.pn;
}
template<class Y> bool owner_equals( shared_ptr<Y> const & rhs ) const BOOST_SP_NOEXCEPT
{
return pn == rhs.pn;
}
std::size_t owner_hash_value() const BOOST_SP_NOEXCEPT
{
return pn.hash_value();
}
// Tasteless as this may seem, making all members public allows member templates
// to work in the absence of member template friends. (Matthew Langston)
@ -249,6 +280,46 @@ template<class T> void swap(weak_ptr<T> & a, weak_ptr<T> & b) BOOST_SP_NOEXCEPT
a.swap(b);
}
#if defined(__cpp_deduction_guides)
template<class T> weak_ptr( shared_ptr<T> ) -> weak_ptr<T>;
#endif
// hash_value
template< class T > std::size_t hash_value( boost::weak_ptr<T> const & p ) BOOST_SP_NOEXCEPT
{
return p.owner_hash_value();
}
} // namespace boost
// std::hash, std::equal_to
namespace std
{
#if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
template<class T> struct hash< ::boost::weak_ptr<T> >
{
std::size_t operator()( ::boost::weak_ptr<T> const & p ) const BOOST_SP_NOEXCEPT
{
return p.owner_hash_value();
}
};
#endif // #if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
template<class T> struct equal_to< ::boost::weak_ptr<T> >
{
bool operator()( ::boost::weak_ptr<T> const & a, ::boost::weak_ptr<T> const & b ) const BOOST_SP_NOEXCEPT
{
return a.owner_equals( b );
}
};
} // namespace std
#endif // #ifndef BOOST_SMART_PTR_WEAK_PTR_HPP_INCLUDED

15
test/CMakeLists.txt Normal file
View File

@ -0,0 +1,15 @@
# Copyright 2018, 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
include(BoostTestJamfile OPTIONAL RESULT_VARIABLE HAVE_BOOST_TEST)
if(HAVE_BOOST_TEST)
# for lw_thread_test.cpp
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads)
boost_test_jamfile(FILE Jamfile LINK_LIBRARIES Boost::smart_ptr Boost::core Boost::align Boost::atomic Boost::container_hash Boost::bind Threads::Threads)
endif()

View File

@ -57,10 +57,11 @@ run yield_k_test.cpp : : : <threading>multi : yield_k_test.mt ;
run spinlock_test.cpp ;
run spinlock_try_test.cpp ;
run spinlock_try_test.cpp : : : <threading>multi : spinlock_try_test.mt ;
run spinlock_pool_test.cpp : : :
# msvc-8.0, 9.0 optimizer codegen bug for `x % 41`
<toolset>msvc-8.0,<variant>release:<build>no
<toolset>msvc-9.0,<variant>release:<build>no ;
run spinlock_pool_test.cpp
: : :
# msvc-8.0, 9.0 optimizer codegen bug for `x % 41`
<toolset>msvc-8.0,<variant>release:<build>no
<toolset>msvc-9.0,<variant>release:<build>no ;
run make_shared_test.cpp ;
run make_shared_move_emulation_test.cpp ;
@ -78,7 +79,10 @@ run sp_recursive_assign_test.cpp ;
run sp_recursive_assign2_test.cpp ;
run sp_recursive_assign_rv_test.cpp ;
run sp_recursive_assign2_rv_test.cpp ;
compile-fail auto_ptr_lv_fail.cpp : <toolset>gcc-4.4.7:<build>no ;
compile-fail auto_ptr_lv_fail.cpp
: <toolset>gcc-4.4.7:<build>no ;
run atomic_count_test2.cpp ;
run sp_typeinfo_test.cpp ;
compile make_shared_fp_test.cpp ;
@ -158,23 +162,33 @@ compile-fail array_fail_dereference.cpp ;
compile-fail array_fail_member_access.cpp ;
compile-fail array_fail_array_access.cpp ;
run make_shared_array_test.cpp ;
run make_shared_arrays_test.cpp ; # <cxxflags>-fno-deduce-init-list no longer needed for gcc-4.6
run make_shared_array_throws_test.cpp ;
run make_shared_array_esft_test.cpp ;
run make_shared_array_noinit_test.cpp ;
run make_shared_array_value_test.cpp ;
run make_shared_array_test.cpp
: : : <toolset>msvc-8.0:<build>no ;
run make_shared_arrays_test.cpp ;
run make_shared_array_throws_test.cpp
: : : <toolset>msvc-8.0:<build>no ;
run make_shared_array_esft_test.cpp
: : : <toolset>msvc-8.0:<build>no ;
run make_shared_array_noinit_test.cpp
: : : <toolset>msvc-8.0:<build>no ;
run make_shared_array_value_test.cpp
: : : <toolset>msvc-8.0:<build>no ;
run allocate_shared_array_test.cpp ;
run allocate_shared_arrays_test.cpp ; # <cxxflags>-fno-deduce-init-list no longer needed for gcc-4.6
run allocate_shared_array_throws_test.cpp ;
run allocate_shared_array_esft_test.cpp ;
run allocate_shared_array_noinit_test.cpp ;
run allocate_shared_array_value_test.cpp ;
run allocate_shared_arrays_test.cpp ;
run allocate_shared_array_throws_test.cpp
: : : <toolset>msvc-8.0:<build>no ;
run allocate_shared_array_esft_test.cpp
: : : <toolset>msvc-8.0:<build>no ;
run allocate_shared_array_noinit_test.cpp
: : : <toolset>msvc-8.0:<build>no ;
run allocate_shared_array_value_test.cpp
: : : <toolset>msvc-8.0:<build>no ;
run allocate_shared_array_construct_test.cpp ;
run make_unique_test.cpp ;
run make_unique_args_test.cpp ;
run make_unique_value_test.cpp : : : <toolset>gcc-4.6:<cxxflags>-fno-deduce-init-list ;
run make_unique_value_test.cpp
: : : <toolset>gcc-4.6:<cxxflags>-fno-deduce-init-list ;
run make_unique_noinit_test.cpp ;
run make_unique_throws_test.cpp ;
run make_unique_array_test.cpp ;
@ -236,7 +250,8 @@ run shared_ptr_fn_test.cpp ;
run get_deleter_test2.cpp ;
run get_deleter_test3.cpp ;
run get_deleter_array_test2.cpp ;
run get_deleter_array_test3.cpp ;
run get_deleter_array_test3.cpp
: : : <toolset>msvc-8.0:<build>no ;
run sp_convertible_test2.cpp ;
@ -258,13 +273,15 @@ run allocate_local_shared_test.cpp ;
run allocate_local_shared_esft_test.cpp ;
run make_local_shared_array_test.cpp ;
run make_local_shared_arrays_test.cpp : : : <toolset>gcc-4.6.3_0x:<cxxflags>-fno-deduce-init-list ;
run make_local_shared_arrays_test.cpp
: : : <toolset>gcc-4.6.3_0x:<cxxflags>-fno-deduce-init-list ;
run make_local_shared_array_throws_test.cpp ;
run make_local_shared_array_esft_test.cpp ;
run make_local_shared_array_noinit_test.cpp ;
run make_local_shared_array_value_test.cpp ;
run allocate_local_shared_array_test.cpp ;
run allocate_local_shared_arrays_test.cpp : : : <toolset>gcc-4.6.3_0x:<cxxflags>-fno-deduce-init-list ;
run allocate_local_shared_arrays_test.cpp
: : : <toolset>gcc-4.6.3_0x:<cxxflags>-fno-deduce-init-list ;
run allocate_local_shared_array_throws_test.cpp ;
run allocate_local_shared_array_esft_test.cpp ;
run allocate_local_shared_array_noinit_test.cpp ;
@ -275,9 +292,11 @@ run local_sp_fn_test.cpp ;
run lsp_convertible_test.cpp ;
run lsp_convertible_test2.cpp ;
run make_shared_array_tmp_test.cpp ;
run make_shared_array_tmp_test.cpp
: : : <toolset>msvc-8.0:<build>no ;
run lw_thread_test.cpp : : : <threading>multi ;
run lw_thread_test.cpp
: : : <threading>multi ;
compile sp_windows_h_test.cpp ;
compile spinlock_windows_h_test.cpp ;
@ -306,3 +325,83 @@ run abi_test_main.cpp abi_test_nt : : : : abi_test_mt_nt ;
run abi_test_main.cpp abi_test_mt/<cxxstd>0x : : : <cxxstd>98 : abi_test_03_11 ;
run abi_test_main.cpp abi_test_mt/<cxxstd>98 : : : <cxxstd>0x : abi_test_11_03 ;
run weak_ptr_alias_test.cpp ;
run weak_ptr_alias_move_test.cpp ;
run sp_typeinfo_test.cpp : : : <rtti>off : sp_typeinfo_test_no_rtti ;
run get_deleter_test.cpp : : : <rtti>off <toolset>gcc-4.4.7,<cxxstd>0x:<build>no : get_deleter_test_no_rtti ;
run get_deleter_test2.cpp : : : <rtti>off <toolset>gcc-4.4.7,<cxxstd>0x:<build>no : get_deleter_test2_no_rtti ;
run get_deleter_test3.cpp : : : <rtti>off <toolset>gcc-4.4.7,<cxxstd>0x:<build>no : get_deleter_test3_no_rtti ;
run shared_from_test.cpp ;
run weak_from_test.cpp ;
run weak_from_test2.cpp ;
run allocate_unique_aggregate_test.cpp ;
run allocate_unique_args_test.cpp ;
run allocate_unique_array_construct_test.cpp ;
run allocate_unique_array_noinit_test.cpp ;
run allocate_unique_arrays_test.cpp ;
run allocate_unique_array_test.cpp ;
run allocate_unique_array_throws_test.cpp ;
run allocate_unique_array_value_test.cpp ;
run allocate_unique_construct_test.cpp ;
run allocate_unique_noinit_test.cpp ;
run allocate_unique_test.cpp ;
run allocate_unique_throws_test.cpp ;
run allocate_unique_value_test.cpp ;
run sp_guides_test.cpp ;
run sp_guides_test2.cpp ;
run wp_guides_test.cpp ;
compile-fail shared_from_fail.cpp ;
compile-fail weak_from_fail.cpp ;
compile sp_override_test.cpp ;
compile sp_pedantic_test.cpp
: <warnings>pedantic
<toolset>msvc:<warnings-as-errors>on
<toolset>gcc:<warnings-as-errors>on
<toolset>clang:<warnings-as-errors>on ;
run sp_owner_before_test.cpp ;
run sp_owner_equals_test.cpp ;
run lsp_owner_before_test.cpp ;
run lsp_owner_equals_test.cpp ;
run owner_equal_to_test.cpp ;
run owner_equal_to_test2.cpp ;
run owner_less_test2.cpp ;
run ip_hash_test2.cpp ;
run sp_hash_test4.cpp ;
run lsp_hash_test.cpp ;
run lsp_hash_test2.cpp ;
run atomic_count_mt_test.cpp
: : : <threading>multi ;
run spinlock_mt_test.cpp
: : : <threading>multi ;
run spinlock_pool_mt_test.cpp
: : : <threading>multi ;
run shared_ptr_mt_test.cpp
: : : <threading>multi ;
run weak_ptr_mt_test.cpp
: : : <threading>multi ;
compile sp_report_implementation.cpp ;
run sp_owner_hash_value_test.cpp ;
run wp_hash_test.cpp ;
run wp_hash_test2.cpp ;
run wp_unordered_test.cpp ;

View File

@ -8,7 +8,7 @@
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/detail/lightweight_test.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/make_shared.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>

View File

@ -8,7 +8,7 @@
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/detail/lightweight_test.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/make_shared.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>

View File

@ -6,7 +6,7 @@
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/detail/lightweight_test.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/make_shared.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>

View File

@ -6,7 +6,7 @@
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/detail/lightweight_test.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/make_shared.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>

View File

@ -0,0 +1,84 @@
/*
Copyright 2019 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#include <boost/config.hpp>
#if (!defined(BOOST_LIBSTDCXX_VERSION) || \
BOOST_LIBSTDCXX_VERSION >= 46000) && \
!defined(BOOST_NO_CXX11_SMART_PTR) && \
!defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
#include <boost/smart_ptr/allocate_unique.hpp>
#include <boost/core/lightweight_test.hpp>
template<class T = void>
struct creator {
typedef T value_type;
typedef T* pointer;
template<class U>
struct rebind {
typedef creator<U> other;
};
creator() { }
template<class U>
creator(const creator<U>&) { }
T* allocate(std::size_t size) {
return static_cast<T*>(::operator new(sizeof(T) * size));
}
void deallocate(T* ptr, std::size_t) {
::operator delete(ptr);
}
};
template<class T, class U>
inline bool
operator==(const creator<T>&, const creator<U>&)
{
return true;
}
template<class T, class U>
inline bool
operator!=(const creator<T>&, const creator<U>&)
{
return false;
}
struct type {
int x;
int y;
};
int main()
{
{
std::unique_ptr<type,
boost::alloc_deleter<type, creator<type> > > result =
boost::allocate_unique<type>(creator<type>(), { 1, 2 });
BOOST_TEST(result.get() != 0);
BOOST_TEST(result->x == 1);
BOOST_TEST(result->y == 2);
}
{
std::unique_ptr<const type,
boost::alloc_deleter<const type, creator<> > > result =
boost::allocate_unique<const type>(creator<>(), { 1, 2 });
BOOST_TEST(result.get() != 0);
BOOST_TEST(result->x == 1);
BOOST_TEST(result->y == 2);
}
return boost::report_errors();
}
#else
int main()
{
return 0;
}
#endif

View File

@ -0,0 +1,111 @@
/*
Copyright 2019 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#include <boost/config.hpp>
#if (!defined(BOOST_LIBSTDCXX_VERSION) || \
BOOST_LIBSTDCXX_VERSION >= 46000) && \
!defined(BOOST_NO_CXX11_SMART_PTR) && \
!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <boost/smart_ptr/allocate_unique.hpp>
#include <boost/core/lightweight_test.hpp>
template<class T = void>
struct creator {
typedef T value_type;
typedef T* pointer;
template<class U>
struct rebind {
typedef creator<U> other;
};
creator() { }
template<class U>
creator(const creator<U>&) { }
T* allocate(std::size_t size) {
return static_cast<T*>(::operator new(sizeof(T) * size));
}
void deallocate(T* ptr, std::size_t) {
::operator delete(ptr);
}
};
template<class T, class U>
inline bool
operator==(const creator<T>&, const creator<U>&)
{
return true;
}
template<class T, class U>
inline bool
operator!=(const creator<T>&, const creator<U>&)
{
return false;
}
class type {
public:
static unsigned instances;
type(int v1, int v2, int v3, int v4, int v5)
: sum_(v1 + v2 + v3 + v4 + v5) {
++instances;
}
~type() {
--instances;
}
int sum() const {
return sum_;
}
private:
int sum_;
type(const type&);
type& operator=(const type&);
};
unsigned type::instances = 0;
int main()
{
BOOST_TEST(type::instances == 0);
{
std::unique_ptr<type,
boost::alloc_deleter<type, creator<type> > > result =
boost::allocate_unique<type>(creator<type>(), 1, 2, 3, 4, 5);
BOOST_TEST(result.get() != 0);
BOOST_TEST(type::instances == 1);
BOOST_TEST(result->sum() == 15);
result.reset();
BOOST_TEST(type::instances == 0);
}
BOOST_TEST(type::instances == 0);
{
std::unique_ptr<const type,
boost::alloc_deleter<const type, creator<> > > result =
boost::allocate_unique<const type>(creator<>(), 1, 2, 3, 4, 5);
BOOST_TEST(result.get() != 0);
BOOST_TEST(type::instances == 1);
BOOST_TEST(result->sum() == 15);
result.reset();
BOOST_TEST(type::instances == 0);
}
return boost::report_errors();
}
#else
int main()
{
return 0;
}
#endif

View File

@ -0,0 +1,166 @@
/*
Copyright 2019 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#include <boost/config.hpp>
#if (!defined(BOOST_LIBSTDCXX_VERSION) || \
BOOST_LIBSTDCXX_VERSION >= 48000) && \
!defined(BOOST_NO_CXX11_SMART_PTR) && \
!defined(BOOST_NO_CXX11_ALLOCATOR)
#include <boost/smart_ptr/allocate_unique.hpp>
#include <boost/core/lightweight_test.hpp>
struct allow { };
template<class T = void>
struct creator {
typedef T value_type;
template<class U>
struct rebind {
typedef creator<U> other;
};
creator() { }
template<class U>
creator(const creator<U>&) { }
T* allocate(std::size_t size) {
return static_cast<T*>(::operator new(sizeof(T) * size));
}
void deallocate(T* ptr, std::size_t) {
::operator delete(ptr);
}
template<class U>
void construct(U* ptr) {
::new(static_cast<void*>(ptr)) U(allow());
}
template<class U>
void destroy(U* ptr) {
ptr->~U();
}
};
template<class T, class U>
inline bool
operator==(const creator<T>&, const creator<U>&)
{
return true;
}
template<class T, class U>
inline bool
operator!=(const creator<T>&, const creator<U>&)
{
return false;
}
class type {
public:
static unsigned instances;
explicit type(allow) {
++instances;
}
~type() {
--instances;
}
private:
type(const type&);
type& operator=(const type&);
};
unsigned type::instances = 0;
int main()
{
{
std::unique_ptr<type[],
boost::alloc_deleter<type[], creator<type> > > result =
boost::allocate_unique<type[]>(creator<type>(), 3);
BOOST_TEST(result.get() != 0);
BOOST_TEST(type::instances == 3);
result.reset();
BOOST_TEST(type::instances == 0);
}
{
std::unique_ptr<type[],
boost::alloc_deleter<type[3], creator<type> > > result =
boost::allocate_unique<type[3]>(creator<type>());
BOOST_TEST(result.get() != 0);
BOOST_TEST(type::instances == 3);
result.reset();
BOOST_TEST(type::instances == 0);
}
{
std::unique_ptr<type[][2],
boost::alloc_deleter<type[][2], creator<> > > result =
boost::allocate_unique<type[][2]>(creator<>(), 2);
BOOST_TEST(result.get() != 0);
BOOST_TEST(type::instances == 4);
result.reset();
BOOST_TEST(type::instances == 0);
}
{
std::unique_ptr<type[][2],
boost::alloc_deleter<type[2][2], creator<> > > result =
boost::allocate_unique<type[2][2]>(creator<>());
BOOST_TEST(result.get() != 0);
BOOST_TEST(type::instances == 4);
result.reset();
BOOST_TEST(type::instances == 0);
}
{
std::unique_ptr<const type[],
boost::alloc_deleter<const type[], creator<> > > result =
boost::allocate_unique<const type[]>(creator<>(), 3);
BOOST_TEST(result.get() != 0);
BOOST_TEST(type::instances == 3);
result.reset();
BOOST_TEST(type::instances == 0);
}
{
std::unique_ptr<const type[],
boost::alloc_deleter<const type[3], creator<> > > result =
boost::allocate_unique<const type[3]>(creator<>());
BOOST_TEST(result.get() != 0);
BOOST_TEST(type::instances == 3);
result.reset();
BOOST_TEST(type::instances == 0);
}
{
std::unique_ptr<const type[][2],
boost::alloc_deleter<const type[][2], creator<> > > result =
boost::allocate_unique<const type[][2]>(creator<>(), 2);
BOOST_TEST(result.get() != 0);
BOOST_TEST(type::instances == 4);
result.reset();
BOOST_TEST(type::instances == 0);
}
{
std::unique_ptr<const type[][2],
boost::alloc_deleter<const type[2][2], creator<> > > result =
boost::allocate_unique<const type[2][2]>(creator<>());
BOOST_TEST(result.get() != 0);
BOOST_TEST(type::instances == 4);
result.reset();
BOOST_TEST(type::instances == 0);
}
return boost::report_errors();
}
#else
int main()
{
return 0;
}
#endif

View File

@ -0,0 +1,228 @@
/*
Copyright 2019 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#include <boost/config.hpp>
#if (!defined(BOOST_LIBSTDCXX_VERSION) || \
BOOST_LIBSTDCXX_VERSION >= 48000) && \
!defined(BOOST_NO_CXX11_SMART_PTR)
#include <boost/smart_ptr/allocate_unique.hpp>
#include <boost/core/lightweight_test.hpp>
template<class T = void>
struct creator {
typedef T value_type;
typedef T* pointer;
template<class U>
struct rebind {
typedef creator<U> other;
};
creator() { }
template<class U>
creator(const creator<U>&) { }
T* allocate(std::size_t size) {
return static_cast<T*>(::operator new(sizeof(T) * size));
}
void deallocate(T* ptr, std::size_t) {
::operator delete(ptr);
}
};
template<class T, class U>
inline bool
operator==(const creator<T>&, const creator<U>&)
{
return true;
}
template<class T, class U>
inline bool
operator!=(const creator<T>&, const creator<U>&)
{
return false;
}
class type {
public:
static unsigned instances;
type()
: value_(0.0) {
++instances;
}
~type() {
--instances;
}
void set(long double value) {
value_ = value;
}
long double get() const {
return value_;
}
private:
type(const type&);
type& operator=(const type&);
long double value_;
};
unsigned type::instances = 0;
int main()
{
{
std::unique_ptr<int[],
boost::alloc_deleter<int[],
boost::noinit_adaptor<creator<int> > > > result =
boost::allocate_unique_noinit<int[]>(creator<int>(), 3);
BOOST_TEST(result.get() != 0);
}
{
std::unique_ptr<int[],
boost::alloc_deleter<int[3],
boost::noinit_adaptor<creator<int> > > > result =
boost::allocate_unique_noinit<int[3]>(creator<int>());
BOOST_TEST(result.get() != 0);
}
{
std::unique_ptr<int[][2],
boost::alloc_deleter<int[][2],
boost::noinit_adaptor<creator<> > > > result =
boost::allocate_unique_noinit<int[][2]>(creator<>(), 2);
BOOST_TEST(result.get() != 0);
}
{
std::unique_ptr<int[][2],
boost::alloc_deleter<int[2][2],
boost::noinit_adaptor<creator<> > > > result =
boost::allocate_unique_noinit<int[2][2]>(creator<>());
BOOST_TEST(result.get() != 0);
}
{
std::unique_ptr<const int[],
boost::alloc_deleter<const int[],
boost::noinit_adaptor<creator<> > > > result =
boost::allocate_unique_noinit<const int[]>(creator<>(), 3);
BOOST_TEST(result.get() != 0);
}
{
std::unique_ptr<const int[],
boost::alloc_deleter<const int[3],
boost::noinit_adaptor<creator<> > > > result =
boost::allocate_unique_noinit<const int[3]>(creator<>());
BOOST_TEST(result.get() != 0);
}
{
std::unique_ptr<const int[][2],
boost::alloc_deleter<const int[][2],
boost::noinit_adaptor<creator<> > > > result =
boost::allocate_unique_noinit<const int[][2]>(creator<>(), 2);
BOOST_TEST(result.get() != 0);
}
{
std::unique_ptr<const int[][2],
boost::alloc_deleter<const int[2][2],
boost::noinit_adaptor<creator<> > > > result =
boost::allocate_unique_noinit<const int[2][2]>(creator<>());
BOOST_TEST(result.get() != 0);
}
{
std::unique_ptr<type[],
boost::alloc_deleter<type[],
boost::noinit_adaptor<creator<type> > > > result =
boost::allocate_unique_noinit<type[]>(creator<type>(), 3);
BOOST_TEST(result.get() != 0);
BOOST_TEST(type::instances == 3);
result.reset();
BOOST_TEST(type::instances == 0);
}
{
std::unique_ptr<type[],
boost::alloc_deleter<type[3],
boost::noinit_adaptor<creator<type> > > > result =
boost::allocate_unique_noinit<type[3]>(creator<type>());
BOOST_TEST(result.get() != 0);
BOOST_TEST(type::instances == 3);
result.reset();
BOOST_TEST(type::instances == 0);
}
{
std::unique_ptr<type[][2],
boost::alloc_deleter<type[][2],
boost::noinit_adaptor<creator<> > > > result =
boost::allocate_unique_noinit<type[][2]>(creator<>(), 2);
BOOST_TEST(result.get() != 0);
BOOST_TEST(type::instances == 4);
result.reset();
BOOST_TEST(type::instances == 0);
}
{
std::unique_ptr<type[][2],
boost::alloc_deleter<type[2][2],
boost::noinit_adaptor<creator<> > > > result =
boost::allocate_unique_noinit<type[2][2]>(creator<>());
BOOST_TEST(result.get() != 0);
BOOST_TEST(type::instances == 4);
result.reset();
BOOST_TEST(type::instances == 0);
}
{
std::unique_ptr<const type[],
boost::alloc_deleter<const type[],
boost::noinit_adaptor<creator<> > > > result =
boost::allocate_unique_noinit<const type[]>(creator<>(), 3);
BOOST_TEST(result.get() != 0);
BOOST_TEST(type::instances == 3);
result.reset();
BOOST_TEST(type::instances == 0);
}
{
std::unique_ptr<const type[],
boost::alloc_deleter<const type[3],
boost::noinit_adaptor<creator<> > > > result =
boost::allocate_unique_noinit<const type[3]>(creator<>());
BOOST_TEST(result.get() != 0);
BOOST_TEST(type::instances == 3);
result.reset();
BOOST_TEST(type::instances == 0);
}
{
std::unique_ptr<const type[][2],
boost::alloc_deleter<const type[][2],
boost::noinit_adaptor<creator<> > > > result =
boost::allocate_unique_noinit<const type[][2]>(creator<>(), 2);
BOOST_TEST(result.get() != 0);
BOOST_TEST(type::instances == 4);
result.reset();
BOOST_TEST(type::instances == 0);
}
{
std::unique_ptr<const type[][2],
boost::alloc_deleter<const type[2][2],
boost::noinit_adaptor<creator<> > > > result =
boost::allocate_unique_noinit<const type[2][2]>(creator<>());
BOOST_TEST(result.get() != 0);
BOOST_TEST(type::instances == 4);
result.reset();
BOOST_TEST(type::instances == 0);
}
return boost::report_errors();
}
#else
int main()
{
return 0;
}
#endif

View File

@ -0,0 +1,240 @@
/*
Copyright 2019 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#include <boost/config.hpp>
#if (!defined(BOOST_LIBSTDCXX_VERSION) || \
BOOST_LIBSTDCXX_VERSION >= 48000) && \
!defined(BOOST_NO_CXX11_SMART_PTR)
#include <boost/smart_ptr/allocate_unique.hpp>
#include <boost/core/lightweight_test.hpp>
template<class T = void>
struct creator {
typedef T value_type;
typedef T* pointer;
template<class U>
struct rebind {
typedef creator<U> other;
};
creator() { }
template<class U>
creator(const creator<U>&) { }
T* allocate(std::size_t size) {
return static_cast<T*>(::operator new(sizeof(T) * size));
}
void deallocate(T* ptr, std::size_t) {
::operator delete(ptr);
}
};
template<class T, class U>
inline bool
operator==(const creator<T>&, const creator<U>&)
{
return true;
}
template<class T, class U>
inline bool
operator!=(const creator<T>&, const creator<U>&)
{
return false;
}
class type {
public:
static unsigned instances;
type()
: value_(0.0) {
++instances;
}
~type() {
--instances;
}
void set(long double value) {
value_ = value;
}
long double get() const {
return value_;
}
private:
type(const type&);
type& operator=(const type&);
long double value_;
};
unsigned type::instances = 0;
int main()
{
{
std::unique_ptr<int[],
boost::alloc_deleter<int[], creator<int> > > result =
boost::allocate_unique<int[]>(creator<int>(), 3);
BOOST_TEST(result.get() != 0);
BOOST_TEST(result[0] == 0);
BOOST_TEST(result[1] == 0);
BOOST_TEST(result[2] == 0);
}
{
std::unique_ptr<int[],
boost::alloc_deleter<int[3], creator<int> > > result =
boost::allocate_unique<int[3]>(creator<int>());
BOOST_TEST(result.get() != 0);
BOOST_TEST(result[0] == 0);
BOOST_TEST(result[1] == 0);
BOOST_TEST(result[2] == 0);
}
{
std::unique_ptr<int[][2],
boost::alloc_deleter<int[][2], creator<> > > result =
boost::allocate_unique<int[][2]>(creator<>(), 2);
BOOST_TEST(result.get() != 0);
BOOST_TEST(result[0][0] == 0);
BOOST_TEST(result[0][1] == 0);
BOOST_TEST(result[1][0] == 0);
BOOST_TEST(result[1][1] == 0);
}
{
std::unique_ptr<int[][2],
boost::alloc_deleter<int[2][2], creator<> > > result =
boost::allocate_unique<int[2][2]>(creator<>());
BOOST_TEST(result.get() != 0);
BOOST_TEST(result[0][0] == 0);
BOOST_TEST(result[0][1] == 0);
BOOST_TEST(result[1][0] == 0);
BOOST_TEST(result[1][1] == 0);
}
{
std::unique_ptr<const int[],
boost::alloc_deleter<const int[], creator<> > > result =
boost::allocate_unique<const int[]>(creator<>(), 3);
BOOST_TEST(result.get() != 0);
BOOST_TEST(result[0] == 0);
BOOST_TEST(result[1] == 0);
BOOST_TEST(result[2] == 0);
}
{
std::unique_ptr<const int[],
boost::alloc_deleter<const int[3], creator<> > > result =
boost::allocate_unique<const int[3]>(creator<>());
BOOST_TEST(result.get() != 0);
BOOST_TEST(result[0] == 0);
BOOST_TEST(result[1] == 0);
BOOST_TEST(result[2] == 0);
}
{
std::unique_ptr<const int[][2],
boost::alloc_deleter<const int[][2], creator<> > > result =
boost::allocate_unique<const int[][2]>(creator<>(), 2);
BOOST_TEST(result.get() != 0);
BOOST_TEST(result[0][0] == 0);
BOOST_TEST(result[0][1] == 0);
BOOST_TEST(result[1][0] == 0);
BOOST_TEST(result[1][1] == 0);
}
{
std::unique_ptr<const int[][2],
boost::alloc_deleter<const int[2][2], creator<> > > result =
boost::allocate_unique<const int[2][2]>(creator<>());
BOOST_TEST(result.get() != 0);
BOOST_TEST(result[0][0] == 0);
BOOST_TEST(result[0][1] == 0);
BOOST_TEST(result[1][0] == 0);
BOOST_TEST(result[1][1] == 0);
}
{
std::unique_ptr<type[],
boost::alloc_deleter<type[], creator<type> > > result =
boost::allocate_unique<type[]>(creator<type>(), 3);
BOOST_TEST(result.get() != 0);
BOOST_TEST(type::instances == 3);
result.reset();
BOOST_TEST(type::instances == 0);
}
{
std::unique_ptr<type[],
boost::alloc_deleter<type[3], creator<type> > > result =
boost::allocate_unique<type[3]>(creator<type>());
BOOST_TEST(result.get() != 0);
BOOST_TEST(type::instances == 3);
result.reset();
BOOST_TEST(type::instances == 0);
}
{
std::unique_ptr<type[][2],
boost::alloc_deleter<type[][2], creator<> > > result =
boost::allocate_unique<type[][2]>(creator<>(), 2);
BOOST_TEST(result.get() != 0);
BOOST_TEST(type::instances == 4);
result.reset();
BOOST_TEST(type::instances == 0);
}
{
std::unique_ptr<type[][2],
boost::alloc_deleter<type[2][2], creator<> > > result =
boost::allocate_unique<type[2][2]>(creator<>());
BOOST_TEST(result.get() != 0);
BOOST_TEST(type::instances == 4);
result.reset();
BOOST_TEST(type::instances == 0);
}
{
std::unique_ptr<const type[],
boost::alloc_deleter<const type[], creator<> > > result =
boost::allocate_unique<const type[]>(creator<>(), 3);
BOOST_TEST(result.get() != 0);
BOOST_TEST(type::instances == 3);
result.reset();
BOOST_TEST(type::instances == 0);
}
{
std::unique_ptr<const type[],
boost::alloc_deleter<const type[3], creator<> > > result =
boost::allocate_unique<const type[3]>(creator<>());
BOOST_TEST(result.get() != 0);
BOOST_TEST(type::instances == 3);
result.reset();
BOOST_TEST(type::instances == 0);
}
{
std::unique_ptr<const type[][2],
boost::alloc_deleter<const type[][2], creator<> > > result =
boost::allocate_unique<const type[][2]>(creator<>(), 2);
BOOST_TEST(result.get() != 0);
BOOST_TEST(type::instances == 4);
result.reset();
BOOST_TEST(type::instances == 0);
}
{
std::unique_ptr<const type[][2],
boost::alloc_deleter<const type[2][2], creator<> > > result =
boost::allocate_unique<const type[2][2]>(creator<>());
BOOST_TEST(result.get() != 0);
BOOST_TEST(type::instances == 4);
result.reset();
BOOST_TEST(type::instances == 0);
}
return boost::report_errors();
}
#else
int main()
{
return 0;
}
#endif

View File

@ -0,0 +1,132 @@
/*
Copyright 2019 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#include <boost/config.hpp>
#if (!defined(BOOST_LIBSTDCXX_VERSION) || \
BOOST_LIBSTDCXX_VERSION >= 48000) && \
!defined(BOOST_NO_CXX11_SMART_PTR)
#include <boost/smart_ptr/allocate_unique.hpp>
#include <boost/core/lightweight_test.hpp>
template<class T = void>
struct creator {
typedef T value_type;
typedef T* pointer;
template<class U>
struct rebind {
typedef creator<U> other;
};
creator() { }
template<class U>
creator(const creator<U>&) { }
T* allocate(std::size_t size) {
return static_cast<T*>(::operator new(sizeof(T) * size));
}
void deallocate(T* ptr, std::size_t) {
::operator delete(ptr);
}
};
template<class T, class U>
inline bool
operator==(const creator<T>&, const creator<U>&)
{
return true;
}
template<class T, class U>
inline bool
operator!=(const creator<T>&, const creator<U>&)
{
return false;
}
class type {
public:
static unsigned instances;
type() {
if (instances == 5) {
throw true;
}
++instances;
}
~type() {
--instances;
}
private:
type(const type&);
type& operator=(const type&);
};
unsigned type::instances = 0;
int main()
{
try {
boost::allocate_unique<type[]>(creator<type>(), 6);
BOOST_ERROR("allocate_unique did not throw");
} catch (...) {
BOOST_TEST(type::instances == 0);
}
try {
boost::allocate_unique<type[][2]>(creator<type>(), 3);
BOOST_ERROR("allocate_unique did not throw");
} catch (...) {
BOOST_TEST(type::instances == 0);
}
try {
boost::allocate_unique<type[6]>(creator<>());
BOOST_ERROR("allocate_unique did not throw");
} catch (...) {
BOOST_TEST(type::instances == 0);
}
try {
boost::allocate_unique<type[3][2]>(creator<>());
BOOST_ERROR("allocate_unique did not throw");
} catch (...) {
BOOST_TEST(type::instances == 0);
}
try {
boost::allocate_unique_noinit<type[]>(creator<>(), 6);
BOOST_ERROR("allocate_unique_noinit did not throw");
} catch (...) {
BOOST_TEST(type::instances == 0);
}
try {
boost::allocate_unique_noinit<type[][2]>(creator<>(), 3);
BOOST_ERROR("allocate_unique_noinit did not throw");
} catch (...) {
BOOST_TEST(type::instances == 0);
}
try {
boost::allocate_unique_noinit<type[6]>(creator<>());
BOOST_ERROR("allocate_unique_noinit did not throw");
} catch (...) {
BOOST_TEST(type::instances == 0);
}
try {
boost::allocate_unique_noinit<type[3][2]>(creator<>());
BOOST_ERROR("allocate_unique_noinit did not throw");
} catch (...) {
BOOST_TEST(type::instances == 0);
}
return boost::report_errors();
}
#else
int main()
{
return 0;
}
#endif

View File

@ -0,0 +1,98 @@
/*
Copyright 2019 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#include <boost/config.hpp>
#if (!defined(BOOST_LIBSTDCXX_VERSION) || \
BOOST_LIBSTDCXX_VERSION >= 48000) && \
!defined(BOOST_NO_CXX11_SMART_PTR)
#include <boost/smart_ptr/allocate_unique.hpp>
#include <boost/core/lightweight_test.hpp>
template<class T = void>
struct creator {
typedef T value_type;
typedef T* pointer;
template<class U>
struct rebind {
typedef creator<U> other;
};
creator() { }
template<class U>
creator(const creator<U>&) { }
T* allocate(std::size_t size) {
return static_cast<T*>(::operator new(sizeof(T) * size));
}
void deallocate(T* ptr, std::size_t) {
::operator delete(ptr);
}
};
template<class T, class U>
inline bool
operator==(const creator<T>&, const creator<U>&)
{
return true;
}
template<class T, class U>
inline bool
operator!=(const creator<T>&, const creator<U>&)
{
return false;
}
int main()
{
{
std::unique_ptr<int[],
boost::alloc_deleter<int[], creator<int> > > result =
boost::allocate_unique<int[]>(creator<int>(), 4, 1);
BOOST_TEST(result[0] == 1);
BOOST_TEST(result[1] == 1);
BOOST_TEST(result[2] == 1);
BOOST_TEST(result[3] == 1);
}
{
std::unique_ptr<int[],
boost::alloc_deleter<int[4], creator<int> > > result =
boost::allocate_unique<int[4]>(creator<int>(), 1);
BOOST_TEST(result[0] == 1);
BOOST_TEST(result[1] == 1);
BOOST_TEST(result[2] == 1);
BOOST_TEST(result[3] == 1);
}
{
std::unique_ptr<const int[],
boost::alloc_deleter<const int[], creator<> > > result =
boost::allocate_unique<const int[]>(creator<>(), 4, 1);
BOOST_TEST(result[0] == 1);
BOOST_TEST(result[1] == 1);
BOOST_TEST(result[2] == 1);
BOOST_TEST(result[3] == 1);
}
{
std::unique_ptr<const int[],
boost::alloc_deleter<const int[4], creator<> > > result =
boost::allocate_unique<const int[4]>(creator<>(), 1);
BOOST_TEST(result[0] == 1);
BOOST_TEST(result[1] == 1);
BOOST_TEST(result[2] == 1);
BOOST_TEST(result[3] == 1);
}
return boost::report_errors();
}
#else
int main()
{
return 0;
}
#endif

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