mirror of
				https://github.com/boostorg/smart_ptr.git
				synced 2025-10-31 15:51:38 +01:00 
			
		
		
		
	Compare commits
	
		
			75 Commits
		
	
	
		
			feature/cm
			...
			feature/de
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 7b9a969215 | ||
|  | 91cd83e5bf | ||
|  | 2fdb8c4b0a | ||
|  | e806b53433 | ||
|  | e0c7bd9a7e | ||
|  | 766ab05a12 | ||
|  | 05cbefd28e | ||
|  | bfbdf4f45f | ||
|  | 169c0cd52a | ||
|  | 7d70691a16 | ||
|  | 90c27d7cfa | ||
|  | 43d1fe12c5 | ||
|  | a2749dddb4 | ||
|  | a71e62146c | ||
|  | 274ec17836 | ||
|  | a7341070f1 | ||
|  | a6323354cd | ||
|  | f788448101 | ||
|  | 283f2d2a11 | ||
|  | 034f94617d | ||
|  | 6a5f67b3a2 | ||
|  | dcd3c8ef80 | ||
|  | bb2a453ff6 | ||
|  | e56eec70ca | ||
|  | 60c26acab8 | ||
|  | 00f6b5dcb0 | ||
|  | 6195ae1eb0 | ||
|  | 30291c406a | ||
|  | 610f19f247 | ||
|  | 876d40a9ab | ||
|  | e4d642c46a | ||
|  | 3dffa64f58 | ||
|  | af92bd89ef | ||
|  | 4742143605 | ||
|  | 872bf10347 | ||
|  | c0ae9b3728 | ||
|  | 1298c2e8e5 | ||
|  | d593061b15 | ||
|  | 5072045f12 | ||
|  | 442e179920 | ||
|  | 9544a8cb91 | ||
|  | 5823d6bcc9 | ||
|  | f56e609757 | ||
|  | 8df63a3d0e | ||
|  | 4b6cb1223b | ||
|  | 719e819570 | ||
|  | a571b3a250 | ||
|  | f17c5e8e3b | ||
|  | e306b30dcf | ||
|  | b6b49ef591 | ||
|  | 2122c7753c | ||
|  | 7c76fb385d | ||
|  | 372fac679b | ||
|  | e3adcaed1e | ||
|  | 016e682af6 | ||
|  | 78e095d761 | ||
|  | eb8a91cb46 | ||
|  | 513cd15378 | ||
|  | 7bfa6a1f3d | ||
|  | 8120bb44cb | ||
|  | 18974ea2db | ||
|  | 2a4aca403a | ||
|  | 4d0d81477c | ||
|  | 1725e26f70 | ||
|  | 47fffaf11c | ||
|  | 7f0323a347 | ||
|  | 6d8ea0f0c4 | ||
|  | d10299159a | ||
|  | adcab0e313 | ||
|  | 4fbb9ff076 | ||
|  | 8ccb36dfcf | ||
|  | fde2e91443 | ||
|  | aa1341a6a2 | ||
|  | 053779f3ee | ||
|  | 51d8167fbf | 
							
								
								
									
										131
									
								
								.travis.yml
									
									
									
									
									
								
							
							
						
						
									
										131
									
								
								.travis.yml
									
									
									
									
									
								
							| @@ -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,19 @@ 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: linux | ||||
|       compiler: g++-4.4 | ||||
| @@ -107,7 +118,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 +126,36 @@ 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 | ||||
|       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 +167,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 +176,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 +186,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 +203,6 @@ matrix: | ||||
|             - clang-3.6 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - llvm-toolchain-precise-3.6 | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: clang++-3.7 | ||||
| @@ -177,7 +213,6 @@ matrix: | ||||
|             - clang-3.7 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - llvm-toolchain-precise-3.7 | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: clang++-3.8 | ||||
| @@ -186,10 +221,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 +231,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 +243,6 @@ matrix: | ||||
|             - clang-4.0 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - llvm-toolchain-trusty-4.0 | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: clang++-5.0 | ||||
| @@ -223,7 +253,6 @@ matrix: | ||||
|             - clang-5.0 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - llvm-toolchain-trusty-5.0 | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: clang++-6.0 | ||||
| @@ -234,7 +263,6 @@ matrix: | ||||
|             - clang-6.0 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - llvm-toolchain-trusty-6.0 | ||||
|  | ||||
|     - os: linux | ||||
|       compiler: clang++-7 | ||||
| @@ -245,21 +273,45 @@ 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 | ||||
|       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 +320,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 +332,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 +352,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 +384,9 @@ 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 update # no --jobs 3 on non-amd64 | ||||
|   - cp -r $TRAVIS_BUILD_DIR/* libs/smart_ptr | ||||
|   - ./bootstrap.sh | ||||
|   - ./b2 headers | ||||
|   | ||||
| @@ -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() | ||||
|   | ||||
							
								
								
									
										24
									
								
								appveyor.yml
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								appveyor.yml
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | ||||
| # Copyright 2016-2018 Peter Dimov | ||||
| # Copyright 2016-2019 Peter Dimov | ||||
| # Distributed under the Boost Software License, Version 1.0. | ||||
| # (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt) | ||||
|  | ||||
| @@ -14,28 +14,36 @@ branches: | ||||
|  | ||||
| environment: | ||||
|   matrix: | ||||
|     - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013 | ||||
|       TOOLSET: msvc-9.0,msvc-10.0,msvc-11.0,msvc-12.0 | ||||
|     - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 | ||||
|       TOOLSET: msvc-14.0 | ||||
|       TOOLSET: msvc-9.0,msvc-10.0,msvc-11.0 | ||||
|     - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 | ||||
|       TOOLSET: msvc-12.0,msvc-14.0 | ||||
|       ADDRMD: 32,64 | ||||
|     - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 | ||||
|       TOOLSET: msvc-14.1 | ||||
|       CXXSTD: 14,17 | ||||
|       ADDRMD: 32,64 | ||||
|     - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013 | ||||
|     - 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 | ||||
|       CXXSTD: 03,11,14,1z | ||||
|     - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013 | ||||
|     - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 | ||||
|       ADDPATH: C:\cygwin64\bin; | ||||
|       TOOLSET: gcc | ||||
|       CXXSTD: 03,11,14,1z | ||||
|     - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013 | ||||
|     - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 | ||||
|       ADDPATH: C:\mingw\bin; | ||||
|       TOOLSET: gcc | ||||
|       CXXSTD: 03,11,14,1z | ||||
|     - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013 | ||||
|     - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 | ||||
|       ADDPATH: C:\mingw-w64\x86_64-7.2.0-posix-seh-rt_v5-rev1\mingw64\bin; | ||||
|       TOOLSET: gcc | ||||
|       CXXSTD: 03,11,14,1z | ||||
|   | ||||
| @@ -5,8 +5,6 @@ | ||||
| # See accompanying file LICENSE_1_0.txt or copy at | ||||
| # http://www.boost.org/LICENSE_1_0.txt | ||||
|  | ||||
| project doc/smart_ptr ; | ||||
|  | ||||
| import asciidoctor ; | ||||
|  | ||||
| html smart_ptr.html : smart_ptr.adoc ; | ||||
|   | ||||
| @@ -19,6 +19,8 @@ Greg Colvin, Beman Dawes, Peter Dimov, Glen Fernandes | ||||
|  | ||||
| include::smart_ptr/introduction.adoc[] | ||||
|  | ||||
| include::smart_ptr/changelog.adoc[] | ||||
|  | ||||
| include::smart_ptr/scoped_ptr.adoc[] | ||||
|  | ||||
| include::smart_ptr/scoped_array.adoc[] | ||||
| @@ -31,8 +33,12 @@ 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[] | ||||
|   | ||||
							
								
								
									
										318
									
								
								doc/smart_ptr/allocate_unique.adoc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										318
									
								
								doc/smart_ptr/allocate_unique.adoc
									
									
									
									
									
										Normal 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. | ||||
							
								
								
									
										29
									
								
								doc/smart_ptr/changelog.adoc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								doc/smart_ptr/changelog.adoc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | ||||
| //// | ||||
| Copyright 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 | ||||
| //// | ||||
|  | ||||
| [#changelog] | ||||
| # Revision History | ||||
| :toc: | ||||
| :toc-title: | ||||
| :idprefix: changelog_ | ||||
|  | ||||
| ## 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` | ||||
							
								
								
									
										89
									
								
								doc/smart_ptr/enable_shared_from.adoc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								doc/smart_ptr/enable_shared_from.adoc
									
									
									
									
									
										Normal 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. | ||||
| @@ -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. | ||||
|   | ||||
| @@ -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. | ||||
|   | ||||
| @@ -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 | ||||
| @@ -39,6 +41,7 @@ In addition, the library contains the following supporting utility functions and | ||||
|  | ||||
| * `<<make_shared,make_shared>>`, a factory function for creating objects that returns 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`; | ||||
| * `<<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; | ||||
|   | ||||
| @@ -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> | ||||
|   | ||||
| @@ -78,12 +78,13 @@ namespace boost { | ||||
| ``` | ||||
| intrusive_ref_counter() noexcept; | ||||
| ``` | ||||
| :: | ||||
| ``` | ||||
| intrusive_ref_counter(const intrusive_ref_counter&) noexcept; | ||||
| ``` | ||||
| :: | ||||
| Postconditions::: `use_count() == 0`. | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Postconditions:: `use_count() == 0`. | ||||
|  | ||||
| NOTE: The pointer to the constructed object is expected to be passed to | ||||
| `intrusive_ptr` constructor, assignment operator or `reset` method, which | ||||
| @@ -94,8 +95,10 @@ would increment the reference counter. | ||||
| ``` | ||||
| ~intrusive_ref_counter(); | ||||
| ``` | ||||
| :: | ||||
| Effects::: Destroys the counter object. | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Effects:: Destroys the counter object. | ||||
|  | ||||
| NOTE: The destructor is protected so that the object can only be destroyed | ||||
| through the `Derived` class. | ||||
| @@ -105,16 +108,20 @@ through the `Derived` class. | ||||
| ``` | ||||
| intrusive_ref_counter& operator=(const intrusive_ref_counter& v) noexcept; | ||||
| ``` | ||||
| :: | ||||
| Effects::: Does nothing, reference counter is not modified. | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Effects:: Does nothing, reference counter is not modified. | ||||
|  | ||||
| ### use_count | ||||
|  | ||||
| ``` | ||||
| unsigned int use_count() const noexcept; | ||||
| ``` | ||||
| :: | ||||
| Returns::: The current value of the reference counter. | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: The current value of the reference counter. | ||||
|  | ||||
| NOTE: The returned value may not be actual in multi-threaded applications. | ||||
|  | ||||
| @@ -127,8 +134,10 @@ template<class Derived, class CounterPolicy> | ||||
|   void intrusive_ptr_add_ref( | ||||
|     const intrusive_ref_counter<Derived, CounterPolicy>* p) noexcept; | ||||
| ``` | ||||
| :: | ||||
| Effects::: Increments the reference counter. | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Effects:: Increments the reference counter. | ||||
|  | ||||
| ### intrusive_ptr_release | ||||
|  | ||||
| @@ -137,6 +146,8 @@ template<class Derived, class CounterPolicy> | ||||
|   void intrusive_ptr_release( | ||||
|     const intrusive_ref_counter<Derived, CounterPolicy>* p) noexcept; | ||||
| ``` | ||||
| :: | ||||
| Effects::: Decrements the reference counter. If the reference counter reaches | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Effects:: Decrements the reference counter. If the reference counter reaches | ||||
| 0, calls `delete static_cast<const Derived*>(p)`. | ||||
|   | ||||
| @@ -716,4 +716,3 @@ template<class D, class T> | ||||
| * {blank} | ||||
| + | ||||
| Returns:: If `*this` owns a `shared_ptr` instance `p`, `get_deleter<D>( p )`, otherwise 0. | ||||
|  | ||||
|   | ||||
| @@ -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> | ||||
|   | ||||
| @@ -55,43 +55,43 @@ types. | ||||
| [subs=+quotes] | ||||
| ``` | ||||
| namespace boost { | ||||
|   `// only if T is not an array type` | ||||
|   `// T is not an array` | ||||
|   template<class T, class... Args> | ||||
|     shared_ptr<T> make_shared(Args&&... args); | ||||
|   template<class T, class A, class... Args> | ||||
|     shared_ptr<T> allocate_shared(const A& a, Args&&... args); | ||||
|  | ||||
|   `// only if T is an array type of the form U[]` | ||||
|   `// T is an array of unknown bounds` | ||||
|   template<class T> | ||||
|     shared_ptr<T> make_shared(std::size_t n); | ||||
|   template<class T, class A> | ||||
|     shared_ptr<T> allocate_shared(const A& a, std::size_t n); | ||||
|  | ||||
|   `// only if T is an array type of the form U[N]` | ||||
|   `// T is an array of known bounds` | ||||
|   template<class T> | ||||
|     shared_ptr<T> make_shared(); | ||||
|   template<class T, class A> | ||||
|     shared_ptr<T> allocate_shared(const A& a); | ||||
|  | ||||
|   `// only if T is an array type of the form U[]` | ||||
|   `// T is an array of unknown bounds` | ||||
|   template<class T> shared_ptr<T> | ||||
|     make_shared(std::size_t n, const remove_extent_t<T>& v); | ||||
|   template<class T, class A> shared_ptr<T> | ||||
|     allocate_shared(const A& a, std::size_t n, const remove_extent_t<T>& v); | ||||
|  | ||||
|   `// only if T is an array type of the form U[N]` | ||||
|   `// T is an array of known bounds` | ||||
|   template<class T> | ||||
|     shared_ptr<T> make_shared(const remove_extent_t<T>& v); | ||||
|   template<class T, class A> | ||||
|     shared_ptr<T> allocate_shared(const A& a, const remove_extent_t<T>& v); | ||||
|  | ||||
|   `// only if T is not an array type of the form U[]` | ||||
|   `// T is not an array of unknown bounds` | ||||
|   template<class T> | ||||
|     shared_ptr<T> make_shared_noinit(); | ||||
|   template<class T, class A> | ||||
|     shared_ptr<T> allocate_shared_noinit(const A& a); | ||||
|  | ||||
|   `// only if T is an array type of the form U[N]` | ||||
|   `// T is an array of unknown bounds` | ||||
|   template<class T> | ||||
|     shared_ptr<T> make_shared_noinit(std::size_t n); | ||||
|   template<class T, class A> | ||||
| @@ -144,7 +144,7 @@ perform this initialization via the expression | ||||
| `std::allocator_traits<A2>::construct(a2, p, expr)` (where | ||||
| `_expr_` is `v` or `std::forward<Args>(args)\...)` respectively), `p` | ||||
| points to storage suitable to hold an object of type `U`, and `a2` of | ||||
| type `A2` is a rebound copy `a` such that its `value_type` is `U`. | ||||
| type `A2` is a potentially rebound copy of `a`. | ||||
| * When a (sub)object of non-array type `U` is specified to be | ||||
| default-initialized, `make_shared_noinit` and `allocate_shared_noinit` shall | ||||
| perform this initialization via the expression `::new(p) U`, where | ||||
| @@ -158,7 +158,7 @@ storage suitable to hold an object of type `U`. | ||||
| value-initialized, `allocate_shared` shall perform this initialization via the | ||||
| expression `std::allocator_traits<A2>::construct(a2, p)`, where | ||||
| `p` points to storage suitable to hold an object of type `U` and `a2` of | ||||
| type `A2` is a rebound copy of `a` such that its value_type is `U`. | ||||
| type `A2` is a potentially rebound copy of `a`. | ||||
| * Array elements are initialized in ascending order of their addresses. | ||||
| * When the lifetime of the object managed by the return value ends, or when | ||||
| the initialization of an array element throws an exception, the initialized | ||||
| @@ -174,17 +174,17 @@ the reference counts. | ||||
| template<class T, class... Args> | ||||
|   shared_ptr<T> make_shared(Args&&... args); | ||||
| ``` | ||||
| :: | ||||
| ``` | ||||
| template<class T, class A, class... Args> | ||||
|   shared_ptr<T> allocate_shared(const A& a, Args&&... args); | ||||
| ``` | ||||
| :: | ||||
| Remarks::: These overloads shall only participate in overload resolution when | ||||
| `T` is not an array type. | ||||
| Returns::: A `shared_ptr` to an object of type `T`, constructed from | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Constraints:: `T` is not an array. | ||||
| Returns:: A `shared_ptr` to an object of type `T`, constructed from | ||||
| `args\...`. | ||||
| Examples::: | ||||
| Examples:: | ||||
| * `auto p = make_shared<int>();` | ||||
| * `auto p = make_shared<std::vector<int> >(16, 1);` | ||||
|  | ||||
| @@ -192,17 +192,17 @@ Examples::: | ||||
| template<class T> | ||||
|   shared_ptr<T> make_shared(std::size_t n); | ||||
| ``` | ||||
| :: | ||||
| ``` | ||||
| template<class T, class A> | ||||
|   shared_ptr<T> allocate_shared(const A& a, std::size_t n); | ||||
| ``` | ||||
| :: | ||||
| Remarks::: These overloads shall only participate in overload resolution when | ||||
| `T` is an array type of the form `U[]`. | ||||
| Returns::: A `shared_ptr` to a sequence of `n` value-initialized objects of | ||||
| type `U`. | ||||
| Examples::: | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Constraints:: `T` is an array of unknown bounds. | ||||
| Returns:: A `shared_ptr` to a sequence of `n` value-initialized objects of | ||||
| type `remove_extent_t<T>`. | ||||
| Examples:: | ||||
| * `auto p = make_shared<double[]>(1024);` | ||||
| * `auto p = make_shared<double[][2][2]>(6);` | ||||
|  | ||||
| @@ -210,17 +210,17 @@ Examples::: | ||||
| template<class T> | ||||
|   shared_ptr<T> make_shared(); | ||||
| ``` | ||||
| :: | ||||
| ``` | ||||
| template<class T, class A> | ||||
|   shared_ptr<T> allocate_shared(const A& a); | ||||
| ``` | ||||
| :: | ||||
| Remarks::: These overloads shall only participate in overload resolution when | ||||
| `T` is an array type of the form `U[N]`. | ||||
| Returns::: A `shared_ptr` to a sequence of `N` value-initialized objects of | ||||
| type `U`. | ||||
| Examples::: | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Constraints:: `T` is an array of known bounds. | ||||
| Returns:: A `shared_ptr` to a sequence of `extent_v<T>` value-initialized | ||||
| objects of type `remove_extent_t<T>`. | ||||
| Examples:: | ||||
| * `auto p = make_shared<double[1024]>();` | ||||
| * `auto p = make_shared<double[6][2][2]>();` | ||||
|  | ||||
| @@ -228,17 +228,17 @@ Examples::: | ||||
| template<class T> shared_ptr<T> | ||||
|   make_shared(std::size_t n, const remove_extent_t<T>& v); | ||||
| ``` | ||||
| :: | ||||
| ``` | ||||
| template<class T, class A> shared_ptr<T> | ||||
|   allocate_shared(const A& a, std::size_t n, const remove_extent_t<T>& v); | ||||
| ``` | ||||
| :: | ||||
| Remarks::: These overloads shall only participate in overload resolution when | ||||
| `T` is an array type of the form `U[]`. | ||||
| Returns::: A `shared_ptr` to a sequence of `n` objects of type `U`, each | ||||
| initialized to `v`. | ||||
| Examples::: | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Constraints:: `T` is an array of unknown bounds. | ||||
| Returns:: A `shared_ptr` to a sequence of `n` objects of type | ||||
| `remove_extent_t<T>`, each initialized to `v`. | ||||
| Examples:: | ||||
| * `auto p = make_shared<double[]>(1024, 1.0);` | ||||
| * `auto p = make_shared<double[][2]>(6, {1.0, 0.0});` | ||||
| * `auto p = make_shared<std::vector<int>[]>(4, {1, 2});` | ||||
| @@ -247,17 +247,17 @@ Examples::: | ||||
| template<class T> | ||||
|   shared_ptr<T> make_shared(const remove_extent_t<T>& v); | ||||
| ``` | ||||
| :: | ||||
| ``` | ||||
| template<class T, class A> | ||||
|   shared_ptr<T> allocate_shared(const A& a, const remove_extent_t<T>& v); | ||||
| ``` | ||||
| :: | ||||
| Remarks::: These overloads shall only participate in overload resolution when | ||||
| `T` is an array type of the form `U[N]`. | ||||
| Returns::: A `shared_ptr` to a sequence of `N` objects of type `U`, each | ||||
| initialized to `v`. | ||||
| Examples::: | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Constraints:: `T` is an array of known bounds. | ||||
| Returns:: A `shared_ptr` to a sequence of `extent_v<T>` objects of type | ||||
| `remove_extent_t<T>`, each initialized to `v`. | ||||
| Examples:: | ||||
| * `auto p = make_shared<double[1024]>(1.0);` | ||||
| * `auto p = make_shared<double[6][2]>({1.0, 0.0});` | ||||
| * `auto p = make_shared<std::vector<int>[4]>({1, 2});` | ||||
| @@ -266,30 +266,31 @@ Examples::: | ||||
| template<class T> | ||||
|   shared_ptr<T> make_shared_noinit(); | ||||
| ``` | ||||
| :: | ||||
| ``` | ||||
| template<class T, class A> | ||||
|   shared_ptr<T> allocate_shared_noinit(const A& a); | ||||
| ``` | ||||
| :: | ||||
| Remarks::: These overloads shall only participate in overload resolution when | ||||
| `T` is not an array type, or an array type of the `U[N]`. | ||||
| Returns::: A `shared_ptr` to a default-initialized object of type `T`, or a | ||||
| sequence of `N` default-initialized objects of type `U`, respectively. | ||||
| Example::: `auto p = make_shared_noinit<double[1024]>();` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Constraints:: `T` is not an array, or is an array of known bounds. | ||||
| Returns:: A `shared_ptr` to a default-initialized object of type `T`, or a | ||||
| sequence of `extent_v<T>` default-initialized objects of type | ||||
| `remove_extent_t<T>`, respectively. | ||||
| Example:: `auto p = make_shared_noinit<double[1024]>();` | ||||
|  | ||||
| ``` | ||||
| template<class T> | ||||
|   shared_ptr<T> make_shared_noinit(std::size_t n); | ||||
| ``` | ||||
| :: | ||||
| ``` | ||||
| template<class T, class A> | ||||
|   shared_ptr<T> allocate_shared_noinit(const A& a, std::size_t n); | ||||
| ``` | ||||
| :: | ||||
| Remarks::: These overloads shall only participate in overload resolution when | ||||
| `T` is an array type of the form `U[]`. | ||||
| Returns::: A `shared_ptr` to a sequence of `_n_` default-initialized objects | ||||
| of type `U`. | ||||
| Example::: `auto p = make_shared_noinit<double[]>(1024);` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Constraints:: `T` is an array of unknown bounds. | ||||
| Returns:: A `shared_ptr` to a sequence of `_n_` default-initialized objects | ||||
| of type `remove_extent_t<T>`. | ||||
| Example:: `auto p = make_shared_noinit<double[]>(1024);` | ||||
|   | ||||
| @@ -40,23 +40,23 @@ feature with `std::make_unique`. | ||||
| [subs=+quotes] | ||||
| ``` | ||||
| namespace boost { | ||||
|   `// only if T is not an array type` | ||||
|   `// T is not an array` | ||||
|   template<class T, class... Args> | ||||
|     std::unique_ptr<T> make_unique(Args&&... args); | ||||
|  | ||||
|   `// only if T is not an array type` | ||||
|   `// T is not an array` | ||||
|   template<class T> | ||||
|     std::unique_ptr<T> make_unique(remove_reference_t<T>&& v); | ||||
|     std::unique_ptr<T> make_unique(type_identity_t<T>&& v); | ||||
|  | ||||
|   `// only if T is an array type of the form U[]` | ||||
|   `// T is an array of unknown bounds` | ||||
|   template<class T> | ||||
|     std::unique_ptr<T> make_unique(std::size_t n); | ||||
|  | ||||
|   `// only if T is not an array type` | ||||
|   `// T is not an array` | ||||
|   template<class T> | ||||
|     std::unique_ptr<T> make_unique_noinit(); | ||||
|  | ||||
|   `// only if T is an array type of the form U[]` | ||||
|   `// T is an array of unknown bounds` | ||||
|   template<class T> | ||||
|     std::unique_ptr<T> make_unique_noinit(std::size_t n); | ||||
| } | ||||
| @@ -68,48 +68,53 @@ namespace boost { | ||||
| template<class T, class... Args> | ||||
|   std::unique_ptr<T> make_unique(Args&&... args); | ||||
| ``` | ||||
| :: | ||||
| Remarks::: These overloads shall only participate in overload resolution when | ||||
| `T` is not an array type. | ||||
| Returns::: `std::unique_ptr<T>(new T(std::forward<Args>(args)\...)`. | ||||
| Example::: `auto p = make_unique<int>();` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Constraints:: `T` is not an array. | ||||
| Returns:: `std::unique_ptr<T>(new T(std::forward<Args>(args)\...)`. | ||||
| Example:: `auto p = make_unique<int>();` | ||||
|  | ||||
| ``` | ||||
| template<class T> | ||||
|   std::unique_ptr<T> make_unique(remove_reference_t<T>&& v); | ||||
|   std::unique_ptr<T> make_unique(type_identity_t<T>&& v); | ||||
| ``` | ||||
| :: | ||||
| Remarks::: These overloads shall only participate in overload resolution when | ||||
| `T` is not an array type. | ||||
| Returns::: `std::unique_ptr<T>(new T(std::move(v))`. | ||||
| Example::: `auto p = make_unique<std::vector<int> >({1, 2});` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Constraints:: `T` is not an array. | ||||
| Returns:: `std::unique_ptr<T>(new T(std::move(v))`. | ||||
| Example:: `auto p = make_unique<std::vector<int> >({1, 2});` | ||||
|  | ||||
| ``` | ||||
| template<class T> | ||||
|   std::unique_ptr<T> make_unique(std::size_t n); | ||||
| ``` | ||||
| :: | ||||
| Remarks::: These overloads shall only participate in overload resolution when | ||||
| `T` is an array type of the form `U[]`. | ||||
| Returns::: `std::unique_ptr<U[]>(new U[n]())`. | ||||
| Example::: `auto p = make_unique<double[]>(1024);` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Constraints:: `T` is an array of unknown bounds. | ||||
| Returns:: `std::unique_ptr<T>(new remove_extent_t<T>[n]())`. | ||||
| Example:: `auto p = make_unique<double[]>(1024);` | ||||
|  | ||||
| ``` | ||||
| template<class T> | ||||
|   std::unique_ptr<T> make_unique_noinit(); | ||||
| ``` | ||||
| :: | ||||
| Remarks::: These overloads shall only participate in overload resolution when | ||||
| `T` is not an array type. | ||||
| Returns::: `std::unique_ptr<T>(new T)`. | ||||
| Example::: `auto p = make_unique_noinit<double[1024]>();` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Constraints:: `T` is not an array. | ||||
| Returns:: `std::unique_ptr<T>(new T)`. | ||||
| Example:: `auto p = make_unique_noinit<std::array<double, 1024> >();` | ||||
|  | ||||
| ``` | ||||
| template<class T> | ||||
|   std::unique_ptr<T> make_unique_noinit(std::size_t n); | ||||
| ``` | ||||
| :: | ||||
| Remarks::: These overloads shall only participate in overload resolution when | ||||
| `T` is an array type of the form `U[]`. | ||||
| Returns::: `std::unique_ptr<U[]>(new U[n])`. | ||||
| Example::: `auto p = make_unique_noinit<double[]>(1024);` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Constraints:: `T` is an array of unknown bounds. | ||||
| Returns:: `std::unique_ptr<T>(new remove_extent_t<T>[n])`. | ||||
| Example:: `auto p = make_unique_noinit<double[]>(1024);` | ||||
|   | ||||
| @@ -78,23 +78,29 @@ namespace boost { | ||||
| ``` | ||||
| template<class T, class U> T* static_pointer_cast(U* p) noexcept; | ||||
| ``` | ||||
| :: | ||||
| Returns::: `static_cast<T*>(p)` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: `static_cast<T*>(p)` | ||||
|  | ||||
| ``` | ||||
| template<class T, class U> std::shared_ptr<T> | ||||
|   static_pointer_cast(const std::shared_ptr<U>& p) noexcept; | ||||
| ``` | ||||
| :: | ||||
| Returns::: `std::static_pointer_cast<T>(p)` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: `std::static_pointer_cast<T>(p)` | ||||
|  | ||||
| ``` | ||||
| template<class T, class U> std::unique_ptr<T> | ||||
|   static_pointer_cast(std::unique_ptr<U>&& p) noexcept; | ||||
| ``` | ||||
| :: | ||||
| Requires::: The expression `static_cast<T*>((U*)0)` must be well-formed. | ||||
| Returns::: `std::unique_ptr<T>(static_cast<typename | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Requires:: The expression `static_cast<T*>((U*)0)` must be well-formed. | ||||
| Returns:: `std::unique_ptr<T>(static_cast<typename | ||||
| std::unique_ptr<T>::element_type*>(p.release()))`. | ||||
|  | ||||
| CAUTION: The seemingly equivalent expression | ||||
| @@ -106,25 +112,31 @@ undefined behavior, attempting to delete the same object twice. | ||||
| ``` | ||||
| template<class T, class U> T* dynamic_pointer_cast(U* p) noexcept; | ||||
| ``` | ||||
| :: | ||||
| Returns::: `dynamic_cast<T*>(p)` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: `dynamic_cast<T*>(p)` | ||||
|  | ||||
| ``` | ||||
| template<class T, class U> std::shared_ptr<T> | ||||
|   dynamic_pointer_cast(const std::shared_ptr<U>& p) noexcept; | ||||
| ``` | ||||
| :: | ||||
| Returns::: `std::dynamic_pointer_cast<T>(p)` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: `std::dynamic_pointer_cast<T>(p)` | ||||
|  | ||||
| ``` | ||||
| template<class T, class U> std::unique_ptr<T> | ||||
|   dynamic_pointer_cast(std::unique_ptr<U>&& p) noexcept; | ||||
| ``` | ||||
| :: | ||||
| Requires::: | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Requires:: | ||||
| * The expression `static_cast<T*>((U*)0)` must be well-formed. | ||||
| * `T` must have a virtual destructor. | ||||
| Returns::: | ||||
| Returns:: | ||||
| * When `dynamic_cast<typename std::unique_ptr<T>::element_type*>(p.get())` | ||||
| returns a non-zero value, `std::unique_ptr<T>(dynamic_cast<typename | ||||
| std::unique_ptr<T>::element_type*>(p.release()));`. | ||||
| @@ -135,23 +147,29 @@ std::unique_ptr<T>::element_type*>(p.release()));`. | ||||
| ``` | ||||
| template<class T, class U> T* const_pointer_cast(U* p) noexcept; | ||||
| ``` | ||||
| :: | ||||
| Returns::: `const_cast<T*>(p)` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: `const_cast<T*>(p)` | ||||
|  | ||||
| ``` | ||||
| template<class T, class U> std::shared_ptr<T> | ||||
|   const_pointer_cast(const std::shared_ptr<U>& p) noexcept; | ||||
| ``` | ||||
| :: | ||||
| Returns::: `std::const_pointer_cast<T>(p)` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: `std::const_pointer_cast<T>(p)` | ||||
|  | ||||
| ``` | ||||
| template<class T, class U> std::unique_ptr<T> | ||||
|   const_pointer_cast(std::unique_ptr<U>&& p) noexcept; | ||||
| ``` | ||||
| :: | ||||
| Requires::: The expression `const_cast<T*>((U*)0)` must be well-formed. | ||||
| Returns::: `std::unique_ptr<T>(const_cast<typename | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Requires:: The expression `const_cast<T*>((U*)0)` must be well-formed. | ||||
| Returns:: `std::unique_ptr<T>(const_cast<typename | ||||
| std::unique_ptr<T>::element_type*>(p.release()))`. | ||||
|  | ||||
| ### reinterpret_pointer_cast | ||||
| @@ -159,23 +177,29 @@ std::unique_ptr<T>::element_type*>(p.release()))`. | ||||
| ``` | ||||
| template<class T, class U> T* reinterpret_pointer_cast(U* p) noexcept; | ||||
| ``` | ||||
| :: | ||||
| Returns::: `reinterpret_cast<T*>(p)` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: `reinterpret_cast<T*>(p)` | ||||
|  | ||||
| ``` | ||||
| template<class T, class U> std::shared_ptr<T> | ||||
|   reinterpret_pointer_cast(const std::shared_ptr<U>& p) noexcept; | ||||
| ``` | ||||
| :: | ||||
| Returns::: `std::reinterpret_pointer_cast<T>(p)` | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: `std::reinterpret_pointer_cast<T>(p)` | ||||
|  | ||||
| ``` | ||||
| template<class T, class U> std::unique_ptr<T> | ||||
|   reinterpret_pointer_cast(std::unique_ptr<U>&& p) noexcept; | ||||
| ``` | ||||
| :: | ||||
| Requires::: The expression `reinterpret_cast<T*>((U*)0)` must be well-formed. | ||||
| Returns::: `std::unique_ptr<T>(reinterpret_cast<typename | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Requires:: The expression `reinterpret_cast<T*>((U*)0)` must be well-formed. | ||||
| Returns:: `std::unique_ptr<T>(reinterpret_cast<typename | ||||
| std::unique_ptr<T>::element_type*>(p.release()))`. | ||||
|  | ||||
| ## Example | ||||
| @@ -210,4 +234,4 @@ int main() | ||||
|  | ||||
|   delete ptr; | ||||
| } | ||||
| ``` | ||||
| ``` | ||||
|   | ||||
| @@ -105,42 +105,50 @@ Type:: Provides the type of the stored pointer. | ||||
| ``` | ||||
| explicit shared_array(T* p = 0); | ||||
| ``` | ||||
| :: | ||||
| Effects::: Constructs a `shared_array`, storing a copy of `p`, which must be a | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Effects:: Constructs a `shared_array`, storing a copy of `p`, which must be a | ||||
| pointer to an array that was allocated via a C++ `new[]` expression or be 0. | ||||
| Afterwards, the use count is 1 (even if `p == 0`; see `~shared_array`). | ||||
| Requires::: `T` is a complete type. | ||||
| Throws::: `std::bad_alloc`. If an exception is thrown, `delete[] p` is called. | ||||
| Requires:: `T` is a complete type. | ||||
| Throws:: `std::bad_alloc`. If an exception is thrown, `delete[] p` is called. | ||||
|  | ||||
| ``` | ||||
| template<class D> shared_array(T* p, D d); | ||||
| ``` | ||||
| :: | ||||
| Effects::: Constructs a `shared_array`, storing a copy of `p` and of `d`. | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Effects:: Constructs a `shared_array`, storing a copy of `p` and of `d`. | ||||
| Afterwards, the use count is 1. When the the time comes to delete the array | ||||
| pointed to by `p`, the object `d` is used in the statement `d(p)`. | ||||
| Requires::: | ||||
| Requires:: | ||||
| * `T` is a complete type. | ||||
| * The copy constructor and destructor of `D` must not throw. | ||||
| * Invoking the object `d` with parameter `p` must not throw. | ||||
| Throws::: `std::bad_alloc`. If an exception is thrown, `d(p)` is called. | ||||
| Throws:: `std::bad_alloc`. If an exception is thrown, `d(p)` is called. | ||||
|  | ||||
| ``` | ||||
| shared_array(const shared_array& v) noexcept; | ||||
| ``` | ||||
| :: | ||||
| Effects::: Constructs a `shared_array`, as if by storing a copy of the pointer | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Effects:: Constructs a `shared_array`, as if by storing a copy of the pointer | ||||
| stored in `v`. Afterwards, the use count for all copies is 1 more than the | ||||
| initial use count. | ||||
| Requires::: `T` is a complete type. | ||||
| Requires:: `T` is a complete type. | ||||
|  | ||||
| ### Destructor | ||||
|  | ||||
| ``` | ||||
| ~shared_array() noexcept; | ||||
| ``` | ||||
| :: | ||||
| Effects::: Decrements the use count. Then, if the use count is 0, deletes the | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Effects:: Decrements the use count. Then, if the use count is 0, deletes the | ||||
| array pointed to by the stored pointer. Note that `delete[]` on a pointer with | ||||
| a value of 0 is harmless.  | ||||
|  | ||||
| @@ -149,60 +157,70 @@ a value of 0 is harmless. | ||||
| ``` | ||||
| shared_array& operator=(const shared_array& v) noexcept; | ||||
| ``` | ||||
| :: | ||||
| Effects::: Constructs a new `shared_array` as described above, then replaces | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Effects:: Constructs a new `shared_array` as described above, then replaces | ||||
| this `shared_array` with the new one, destroying the replaced object. | ||||
| Requires::: `T` is a complete type. | ||||
| Returns::: `*this`. | ||||
| Requires:: `T` is a complete type. | ||||
| Returns:: `*this`. | ||||
|  | ||||
| ### reset | ||||
|  | ||||
| ``` | ||||
| void reset(T* p = 0); | ||||
| ``` | ||||
| :: | ||||
| Effects::: Constructs a new `shared_array` as described above, then replaces | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Effects:: Constructs a new `shared_array` as described above, then replaces | ||||
| this `shared_array` with the new one, destroying the replaced object. | ||||
| Requires::: `T` is a complete type. | ||||
| Throws::: `std::bad_alloc`. If an exception is thrown, `delete[] p` is called. | ||||
| Requires:: `T` is a complete type. | ||||
| Throws:: `std::bad_alloc`. If an exception is thrown, `delete[] p` is called. | ||||
|  | ||||
| ``` | ||||
| template<class D> void reset(T* p, D d); | ||||
| ``` | ||||
| :: | ||||
| Effects::: Constructs a new `shared_array` as described above, then replaces | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Effects:: Constructs a new `shared_array` as described above, then replaces | ||||
| this `shared_array` with the new one, destroying the replaced object. | ||||
| Requires::: | ||||
| Requires:: | ||||
| * `T` is a complete type. | ||||
| * The copy constructor of `D` must not throw. | ||||
| Throws::: `std::bad_alloc`. If an exception is thrown, `d(p)` is called. | ||||
| Throws:: `std::bad_alloc`. If an exception is thrown, `d(p)` is called. | ||||
|  | ||||
| ### Indexing | ||||
|  | ||||
| ``` | ||||
| T& operator[](std::ptrdiff_t n) const noexcept; | ||||
| ``` | ||||
| Returns::: A reference to element `n` of the array pointed to by the stored | ||||
| Returns:: A reference to element `n` of the array pointed to by the stored | ||||
| pointer. Behavior is undefined and almost certainly undesirable if the stored | ||||
| pointer is 0, or if `n` is less than 0 or is greater than or equal to the | ||||
| number of elements in the array. | ||||
| Requires::: `T` is a complete type. | ||||
| Requires:: `T` is a complete type. | ||||
|  | ||||
| ### get | ||||
|  | ||||
| ``` | ||||
| T* get() const noexcept; | ||||
| ``` | ||||
| :: | ||||
| Returns::: The stored pointer. | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: The stored pointer. | ||||
|  | ||||
| ### unique | ||||
|  | ||||
| ``` | ||||
| bool unique() const noexcept; | ||||
| ``` | ||||
| :: | ||||
| Returns::: `true` if no other `shared_array` is sharing ownership of the | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: `true` if no other `shared_array` is sharing ownership of the | ||||
| stored pointer, `false` otherwise. | ||||
|  | ||||
| ### use_count | ||||
| @@ -210,8 +228,10 @@ stored pointer, `false` otherwise. | ||||
| ``` | ||||
| long use_count() const noexcept; | ||||
| ``` | ||||
| :: | ||||
| Returns::: The number of `shared_array` objects sharing ownership of the | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: The number of `shared_array` objects sharing ownership of the | ||||
| stored pointer. | ||||
|  | ||||
| ### Conversions | ||||
| @@ -219,17 +239,21 @@ stored pointer. | ||||
| ``` | ||||
| explicit operator bool() const noexcept; | ||||
| ``` | ||||
| :: | ||||
| Returns::: `get() != 0`. | ||||
| Requires::: `T` is a complete type. | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: `get() != 0`. | ||||
| Requires:: `T` is a complete type. | ||||
|  | ||||
| ### swap | ||||
|  | ||||
| ``` | ||||
| void swap(shared_array<T>& b) noexcept; | ||||
| ``` | ||||
| :: | ||||
| Effects::: Exchanges the contents of the two smart pointers. | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Effects:: Exchanges the contents of the two smart pointers. | ||||
|  | ||||
| ## Free Functions | ||||
|  | ||||
| @@ -247,8 +271,10 @@ template<class T> bool | ||||
| template<class T> bool | ||||
|   operator<(const shared_array<T>& a, const shared_array<T>& b) noexcept; | ||||
| ``` | ||||
| :: | ||||
| Returns::: The result of comparing the stored pointers of the two smart | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: The result of comparing the stored pointers of the two smart | ||||
| pointers. | ||||
|  | ||||
| NOTE: The `operator<` overload is provided to define an ordering so that | ||||
| @@ -265,6 +291,8 @@ mandates that relational operations on pointers are unspecified (5.9 | ||||
| template<class T> | ||||
|   void swap(shared_array<T>& a, shared_array<T>& b) noexcept; | ||||
| ``` | ||||
| :: | ||||
| Returns::: `a.swap(b)`. | ||||
| Requires::: `T` is a complete type. | ||||
| [none] | ||||
| * {blank} | ||||
| + | ||||
| Returns:: `a.swap(b)`. | ||||
| Requires:: `T` is a complete type. | ||||
|   | ||||
| @@ -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); | ||||
| @@ -373,7 +372,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()`. | ||||
|  | ||||
|   | ||||
| @@ -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; | ||||
| @@ -157,6 +163,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; | ||||
| @@ -204,6 +225,17 @@ bool expired() const noexcept; | ||||
| + | ||||
| 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 | ||||
| ``` | ||||
| shared_ptr<T> lock() const noexcept; | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| /* | ||||
| Copyright 2017 Glen Joseph Fernandes | ||||
| Copyright 2017-2019 Glen Joseph Fernandes | ||||
| (glenjofe@gmail.com) | ||||
|  | ||||
| Distributed under the Boost Software License, Version 1.0. | ||||
| @@ -14,22 +14,6 @@ Distributed under the Boost Software License, Version 1.0. | ||||
| namespace boost { | ||||
| namespace detail { | ||||
|  | ||||
| template<class> | ||||
| struct lsp_if_array { }; | ||||
|  | ||||
| template<class T> | ||||
| struct lsp_if_array<T[]> { | ||||
|     typedef boost::local_shared_ptr<T[]> type; | ||||
| }; | ||||
|  | ||||
| template<class> | ||||
| struct lsp_if_size_array { }; | ||||
|  | ||||
| template<class T, std::size_t N> | ||||
| struct lsp_if_size_array<T[N]> { | ||||
|     typedef boost::local_shared_ptr<T[N]> type; | ||||
| }; | ||||
|  | ||||
| class BOOST_SYMBOL_VISIBLE lsp_array_base | ||||
|     : public local_counted_base { | ||||
| public: | ||||
| @@ -84,143 +68,108 @@ private: | ||||
| } /* detail */ | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename detail::lsp_if_array<T>::type | ||||
| 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 detail::sp_array_element<T>::type type; | ||||
|     typedef typename detail::sp_array_scalar<T>::type scalar; | ||||
|     typedef typename detail::sp_bind_allocator<A, scalar>::type other; | ||||
|     typedef typename detail::sp_array_element<T>::type element; | ||||
|     typedef typename detail::sp_bind_allocator<A, element>::type other; | ||||
|     typedef detail::lsp_array_state<other> state; | ||||
|     typedef detail::sp_array_base<state> base; | ||||
|     std::size_t size = count * detail::sp_array_count<type>::value; | ||||
|     detail::sp_array_result<other, base> result(allocator, size); | ||||
|     detail::sp_array_result<other, base> result(allocator, count); | ||||
|     base* node = result.get(); | ||||
|     scalar* start = detail::sp_array_start<base, scalar>(node); | ||||
|     ::new(static_cast<void*>(node)) base(allocator, size, start); | ||||
|     element* start = detail::sp_array_start<element>(node); | ||||
|     ::new(static_cast<void*>(node)) base(allocator, start, count); | ||||
|     detail::lsp_array_base& local = node->state().base(); | ||||
|     local.set(node); | ||||
|     result.release(); | ||||
|     return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), | ||||
|         reinterpret_cast<type*>(start), &local); | ||||
|     return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), start, | ||||
|         &local); | ||||
| } | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename detail::lsp_if_size_array<T>::type | ||||
| inline typename enable_if_<is_bounded_array<T>::value, | ||||
|     local_shared_ptr<T> >::type | ||||
| allocate_local_shared(const A& allocator) | ||||
| { | ||||
|     enum { | ||||
|         size = detail::sp_array_count<T>::value | ||||
|         count = extent<T>::value | ||||
|     }; | ||||
|     typedef typename detail::sp_array_element<T>::type type; | ||||
|     typedef typename detail::sp_array_scalar<T>::type scalar; | ||||
|     typedef typename detail::sp_bind_allocator<A, scalar>::type other; | ||||
|     typedef detail::lsp_size_array_state<other, size> state; | ||||
|     typedef typename detail::sp_array_element<T>::type element; | ||||
|     typedef typename detail::sp_bind_allocator<A, element>::type other; | ||||
|     typedef detail::lsp_size_array_state<other, count> state; | ||||
|     typedef detail::sp_array_base<state> base; | ||||
|     detail::sp_array_result<other, base> result(allocator, size); | ||||
|     detail::sp_array_result<other, base> result(allocator, count); | ||||
|     base* node = result.get(); | ||||
|     scalar* start = detail::sp_array_start<base, scalar>(node); | ||||
|     ::new(static_cast<void*>(node)) base(allocator, size, start); | ||||
|     element* start = detail::sp_array_start<element>(node); | ||||
|     ::new(static_cast<void*>(node)) base(allocator, start, count); | ||||
|     detail::lsp_array_base& local = node->state().base(); | ||||
|     local.set(node); | ||||
|     result.release(); | ||||
|     return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), | ||||
|         reinterpret_cast<type*>(start), &local); | ||||
|     return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), start, | ||||
|         &local); | ||||
| } | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename detail::lsp_if_array<T>::type | ||||
| inline typename enable_if_<is_unbounded_array<T>::value, | ||||
|     local_shared_ptr<T> >::type | ||||
| allocate_local_shared(const A& allocator, std::size_t count, | ||||
|     const typename detail::sp_array_element<T>::type& value) | ||||
|     const typename remove_extent<T>::type& value) | ||||
| { | ||||
|     typedef typename detail::sp_array_element<T>::type type; | ||||
|     typedef typename detail::sp_array_scalar<T>::type scalar; | ||||
|     typedef typename detail::sp_bind_allocator<A, scalar>::type other; | ||||
|     typedef typename detail::sp_array_element<T>::type element; | ||||
|     typedef typename detail::sp_bind_allocator<A, element>::type other; | ||||
|     typedef detail::lsp_array_state<other> state; | ||||
|     typedef detail::sp_array_base<state> base; | ||||
|     std::size_t size = count * detail::sp_array_count<type>::value; | ||||
|     detail::sp_array_result<other, base> result(allocator, size); | ||||
|     detail::sp_array_result<other, base> result(allocator, count); | ||||
|     base* node = result.get(); | ||||
|     scalar* start = detail::sp_array_start<base, scalar>(node); | ||||
|     ::new(static_cast<void*>(node)) base(allocator, size, | ||||
|         reinterpret_cast<const scalar*>(&value), | ||||
|         detail::sp_array_count<type>::value, start); | ||||
|     element* start = detail::sp_array_start<element>(node); | ||||
|     ::new(static_cast<void*>(node)) base(allocator, start, count, value); | ||||
|     detail::lsp_array_base& local = node->state().base(); | ||||
|     local.set(node); | ||||
|     result.release(); | ||||
|     return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), | ||||
|         reinterpret_cast<type*>(start), &local); | ||||
|     return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), start, | ||||
|         &local); | ||||
| } | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename detail::lsp_if_size_array<T>::type | ||||
| inline typename enable_if_<is_bounded_array<T>::value, | ||||
|     local_shared_ptr<T> >::type | ||||
| allocate_local_shared(const A& allocator, | ||||
|     const typename detail::sp_array_element<T>::type& value) | ||||
|     const typename remove_extent<T>::type& value) | ||||
| { | ||||
|     enum { | ||||
|         size = detail::sp_array_count<T>::value | ||||
|         count = extent<T>::value | ||||
|     }; | ||||
|     typedef typename detail::sp_array_element<T>::type type; | ||||
|     typedef typename detail::sp_array_scalar<T>::type scalar; | ||||
|     typedef typename detail::sp_bind_allocator<A, scalar>::type other; | ||||
|     typedef detail::lsp_size_array_state<other, size> state; | ||||
|     typedef typename detail::sp_array_element<T>::type element; | ||||
|     typedef typename detail::sp_bind_allocator<A, element>::type other; | ||||
|     typedef detail::lsp_size_array_state<other, count> state; | ||||
|     typedef detail::sp_array_base<state> base; | ||||
|     detail::sp_array_result<other, base> result(allocator, size); | ||||
|     detail::sp_array_result<other, base> result(allocator, count); | ||||
|     base* node = result.get(); | ||||
|     scalar* start = detail::sp_array_start<base, scalar>(node); | ||||
|     ::new(static_cast<void*>(node)) base(allocator, size, | ||||
|         reinterpret_cast<const scalar*>(&value), | ||||
|         detail::sp_array_count<type>::value, start); | ||||
|     element* start = detail::sp_array_start<element>(node); | ||||
|     ::new(static_cast<void*>(node)) base(allocator, start, count, value); | ||||
|     detail::lsp_array_base& local = node->state().base(); | ||||
|     local.set(node); | ||||
|     result.release(); | ||||
|     return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), | ||||
|         reinterpret_cast<type*>(start), &local); | ||||
|     return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), start, | ||||
|         &local); | ||||
| } | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename detail::lsp_if_array<T>::type | ||||
| inline typename 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 detail::sp_array_element<T>::type type; | ||||
|     typedef typename detail::sp_array_scalar<T>::type scalar; | ||||
|     typedef typename detail::sp_bind_allocator<A, scalar>::type other; | ||||
|     typedef detail::lsp_array_state<other> state; | ||||
|     typedef detail::sp_array_base<state, false> base; | ||||
|     std::size_t size = count * detail::sp_array_count<type>::value; | ||||
|     detail::sp_array_result<other, base> result(allocator, size); | ||||
|     base* node = result.get(); | ||||
|     scalar* start = detail::sp_array_start<base, scalar>(node); | ||||
|     ::new(static_cast<void*>(node)) base(detail::sp_default(), allocator, | ||||
|         size, start); | ||||
|     detail::lsp_array_base& local = node->state().base(); | ||||
|     local.set(node); | ||||
|     result.release(); | ||||
|     return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), | ||||
|         reinterpret_cast<type*>(start), &local); | ||||
|     return boost::allocate_local_shared<T>(boost::noinit_adapt(allocator), | ||||
|         count); | ||||
| } | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename detail::lsp_if_size_array<T>::type | ||||
| inline typename enable_if_<is_bounded_array<T>::value, | ||||
|     local_shared_ptr<T> >::type | ||||
| allocate_local_shared_noinit(const A& allocator) | ||||
| { | ||||
|     enum { | ||||
|         size = detail::sp_array_count<T>::value | ||||
|     }; | ||||
|     typedef typename detail::sp_array_element<T>::type type; | ||||
|     typedef typename detail::sp_array_scalar<T>::type scalar; | ||||
|     typedef typename detail::sp_bind_allocator<A, scalar>::type other; | ||||
|     typedef detail::lsp_size_array_state<other, size> state; | ||||
|     typedef detail::sp_array_base<state, false> base; | ||||
|     detail::sp_array_result<other, base> result(allocator, size); | ||||
|     base* node = result.get(); | ||||
|     scalar* start = detail::sp_array_start<base, scalar>(node); | ||||
|     ::new(static_cast<void*>(node)) base(detail::sp_default(), allocator, | ||||
|         size, start); | ||||
|     detail::lsp_array_base& local = node->state().base(); | ||||
|     local.set(node); | ||||
|     result.release(); | ||||
|     return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), | ||||
|         reinterpret_cast<type*>(start), &local); | ||||
|     return boost::allocate_local_shared<T>(boost::noinit_adapt(allocator)); | ||||
| } | ||||
|  | ||||
| } /* boost */ | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| /* | ||||
| Copyright 2012-2018 Glen Joseph Fernandes | ||||
| Copyright 2012-2019 Glen Joseph Fernandes | ||||
| (glenjofe@gmail.com) | ||||
|  | ||||
| Distributed under the Boost Software License, Version 1.0. | ||||
| @@ -8,88 +8,25 @@ 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/alloc_construct.hpp> | ||||
| #include <boost/core/first_scalar.hpp> | ||||
| #include <boost/smart_ptr/shared_ptr.hpp> | ||||
| #include <boost/type_traits/alignment_of.hpp> | ||||
| #include <boost/type_traits/has_trivial_assign.hpp> | ||||
| #include <boost/type_traits/has_trivial_constructor.hpp> | ||||
| #include <boost/type_traits/has_trivial_destructor.hpp> | ||||
| #include <boost/type_traits/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/remove_cv.hpp> | ||||
| #include <boost/type_traits/remove_extent.hpp> | ||||
| #include <boost/type_traits/type_with_alignment.hpp> | ||||
|  | ||||
| namespace boost { | ||||
| namespace detail { | ||||
|  | ||||
| template<class> | ||||
| struct sp_if_array { }; | ||||
|  | ||||
| template<class T> | ||||
| struct sp_if_array<T[]> { | ||||
|     typedef boost::shared_ptr<T[]> type; | ||||
| }; | ||||
|  | ||||
| template<class> | ||||
| struct sp_if_size_array { }; | ||||
|  | ||||
| template<class T, std::size_t N> | ||||
| struct sp_if_size_array<T[N]> { | ||||
|     typedef boost::shared_ptr<T[N]> type; | ||||
| }; | ||||
|  | ||||
| template<class> | ||||
| struct sp_array_element { }; | ||||
|  | ||||
| template<class T> | ||||
| struct sp_array_element<T[]> { | ||||
|     typedef T type; | ||||
| }; | ||||
|  | ||||
| template<class T, std::size_t N> | ||||
| struct sp_array_element<T[N]> { | ||||
|     typedef T type; | ||||
| }; | ||||
|  | ||||
| template<class T> | ||||
| struct sp_array_scalar { | ||||
|     typedef T type; | ||||
| }; | ||||
|  | ||||
| template<class T, std::size_t N> | ||||
| struct sp_array_scalar<T[N]> { | ||||
|     typedef typename sp_array_scalar<T>::type type; | ||||
| }; | ||||
|  | ||||
| template<class T, std::size_t N> | ||||
| struct sp_array_scalar<const T[N]> { | ||||
|     typedef typename sp_array_scalar<T>::type type; | ||||
| }; | ||||
|  | ||||
| template<class T, std::size_t N> | ||||
| struct sp_array_scalar<volatile T[N]> { | ||||
|     typedef typename sp_array_scalar<T>::type type; | ||||
| }; | ||||
|  | ||||
| template<class T, std::size_t N> | ||||
| struct sp_array_scalar<const volatile T[N]> { | ||||
|     typedef typename sp_array_scalar<T>::type type; | ||||
| }; | ||||
|  | ||||
| template<class T> | ||||
| struct sp_array_scalar<T[]> { | ||||
|     typedef typename sp_array_scalar<T>::type type; | ||||
| }; | ||||
|  | ||||
| template<class T> | ||||
| struct sp_array_scalar<const T[]> { | ||||
|     typedef typename sp_array_scalar<T>::type type; | ||||
| }; | ||||
|  | ||||
| template<class T> | ||||
| struct sp_array_scalar<volatile T[]> { | ||||
|     typedef typename sp_array_scalar<T>::type type; | ||||
| }; | ||||
|  | ||||
| template<class T> | ||||
| struct sp_array_scalar<const volatile T[]> { | ||||
|     typedef typename sp_array_scalar<T>::type type; | ||||
| struct sp_array_element { | ||||
|     typedef typename boost::remove_cv<typename | ||||
|         boost::remove_extent<T>::type>::type type; | ||||
| }; | ||||
|  | ||||
| template<class T> | ||||
| @@ -139,159 +76,6 @@ sp_objects(std::size_t size) BOOST_SP_NOEXCEPT | ||||
|     return (size + sizeof(T) - 1) / sizeof(T); | ||||
| } | ||||
|  | ||||
| template<bool, class = void> | ||||
| struct sp_enable { }; | ||||
|  | ||||
| template<class T> | ||||
| struct sp_enable<true, T> { | ||||
|     typedef T type; | ||||
| }; | ||||
|  | ||||
| template<bool E, class A, class T> | ||||
| inline typename sp_enable<!E && boost::has_trivial_destructor<T>::value>::type | ||||
| sp_array_destroy(A&, T*, std::size_t) BOOST_SP_NOEXCEPT { } | ||||
|  | ||||
| template<bool E, class A, class T> | ||||
| inline typename sp_enable<!E && | ||||
|     !boost::has_trivial_destructor<T>::value>::type | ||||
| sp_array_destroy(A&, T* 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 sp_enable<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 sp_enable<!E && | ||||
|     boost::has_trivial_constructor<T>::value && | ||||
|     boost::has_trivial_assign<T>::value && | ||||
|     boost::has_trivial_destructor<T>::value>::type | ||||
| sp_array_construct(A&, T* 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 sp_enable<!E && | ||||
|     boost::has_trivial_constructor<T>::value && | ||||
|     boost::has_trivial_assign<T>::value && | ||||
|     boost::has_trivial_destructor<T>::value>::type | ||||
| sp_array_construct(A&, T* 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 sp_enable<!E && | ||||
|     !(boost::has_trivial_constructor<T>::value && | ||||
|       boost::has_trivial_assign<T>::value && | ||||
|       boost::has_trivial_destructor<T>::value)>::type | ||||
| sp_array_construct(A& none, T* 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 sp_enable<!E && | ||||
|     !(boost::has_trivial_constructor<T>::value && | ||||
|       boost::has_trivial_assign<T>::value && | ||||
|       boost::has_trivial_destructor<T>::value)>::type | ||||
| sp_array_construct(A& none, T* 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 sp_enable<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 sp_enable<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 sp_enable<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 sp_enable<!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: | ||||
| @@ -336,29 +120,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 { | ||||
| @@ -374,39 +135,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_)); | ||||
| @@ -421,9 +175,7 @@ private: | ||||
|     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; | ||||
| @@ -432,50 +184,50 @@ 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() { | ||||
|         sp_array_destroy<E>(state_.allocator(), | ||||
|             sp_array_start<sp_array_base, type>(this), state_.size()); | ||||
|     virtual void dispose() BOOST_SP_NOEXCEPT { | ||||
|         boost::alloc_destroy_n(state_.allocator(), | ||||
|             boost::first_scalar(sp_array_start<type>(this)), | ||||
|             state_.size() * sp_array_count<type>::value); | ||||
|     } | ||||
|  | ||||
|     virtual void destroy() { | ||||
|     virtual void destroy() BOOST_SP_NOEXCEPT { | ||||
|         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&) { | ||||
|     virtual void* get_deleter(const sp_typeinfo_&) BOOST_SP_NOEXCEPT { | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     virtual void* get_local_deleter(const sp_typeinfo&) { | ||||
|     virtual void* get_local_deleter(const sp_typeinfo_&) BOOST_SP_NOEXCEPT { | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     virtual void* get_untyped_deleter() { | ||||
|     virtual void* get_untyped_deleter() BOOST_SP_NOEXCEPT { | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
| @@ -497,11 +249,11 @@ public: | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     T* get() const { | ||||
|     T* get() const BOOST_SP_NOEXCEPT { | ||||
|         return result_; | ||||
|     } | ||||
|  | ||||
|     void release() { | ||||
|     void release() BOOST_SP_NOEXCEPT { | ||||
|         result_ = 0; | ||||
|     } | ||||
|  | ||||
| @@ -516,131 +268,93 @@ private: | ||||
| } /* detail */ | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename detail::sp_if_array<T>::type | ||||
| inline typename enable_if_<is_unbounded_array<T>::value, shared_ptr<T> >::type | ||||
| allocate_shared(const A& allocator, std::size_t count) | ||||
| { | ||||
|     typedef typename detail::sp_array_element<T>::type type; | ||||
|     typedef typename detail::sp_array_scalar<T>::type scalar; | ||||
|     typedef typename detail::sp_bind_allocator<A, scalar>::type other; | ||||
|     typedef typename detail::sp_array_element<T>::type element; | ||||
|     typedef typename detail::sp_bind_allocator<A, element>::type other; | ||||
|     typedef detail::sp_array_state<other> state; | ||||
|     typedef detail::sp_array_base<state> base; | ||||
|     std::size_t size = count * detail::sp_array_count<type>::value; | ||||
|     detail::sp_array_result<other, base> result(allocator, size); | ||||
|     detail::sp_counted_base* node = result.get(); | ||||
|     scalar* start = detail::sp_array_start<base, scalar>(node); | ||||
|     ::new(static_cast<void*>(node)) base(allocator, size, start); | ||||
|     detail::sp_array_result<other, base> result(allocator, count); | ||||
|     base* node = result.get(); | ||||
|     element* start = detail::sp_array_start<element>(node); | ||||
|     ::new(static_cast<void*>(node)) base(allocator, start, count); | ||||
|     result.release(); | ||||
|     return shared_ptr<T>(detail::sp_internal_constructor_tag(), | ||||
|         reinterpret_cast<type*>(start), detail::shared_count(node)); | ||||
|     return shared_ptr<T>(detail::sp_internal_constructor_tag(), start, | ||||
|         detail::shared_count(static_cast<detail::sp_counted_base*>(node))); | ||||
| } | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename detail::sp_if_size_array<T>::type | ||||
| inline typename enable_if_<is_bounded_array<T>::value, shared_ptr<T> >::type | ||||
| allocate_shared(const A& allocator) | ||||
| { | ||||
|     enum { | ||||
|         size = detail::sp_array_count<T>::value | ||||
|         count = extent<T>::value | ||||
|     }; | ||||
|     typedef typename detail::sp_array_element<T>::type type; | ||||
|     typedef typename detail::sp_array_scalar<T>::type scalar; | ||||
|     typedef typename detail::sp_bind_allocator<A, scalar>::type other; | ||||
|     typedef detail::sp_size_array_state<other, size> state; | ||||
|     typedef typename detail::sp_array_element<T>::type element; | ||||
|     typedef typename detail::sp_bind_allocator<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> | ||||
| inline typename detail::sp_if_array<T>::type | ||||
| inline typename enable_if_<is_unbounded_array<T>::value, shared_ptr<T> >::type | ||||
| allocate_shared(const A& allocator, std::size_t count, | ||||
|     const typename detail::sp_array_element<T>::type& value) | ||||
|     const typename remove_extent<T>::type& value) | ||||
| { | ||||
|     typedef typename detail::sp_array_element<T>::type type; | ||||
|     typedef typename detail::sp_array_scalar<T>::type scalar; | ||||
|     typedef typename detail::sp_bind_allocator<A, scalar>::type other; | ||||
|     typedef typename detail::sp_array_element<T>::type element; | ||||
|     typedef typename detail::sp_bind_allocator<A, element>::type other; | ||||
|     typedef detail::sp_array_state<other> state; | ||||
|     typedef detail::sp_array_base<state> base; | ||||
|     std::size_t size = count * detail::sp_array_count<type>::value; | ||||
|     detail::sp_array_result<other, base> result(allocator, size); | ||||
|     detail::sp_counted_base* node = result.get(); | ||||
|     scalar* start = detail::sp_array_start<base, scalar>(node); | ||||
|     ::new(static_cast<void*>(node)) base(allocator, size, | ||||
|         reinterpret_cast<const scalar*>(&value), | ||||
|         detail::sp_array_count<type>::value, start); | ||||
|     detail::sp_array_result<other, base> result(allocator, count); | ||||
|     base* node = result.get(); | ||||
|     element* start = detail::sp_array_start<element>(node); | ||||
|     ::new(static_cast<void*>(node)) base(allocator, start, count, value); | ||||
|     result.release(); | ||||
|     return shared_ptr<T>(detail::sp_internal_constructor_tag(), | ||||
|         reinterpret_cast<type*>(start), detail::shared_count(node)); | ||||
|     return shared_ptr<T>(detail::sp_internal_constructor_tag(), start, | ||||
|         detail::shared_count(static_cast<detail::sp_counted_base*>(node))); | ||||
| } | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename detail::sp_if_size_array<T>::type | ||||
| inline typename enable_if_<is_bounded_array<T>::value, shared_ptr<T> >::type | ||||
| allocate_shared(const A& allocator, | ||||
|     const typename detail::sp_array_element<T>::type& value) | ||||
|     const typename remove_extent<T>::type& value) | ||||
| { | ||||
|     enum { | ||||
|         size = detail::sp_array_count<T>::value | ||||
|         count = extent<T>::value | ||||
|     }; | ||||
|     typedef typename detail::sp_array_element<T>::type type; | ||||
|     typedef typename detail::sp_array_scalar<T>::type scalar; | ||||
|     typedef typename detail::sp_bind_allocator<A, scalar>::type other; | ||||
|     typedef detail::sp_size_array_state<other, size> state; | ||||
|     typedef typename detail::sp_array_element<T>::type element; | ||||
|     typedef typename detail::sp_bind_allocator<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>::value, start); | ||||
|     detail::sp_array_result<other, base> result(allocator, count); | ||||
|     base* node = result.get(); | ||||
|     element* start = detail::sp_array_start<element>(node); | ||||
|     ::new(static_cast<void*>(node)) base(allocator, start, count, value); | ||||
|     result.release(); | ||||
|     return shared_ptr<T>(detail::sp_internal_constructor_tag(), | ||||
|         reinterpret_cast<type*>(start), detail::shared_count(node)); | ||||
|     return shared_ptr<T>(detail::sp_internal_constructor_tag(), start, | ||||
|         detail::shared_count(static_cast<detail::sp_counted_base*>(node))); | ||||
| } | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename detail::sp_if_array<T>::type | ||||
| inline typename enable_if_<is_unbounded_array<T>::value, shared_ptr<T> >::type | ||||
| allocate_shared_noinit(const A& allocator, std::size_t count) | ||||
| { | ||||
|     typedef typename detail::sp_array_element<T>::type type; | ||||
|     typedef typename detail::sp_array_scalar<T>::type scalar; | ||||
|     typedef typename detail::sp_bind_allocator<A, scalar>::type other; | ||||
|     typedef detail::sp_array_state<other> state; | ||||
|     typedef detail::sp_array_base<state, false> base; | ||||
|     std::size_t size = count * detail::sp_array_count<type>::value; | ||||
|     detail::sp_array_result<other, base> result(allocator, size); | ||||
|     detail::sp_counted_base* node = result.get(); | ||||
|     scalar* start = detail::sp_array_start<base, scalar>(node); | ||||
|     ::new(static_cast<void*>(node)) base(detail::sp_default(), allocator, | ||||
|         size, start); | ||||
|     result.release(); | ||||
|     return shared_ptr<T>(detail::sp_internal_constructor_tag(), | ||||
|         reinterpret_cast<type*>(start), detail::shared_count(node)); | ||||
|     return boost::allocate_shared<T>(boost::noinit_adapt(allocator), count); | ||||
| } | ||||
|  | ||||
| template<class T, class A> | ||||
| inline typename detail::sp_if_size_array<T>::type | ||||
| inline typename enable_if_<is_bounded_array<T>::value, shared_ptr<T> >::type | ||||
| allocate_shared_noinit(const A& allocator) | ||||
| { | ||||
|     enum { | ||||
|         size = detail::sp_array_count<T>::value | ||||
|     }; | ||||
|     typedef typename detail::sp_array_element<T>::type type; | ||||
|     typedef typename detail::sp_array_scalar<T>::type scalar; | ||||
|     typedef typename detail::sp_bind_allocator<A, scalar>::type other; | ||||
|     typedef detail::sp_size_array_state<other, size> state; | ||||
|     typedef detail::sp_array_base<state, false> base; | ||||
|     detail::sp_array_result<other, base> result(allocator, size); | ||||
|     detail::sp_counted_base* node = result.get(); | ||||
|     scalar* start = detail::sp_array_start<base, scalar>(node); | ||||
|     ::new(static_cast<void*>(node)) base(detail::sp_default(), allocator, | ||||
|         size, start); | ||||
|     result.release(); | ||||
|     return shared_ptr<T>(detail::sp_internal_constructor_tag(), | ||||
|         reinterpret_cast<type*>(start), detail::shared_count(node)); | ||||
|     return boost::allocate_shared<T>(boost::noinit_adapt(allocator)); | ||||
| } | ||||
|  | ||||
| } /* boost */ | ||||
|   | ||||
							
								
								
									
										505
									
								
								include/boost/smart_ptr/allocate_unique.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										505
									
								
								include/boost/smart_ptr/allocate_unique.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,505 @@ | ||||
| /* | ||||
| 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/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; | ||||
| }; | ||||
|  | ||||
| #if !defined(BOOST_NO_CXX11_ALLOCATOR) | ||||
| template<class A, class T> | ||||
| struct sp_alloc_to { | ||||
|     typedef typename std::allocator_traits<A>::template rebind_alloc<T> type; | ||||
| }; | ||||
| #else | ||||
| template<class A, class T> | ||||
| struct sp_alloc_to { | ||||
|     typedef typename A::template rebind<T>::other type; | ||||
| }; | ||||
| #endif | ||||
|  | ||||
| #if !defined(BOOST_NO_CXX11_ALLOCATOR) | ||||
| template<class A> | ||||
| struct sp_alloc_type { | ||||
|     typedef typename std::allocator_traits<A>::pointer type; | ||||
| }; | ||||
| #else | ||||
| template<class A> | ||||
| struct sp_alloc_type { | ||||
|     typedef typename A::pointer type; | ||||
| }; | ||||
| #endif | ||||
|  | ||||
| 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 sp_alloc_type<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 sp_alloc_type<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 detail::sp_alloc_to<A, | ||||
|         typename detail::sp_alloc_value<T>::type>::type> { | ||||
|     typedef typename detail::sp_alloc_to<A, | ||||
|         typename detail::sp_alloc_value<T>::type>::type allocator; | ||||
|     typedef empty_value<allocator> base; | ||||
|  | ||||
| public: | ||||
|     typedef detail::sp_alloc_ptr<T, | ||||
|         typename detail::sp_alloc_type<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 sp_alloc_to<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 sp_alloc_type<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 | ||||
| @@ -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_ ); | ||||
|   | ||||
| @@ -26,7 +26,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 ) ) | ||||
|     { | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -101,13 +101,13 @@ private: | ||||
|  | ||||
| public: | ||||
|  | ||||
|     explicit local_counted_impl( shared_count const& pn ): pn_( pn ) | ||||
|     explicit local_counted_impl( shared_count const& pn ) BOOST_SP_NOEXCEPT: pn_( pn ) | ||||
|     { | ||||
|     } | ||||
|  | ||||
| #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) | ||||
|  | ||||
|     explicit local_counted_impl( shared_count && pn ): pn_( std::move(pn) ) | ||||
|     explicit local_counted_impl( shared_count && pn ) BOOST_SP_NOEXCEPT: pn_( std::move(pn) ) | ||||
|     { | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -50,7 +50,7 @@ public: | ||||
|  | ||||
| #endif | ||||
|  | ||||
|     D& deleter() | ||||
|     D& deleter() BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         return d_; | ||||
|     } | ||||
| @@ -74,12 +74,12 @@ template<> class local_sp_deleter<void> | ||||
| { | ||||
| }; | ||||
|  | ||||
| template<class D> D * get_local_deleter( local_sp_deleter<D> * p ) | ||||
| template<class D> D * get_local_deleter( local_sp_deleter<D> * p ) BOOST_SP_NOEXCEPT | ||||
| { | ||||
|     return &p->deleter(); | ||||
| } | ||||
|  | ||||
| inline void * get_local_deleter( local_sp_deleter<void> * /*p*/ ) | ||||
| inline void * get_local_deleter( local_sp_deleter<void> * /*p*/ ) BOOST_SP_NOEXCEPT | ||||
| { | ||||
|     return 0; | ||||
| } | ||||
|   | ||||
| @@ -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 | ||||
							
								
								
									
										62
									
								
								include/boost/smart_ptr/detail/lwm_std_mutex.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								include/boost/smart_ptr/detail/lwm_std_mutex.hpp
									
									
									
									
									
										Normal 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 | ||||
| @@ -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() | ||||
|   | ||||
| @@ -29,7 +29,8 @@ | ||||
| #include <boost/smart_ptr/detail/sp_counted_base.hpp> | ||||
| #include <boost/smart_ptr/detail/sp_counted_impl.hpp> | ||||
| #include <boost/smart_ptr/detail/sp_disable_deprecated.hpp> | ||||
| #include <boost/detail/workaround.hpp> | ||||
| #include <boost/smart_ptr/detail/sp_noexcept.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  | ||||
| @@ -118,14 +119,14 @@ private: | ||||
|  | ||||
| public: | ||||
|  | ||||
|     BOOST_CONSTEXPR shared_count(): pi_(0) // nothrow | ||||
|     BOOST_CONSTEXPR shared_count() BOOST_SP_NOEXCEPT: pi_(0) | ||||
| #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) | ||||
|         , id_(shared_count_id) | ||||
| #endif | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     BOOST_CONSTEXPR explicit shared_count( sp_counted_base * pi ): pi_( pi ) // nothrow | ||||
|     BOOST_CONSTEXPR explicit shared_count( sp_counted_base * pi ) BOOST_SP_NOEXCEPT: pi_( pi ) | ||||
| #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) | ||||
|         , id_(shared_count_id) | ||||
| #endif | ||||
| @@ -421,7 +422,7 @@ public: | ||||
|         r.release(); | ||||
|     } | ||||
|  | ||||
|     ~shared_count() // nothrow | ||||
|     ~shared_count() /*BOOST_SP_NOEXCEPT*/ | ||||
|     { | ||||
|         if( pi_ != 0 ) pi_->release(); | ||||
| #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) | ||||
| @@ -429,7 +430,7 @@ public: | ||||
| #endif | ||||
|     } | ||||
|  | ||||
|     shared_count(shared_count const & r): pi_(r.pi_) // nothrow | ||||
|     shared_count(shared_count const & r) BOOST_SP_NOEXCEPT: pi_(r.pi_) | ||||
| #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) | ||||
|         , id_(shared_count_id) | ||||
| #endif | ||||
| @@ -439,7 +440,7 @@ public: | ||||
|  | ||||
| #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) | ||||
|  | ||||
|     shared_count(shared_count && r): pi_(r.pi_) // nothrow | ||||
|     shared_count(shared_count && r) BOOST_SP_NOEXCEPT: pi_(r.pi_) | ||||
| #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) | ||||
|         , id_(shared_count_id) | ||||
| #endif | ||||
| @@ -450,9 +451,9 @@ public: | ||||
| #endif | ||||
|  | ||||
|     explicit shared_count(weak_count const & r); // throws bad_weak_ptr when r.use_count() == 0 | ||||
|     shared_count( weak_count const & r, sp_nothrow_tag ); // constructs an empty *this when r.use_count() == 0 | ||||
|     shared_count( weak_count const & r, sp_nothrow_tag ) BOOST_SP_NOEXCEPT; // constructs an empty *this when r.use_count() == 0 | ||||
|  | ||||
|     shared_count & operator= (shared_count const & r) // nothrow | ||||
|     shared_count & operator= (shared_count const & r) BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         sp_counted_base * tmp = r.pi_; | ||||
|  | ||||
| @@ -466,49 +467,49 @@ public: | ||||
|         return *this; | ||||
|     } | ||||
|  | ||||
|     void swap(shared_count & r) // nothrow | ||||
|     void swap(shared_count & r) BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         sp_counted_base * tmp = r.pi_; | ||||
|         r.pi_ = pi_; | ||||
|         pi_ = tmp; | ||||
|     } | ||||
|  | ||||
|     long use_count() const // nothrow | ||||
|     long use_count() const BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         return pi_ != 0? pi_->use_count(): 0; | ||||
|     } | ||||
|  | ||||
|     bool unique() const // nothrow | ||||
|     bool unique() const BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         return use_count() == 1; | ||||
|     } | ||||
|  | ||||
|     bool empty() const // nothrow | ||||
|     bool empty() const BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         return pi_ == 0; | ||||
|     } | ||||
|  | ||||
|     friend inline bool operator==(shared_count const & a, shared_count const & b) | ||||
|     friend inline bool operator==(shared_count const & a, shared_count const & b) BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         return a.pi_ == b.pi_; | ||||
|     } | ||||
|  | ||||
|     friend inline bool operator<(shared_count const & a, shared_count const & b) | ||||
|     friend inline bool operator<(shared_count const & a, shared_count const & b) BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         return std::less<sp_counted_base *>()( a.pi_, b.pi_ ); | ||||
|     } | ||||
|  | ||||
|     void * get_deleter( sp_typeinfo const & ti ) const | ||||
|     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 | ||||
|     void * get_local_deleter( sp_typeinfo_ const & ti ) const BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         return pi_? pi_->get_local_deleter( ti ): 0; | ||||
|     } | ||||
|  | ||||
|     void * get_untyped_deleter() const | ||||
|     void * get_untyped_deleter() const BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         return pi_? pi_->get_untyped_deleter(): 0; | ||||
|     } | ||||
| @@ -529,14 +530,14 @@ private: | ||||
|  | ||||
| public: | ||||
|  | ||||
|     BOOST_CONSTEXPR weak_count(): pi_(0) // nothrow | ||||
|     BOOST_CONSTEXPR weak_count() BOOST_SP_NOEXCEPT: pi_(0) | ||||
| #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) | ||||
|         , id_(weak_count_id) | ||||
| #endif | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     weak_count(shared_count const & r): pi_(r.pi_) // nothrow | ||||
|     weak_count(shared_count const & r) BOOST_SP_NOEXCEPT: pi_(r.pi_) | ||||
| #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) | ||||
|         , id_(weak_count_id) | ||||
| #endif | ||||
| @@ -544,7 +545,7 @@ public: | ||||
|         if(pi_ != 0) pi_->weak_add_ref(); | ||||
|     } | ||||
|  | ||||
|     weak_count(weak_count const & r): pi_(r.pi_) // nothrow | ||||
|     weak_count(weak_count const & r) BOOST_SP_NOEXCEPT: pi_(r.pi_) | ||||
| #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) | ||||
|         , id_(weak_count_id) | ||||
| #endif | ||||
| @@ -556,7 +557,7 @@ public: | ||||
|  | ||||
| #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) | ||||
|  | ||||
|     weak_count(weak_count && r): pi_(r.pi_) // nothrow | ||||
|     weak_count(weak_count && r) BOOST_SP_NOEXCEPT: pi_(r.pi_) | ||||
| #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) | ||||
|         , id_(weak_count_id) | ||||
| #endif | ||||
| @@ -566,7 +567,7 @@ public: | ||||
|  | ||||
| #endif | ||||
|  | ||||
|     ~weak_count() // nothrow | ||||
|     ~weak_count() /*BOOST_SP_NOEXCEPT*/ | ||||
|     { | ||||
|         if(pi_ != 0) pi_->weak_release(); | ||||
| #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) | ||||
| @@ -574,7 +575,7 @@ public: | ||||
| #endif | ||||
|     } | ||||
|  | ||||
|     weak_count & operator= (shared_count const & r) // nothrow | ||||
|     weak_count & operator= (shared_count const & r) BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         sp_counted_base * tmp = r.pi_; | ||||
|  | ||||
| @@ -588,7 +589,7 @@ public: | ||||
|         return *this; | ||||
|     } | ||||
|  | ||||
|     weak_count & operator= (weak_count const & r) // nothrow | ||||
|     weak_count & operator= (weak_count const & r) BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         sp_counted_base * tmp = r.pi_; | ||||
|  | ||||
| @@ -602,29 +603,29 @@ public: | ||||
|         return *this; | ||||
|     } | ||||
|  | ||||
|     void swap(weak_count & r) // nothrow | ||||
|     void swap(weak_count & r) BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         sp_counted_base * tmp = r.pi_; | ||||
|         r.pi_ = pi_; | ||||
|         pi_ = tmp; | ||||
|     } | ||||
|  | ||||
|     long use_count() const // nothrow | ||||
|     long use_count() const BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         return pi_ != 0? pi_->use_count(): 0; | ||||
|     } | ||||
|  | ||||
|     bool empty() const // nothrow | ||||
|     bool empty() const BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         return pi_ == 0; | ||||
|     } | ||||
|  | ||||
|     friend inline bool operator==(weak_count const & a, weak_count const & b) | ||||
|     friend inline bool operator==(weak_count const & a, weak_count const & b) BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         return a.pi_ == b.pi_; | ||||
|     } | ||||
|  | ||||
|     friend inline bool operator<(weak_count const & a, weak_count const & b) | ||||
|     friend inline bool operator<(weak_count const & a, weak_count const & b) BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         return std::less<sp_counted_base *>()(a.pi_, b.pi_); | ||||
|     } | ||||
| @@ -641,7 +642,7 @@ inline shared_count::shared_count( weak_count const & r ): pi_( r.pi_ ) | ||||
|     } | ||||
| } | ||||
|  | ||||
| inline shared_count::shared_count( weak_count const & r, sp_nothrow_tag ): pi_( r.pi_ ) | ||||
| inline shared_count::shared_count( weak_count const & r, sp_nothrow_tag ) BOOST_SP_NOEXCEPT: pi_( r.pi_ ) | ||||
| #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) | ||||
|         , id_(shared_count_id) | ||||
| #endif | ||||
|   | ||||
| @@ -15,7 +15,7 @@ | ||||
| //  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> | ||||
|  | ||||
| @@ -104,8 +104,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() | ||||
|   | ||||
| @@ -20,7 +20,7 @@ | ||||
| //  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> | ||||
| @@ -96,8 +96,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() | ||||
|   | ||||
| @@ -15,7 +15,8 @@ | ||||
| //  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> | ||||
|  | ||||
| @@ -27,17 +28,17 @@ namespace detail | ||||
|  | ||||
| typedef _Atomic( boost::int_least32_t ) atomic_int_least32_t; | ||||
|  | ||||
| inline void atomic_increment( atomic_int_least32_t * pw ) | ||||
| inline void atomic_increment( atomic_int_least32_t * pw ) BOOST_SP_NOEXCEPT | ||||
| { | ||||
|     __c11_atomic_fetch_add( pw, 1, __ATOMIC_RELAXED ); | ||||
| } | ||||
|  | ||||
| inline boost::int_least32_t atomic_decrement( atomic_int_least32_t * pw ) | ||||
| inline boost::int_least32_t atomic_decrement( atomic_int_least32_t * pw ) BOOST_SP_NOEXCEPT | ||||
| { | ||||
|     return __c11_atomic_fetch_sub( pw, 1, __ATOMIC_ACQ_REL ); | ||||
| } | ||||
|  | ||||
| inline boost::int_least32_t atomic_conditional_increment( atomic_int_least32_t * pw ) | ||||
| inline boost::int_least32_t atomic_conditional_increment( atomic_int_least32_t * pw ) BOOST_SP_NOEXCEPT | ||||
| { | ||||
|     // long r = *pw; | ||||
|     // if( r != 0 ) ++*pw; | ||||
| @@ -76,43 +77,43 @@ private: | ||||
|  | ||||
| public: | ||||
|  | ||||
|     sp_counted_base() | ||||
|     sp_counted_base() BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         __c11_atomic_init( &use_count_, 1 ); | ||||
|         __c11_atomic_init( &weak_count_, 1 ); | ||||
|     } | ||||
|  | ||||
|     virtual ~sp_counted_base() // nothrow | ||||
|     virtual ~sp_counted_base() /*BOOST_SP_NOEXCEPT*/ | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     // dispose() is called when use_count_ drops to zero, to release | ||||
|     // the resources managed by *this. | ||||
|  | ||||
|     virtual void dispose() = 0; // nothrow | ||||
|     virtual void dispose() BOOST_SP_NOEXCEPT = 0; // nothrow | ||||
|  | ||||
|     // destroy() is called when weak_count_ drops to zero. | ||||
|  | ||||
|     virtual void destroy() // nothrow | ||||
|     virtual void destroy() BOOST_SP_NOEXCEPT // nothrow | ||||
|     { | ||||
|         delete this; | ||||
|     } | ||||
|  | ||||
|     virtual void * get_deleter( sp_typeinfo const & ti ) = 0; | ||||
|     virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0; | ||||
|     virtual void * get_untyped_deleter() = 0; | ||||
|     virtual void * get_deleter( sp_typeinfo_ const & ti ) 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() | ||||
|     void add_ref_copy() BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         atomic_increment( &use_count_ ); | ||||
|     } | ||||
|  | ||||
|     bool add_ref_lock() // true on success | ||||
|     bool add_ref_lock() BOOST_SP_NOEXCEPT // true on success | ||||
|     { | ||||
|         return atomic_conditional_increment( &use_count_ ) != 0; | ||||
|     } | ||||
|  | ||||
|     void release() // nothrow | ||||
|     void release() BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         if( atomic_decrement( &use_count_ ) == 1 ) | ||||
|         { | ||||
| @@ -121,12 +122,12 @@ public: | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     void weak_add_ref() // nothrow | ||||
|     void weak_add_ref() BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         atomic_increment( &weak_count_ ); | ||||
|     } | ||||
|  | ||||
|     void weak_release() // nothrow | ||||
|     void weak_release() BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         if( atomic_decrement( &weak_count_ ) == 1 ) | ||||
|         { | ||||
| @@ -134,7 +135,7 @@ public: | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     long use_count() const // nothrow | ||||
|     long use_count() const BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         return __c11_atomic_load( const_cast< atomic_int_least32_t* >( &use_count_ ), __ATOMIC_ACQUIRE ); | ||||
|     } | ||||
|   | ||||
| @@ -24,7 +24,7 @@ | ||||
| //  formulation | ||||
| // | ||||
|  | ||||
| #include <boost/detail/sp_typeinfo.hpp> | ||||
| #include <boost/smart_ptr/detail/sp_typeinfo_.hpp> | ||||
| #include <boost/config.hpp> | ||||
|  | ||||
| namespace boost | ||||
| @@ -124,8 +124,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() | ||||
|   | ||||
| @@ -25,7 +25,7 @@ | ||||
| //  formulation | ||||
| // | ||||
|  | ||||
| #include <boost/detail/sp_typeinfo.hpp> | ||||
| #include <boost/smart_ptr/detail/sp_typeinfo_.hpp> | ||||
| #include <boost/config.hpp> | ||||
|  | ||||
| namespace boost | ||||
| @@ -112,8 +112,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() | ||||
|   | ||||
| @@ -16,7 +16,7 @@ | ||||
| //  Lock-free algorithm by Alexander Terekhov | ||||
| // | ||||
|  | ||||
| #include <boost/detail/sp_typeinfo.hpp> | ||||
| #include <boost/smart_ptr/detail/sp_typeinfo_.hpp> | ||||
| #include <boost/config.hpp> | ||||
|  | ||||
| namespace boost | ||||
| @@ -111,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() | ||||
|   | ||||
| @@ -20,7 +20,7 @@ | ||||
| //  Lock-free algorithm by Alexander Terekhov | ||||
| // | ||||
|  | ||||
| #include <boost/detail/sp_typeinfo.hpp> | ||||
| #include <boost/smart_ptr/detail/sp_typeinfo_.hpp> | ||||
| #include <boost/config.hpp> | ||||
|  | ||||
| namespace boost | ||||
| @@ -141,8 +141,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() | ||||
|   | ||||
| @@ -24,7 +24,7 @@ | ||||
| //  formulation | ||||
| // | ||||
|  | ||||
| #include <boost/detail/sp_typeinfo.hpp> | ||||
| #include <boost/smart_ptr/detail/sp_typeinfo_.hpp> | ||||
| #include <boost/config.hpp> | ||||
|  | ||||
| namespace boost | ||||
| @@ -135,8 +135,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() | ||||
|   | ||||
| @@ -19,7 +19,7 @@ | ||||
| // | ||||
| //  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 | ||||
|  | ||||
| @@ -120,8 +120,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() | ||||
|   | ||||
| @@ -24,7 +24,7 @@ | ||||
| //  formulation | ||||
| // | ||||
|  | ||||
| #include <boost/detail/sp_typeinfo.hpp> | ||||
| #include <boost/smart_ptr/detail/sp_typeinfo_.hpp> | ||||
| #include <boost/config.hpp> | ||||
|  | ||||
| namespace boost | ||||
| @@ -127,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() | ||||
|   | ||||
| @@ -18,7 +18,8 @@ | ||||
| // 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> | ||||
|  | ||||
| @@ -40,43 +41,43 @@ private: | ||||
|  | ||||
| public: | ||||
|  | ||||
|     sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) | ||||
|     sp_counted_base() BOOST_SP_NOEXCEPT: use_count_( 1 ), weak_count_( 1 ) | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     virtual ~sp_counted_base() // nothrow | ||||
|     virtual ~sp_counted_base() /*BOOST_SP_NOEXCEPT*/ | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     // dispose() is called when use_count_ drops to zero, to release | ||||
|     // the resources managed by *this. | ||||
|  | ||||
|     virtual void dispose() = 0; // nothrow | ||||
|     virtual void dispose() BOOST_SP_NOEXCEPT = 0; // nothrow | ||||
|  | ||||
|     // destroy() is called when weak_count_ drops to zero. | ||||
|  | ||||
|     virtual void destroy() // nothrow | ||||
|     virtual void destroy() BOOST_SP_NOEXCEPT // nothrow | ||||
|     { | ||||
|         delete this; | ||||
|     } | ||||
|  | ||||
|     virtual void * get_deleter( sp_typeinfo const & ti ) = 0; | ||||
|     virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0; | ||||
|     virtual void * get_untyped_deleter() = 0; | ||||
|     virtual void * get_deleter( sp_typeinfo_ const & ti ) 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() | ||||
|     void add_ref_copy() BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         ++use_count_; | ||||
|     } | ||||
|  | ||||
|     bool add_ref_lock() // true on success | ||||
|     bool add_ref_lock() BOOST_SP_NOEXCEPT // true on success | ||||
|     { | ||||
|         if( use_count_ == 0 ) return false; | ||||
|         ++use_count_; | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     void release() // nothrow | ||||
|     void release() BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         if( --use_count_ == 0 ) | ||||
|         { | ||||
| @@ -85,12 +86,12 @@ public: | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     void weak_add_ref() // nothrow | ||||
|     void weak_add_ref() BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         ++weak_count_; | ||||
|     } | ||||
|  | ||||
|     void weak_release() // nothrow | ||||
|     void weak_release() BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         if( --weak_count_ == 0 ) | ||||
|         { | ||||
| @@ -98,7 +99,7 @@ public: | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     long use_count() const // nothrow | ||||
|     long use_count() const BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         return use_count_; | ||||
|     } | ||||
|   | ||||
| @@ -18,7 +18,7 @@ | ||||
| // 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> | ||||
| @@ -72,8 +72,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() | ||||
|   | ||||
| @@ -19,7 +19,7 @@ | ||||
| // | ||||
| //  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 | ||||
|  | ||||
| @@ -115,8 +115,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() | ||||
|   | ||||
| @@ -20,7 +20,7 @@ | ||||
| //  formulation | ||||
| // | ||||
|  | ||||
| #include <boost/detail/sp_typeinfo.hpp> | ||||
| #include <boost/smart_ptr/detail/sp_typeinfo_.hpp> | ||||
| #include <boost/config.hpp> | ||||
| #include <atomic.h> | ||||
|  | ||||
| @@ -62,8 +62,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() | ||||
|   | ||||
| @@ -18,7 +18,7 @@ | ||||
| //  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> | ||||
|  | ||||
| @@ -84,8 +84,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() | ||||
|   | ||||
| @@ -15,7 +15,8 @@ | ||||
| //  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> | ||||
| @@ -26,17 +27,17 @@ namespace boost | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| inline void atomic_increment( std::atomic_int_least32_t * pw ) | ||||
| inline void atomic_increment( std::atomic_int_least32_t * pw ) BOOST_SP_NOEXCEPT | ||||
| { | ||||
|     pw->fetch_add( 1, std::memory_order_relaxed ); | ||||
| } | ||||
|  | ||||
| inline std::int_least32_t atomic_decrement( std::atomic_int_least32_t * pw ) | ||||
| inline std::int_least32_t atomic_decrement( std::atomic_int_least32_t * pw ) BOOST_SP_NOEXCEPT | ||||
| { | ||||
|     return pw->fetch_sub( 1, std::memory_order_acq_rel ); | ||||
| } | ||||
|  | ||||
| inline std::int_least32_t atomic_conditional_increment( std::atomic_int_least32_t * pw ) | ||||
| inline std::int_least32_t atomic_conditional_increment( std::atomic_int_least32_t * pw ) BOOST_SP_NOEXCEPT | ||||
| { | ||||
|     // long r = *pw; | ||||
|     // if( r != 0 ) ++*pw; | ||||
| @@ -70,41 +71,41 @@ private: | ||||
|  | ||||
| public: | ||||
|  | ||||
|     sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) | ||||
|     sp_counted_base() BOOST_SP_NOEXCEPT: use_count_( 1 ), weak_count_( 1 ) | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     virtual ~sp_counted_base() // nothrow | ||||
|     virtual ~sp_counted_base() /*BOOST_SP_NOEXCEPT*/ | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     // dispose() is called when use_count_ drops to zero, to release | ||||
|     // the resources managed by *this. | ||||
|  | ||||
|     virtual void dispose() = 0; // nothrow | ||||
|     virtual void dispose() BOOST_SP_NOEXCEPT = 0; | ||||
|  | ||||
|     // destroy() is called when weak_count_ drops to zero. | ||||
|  | ||||
|     virtual void destroy() // nothrow | ||||
|     virtual void destroy() BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         delete this; | ||||
|     } | ||||
|  | ||||
|     virtual void * get_deleter( sp_typeinfo const & ti ) = 0; | ||||
|     virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0; | ||||
|     virtual void * get_untyped_deleter() = 0; | ||||
|     virtual void * get_deleter( sp_typeinfo_ const & ti ) 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() | ||||
|     void add_ref_copy() BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         atomic_increment( &use_count_ ); | ||||
|     } | ||||
|  | ||||
|     bool add_ref_lock() // true on success | ||||
|     bool add_ref_lock() BOOST_SP_NOEXCEPT // true on success | ||||
|     { | ||||
|         return atomic_conditional_increment( &use_count_ ) != 0; | ||||
|     } | ||||
|  | ||||
|     void release() // nothrow | ||||
|     void release() BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         if( atomic_decrement( &use_count_ ) == 1 ) | ||||
|         { | ||||
| @@ -113,12 +114,12 @@ public: | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     void weak_add_ref() // nothrow | ||||
|     void weak_add_ref() BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         atomic_increment( &weak_count_ ); | ||||
|     } | ||||
|  | ||||
|     void weak_release() // nothrow | ||||
|     void weak_release() BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         if( atomic_decrement( &weak_count_ ) == 1 ) | ||||
|         { | ||||
| @@ -126,7 +127,7 @@ public: | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     long use_count() const // nothrow | ||||
|     long use_count() const BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         return use_count_.load( std::memory_order_acquire ); | ||||
|     } | ||||
|   | ||||
| @@ -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> | ||||
|  | ||||
| @@ -109,8 +109,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() | ||||
|   | ||||
| @@ -21,7 +21,7 @@ | ||||
| //  formulation | ||||
| // | ||||
|  | ||||
| #include <boost/detail/sp_typeinfo.hpp> | ||||
| #include <boost/smart_ptr/detail/sp_typeinfo_.hpp> | ||||
| #include <boost/config.hpp> | ||||
|  | ||||
| extern "builtin" void __lwsync(void); | ||||
| @@ -104,8 +104,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() | ||||
|   | ||||
| @@ -25,8 +25,8 @@ | ||||
| // | ||||
|  | ||||
| #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> | ||||
|  | ||||
| namespace boost | ||||
| @@ -67,8 +67,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() | ||||
|   | ||||
| @@ -26,6 +26,7 @@ | ||||
|  | ||||
| #include <boost/checked_delete.hpp> | ||||
| #include <boost/smart_ptr/detail/sp_counted_base.hpp> | ||||
| #include <boost/smart_ptr/detail/sp_noexcept.hpp> | ||||
| #include <boost/core/addressof.hpp> | ||||
|  | ||||
| #if defined(BOOST_SP_USE_QUICK_ALLOCATOR) | ||||
| @@ -55,12 +56,12 @@ namespace detail | ||||
|  | ||||
| template<class D> class local_sp_deleter; | ||||
|  | ||||
| template<class D> D * get_local_deleter( D * /*p*/ ) | ||||
| template<class D> D * get_local_deleter( D * /*p*/ ) BOOST_SP_NOEXCEPT | ||||
| { | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| template<class D> D * get_local_deleter( local_sp_deleter<D> * p ); | ||||
| template<class D> D * get_local_deleter( local_sp_deleter<D> * p ) BOOST_SP_NOEXCEPT; | ||||
|  | ||||
| // | ||||
|  | ||||
| @@ -84,7 +85,7 @@ public: | ||||
| #endif | ||||
|     } | ||||
|  | ||||
|     virtual void dispose() // nothrow | ||||
|     virtual void dispose() BOOST_SP_NOEXCEPT | ||||
|     { | ||||
| #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) | ||||
|         boost::sp_scalar_destructor_hook( px_, sizeof(X), this ); | ||||
| @@ -92,17 +93,17 @@ public: | ||||
|         boost::checked_delete( px_ ); | ||||
|     } | ||||
|  | ||||
|     virtual void * get_deleter( sp_typeinfo const & ) | ||||
|     virtual void * get_deleter( sp_typeinfo_ const & ) BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     virtual void * get_local_deleter( sp_typeinfo const & ) | ||||
|     virtual void * get_local_deleter( sp_typeinfo_ const & ) BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     virtual void * get_untyped_deleter() | ||||
|     virtual void * get_untyped_deleter() BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         return 0; | ||||
|     } | ||||
| @@ -167,22 +168,22 @@ public: | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     virtual void dispose() // nothrow | ||||
|     virtual void dispose() BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         del( ptr ); | ||||
|     } | ||||
|  | ||||
|     virtual void * get_deleter( sp_typeinfo const & ti ) | ||||
|     virtual void * get_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         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 ) | ||||
|     virtual void * get_local_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         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() | ||||
|     virtual void * get_untyped_deleter() BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         return &reinterpret_cast<char&>( del ); | ||||
|     } | ||||
| @@ -241,12 +242,12 @@ public: | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     virtual void dispose() // nothrow | ||||
|     virtual void dispose() BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         d_( p_ ); | ||||
|     } | ||||
|  | ||||
|     virtual void destroy() // nothrow | ||||
|     virtual void destroy() BOOST_SP_NOEXCEPT | ||||
|     { | ||||
| #if !defined( BOOST_NO_CXX11_ALLOCATOR ) | ||||
|  | ||||
| @@ -265,17 +266,17 @@ public: | ||||
|         a2.deallocate( this, 1 ); | ||||
|     } | ||||
|  | ||||
|     virtual void * get_deleter( sp_typeinfo const & ti ) | ||||
|     virtual void * get_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         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 ) | ||||
|     virtual void * get_local_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         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() | ||||
|     virtual void * get_untyped_deleter() BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         return &reinterpret_cast<char&>( d_ ); | ||||
|     } | ||||
|   | ||||
							
								
								
									
										58
									
								
								include/boost/smart_ptr/detail/sp_typeinfo_.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								include/boost/smart_ptr/detail/sp_typeinfo_.hpp
									
									
									
									
									
										Normal 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 | ||||
| @@ -16,6 +16,7 @@ | ||||
| // | ||||
|  | ||||
| #include <boost/smart_ptr/detail/yield_k.hpp> | ||||
| #include <boost/config.hpp> | ||||
| #include <atomic> | ||||
|  | ||||
| namespace boost | ||||
| @@ -32,12 +33,12 @@ public: | ||||
|  | ||||
| public: | ||||
|  | ||||
|     bool try_lock() | ||||
|     bool try_lock() BOOST_NOEXCEPT | ||||
|     { | ||||
|         return !v_.test_and_set( std::memory_order_acquire ); | ||||
|     } | ||||
|  | ||||
|     void lock() | ||||
|     void lock() BOOST_NOEXCEPT | ||||
|     { | ||||
|         for( unsigned k = 0; !try_lock(); ++k ) | ||||
|         { | ||||
| @@ -45,7 +46,7 @@ public: | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     void unlock() | ||||
|     void unlock() BOOST_NOEXCEPT | ||||
|     { | ||||
|         v_ .clear( std::memory_order_release ); | ||||
|     } | ||||
| @@ -63,12 +64,12 @@ public: | ||||
|  | ||||
|     public: | ||||
|  | ||||
|         explicit scoped_lock( spinlock & sp ): sp_( sp ) | ||||
|         explicit scoped_lock( spinlock & sp ) BOOST_NOEXCEPT: sp_( sp ) | ||||
|         { | ||||
|             sp.lock(); | ||||
|         } | ||||
|  | ||||
|         ~scoped_lock() | ||||
|         ~scoped_lock() /*BOOST_NOEXCEPT*/ | ||||
|         { | ||||
|             sp_.unlock(); | ||||
|         } | ||||
|   | ||||
| @@ -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,9 +70,9 @@ 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 ) | ||||
| inline void yield( unsigned k ) BOOST_NOEXCEPT | ||||
| { | ||||
|     if( k < 4 ) | ||||
|     { | ||||
| @@ -89,7 +83,6 @@ inline void yield( unsigned k ) | ||||
|         BOOST_SMT_PAUSE | ||||
|     } | ||||
| #endif | ||||
| #if !BOOST_PLAT_WINDOWS_RUNTIME | ||||
|     else if( k < 32 ) | ||||
|     { | ||||
|         Sleep( 0 ); | ||||
| @@ -98,13 +91,6 @@ inline void yield( unsigned k ) | ||||
|     { | ||||
|         Sleep( 1 ); | ||||
|     } | ||||
| #else | ||||
|     else | ||||
|     { | ||||
|         // Sleep isn't supported on the Windows Runtime. | ||||
|         std::this_thread::yield(); | ||||
|     } | ||||
| #endif | ||||
| } | ||||
|  | ||||
| } // namespace detail | ||||
|   | ||||
							
								
								
									
										37
									
								
								include/boost/smart_ptr/enable_shared_from.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								include/boost/smart_ptr/enable_shared_from.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| #ifndef BOOST_SMART_PTR_ENABLE_SHARED_FROM_HPP_INCLUDED | ||||
| #define BOOST_SMART_PTR_ENABLE_SHARED_FROM_HPP_INCLUDED | ||||
|  | ||||
| //  enable_shared_from.hpp | ||||
| // | ||||
| //  Copyright 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 | ||||
| // | ||||
| //  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> | ||||
| { | ||||
| }; | ||||
|  | ||||
|  | ||||
| template<class T> shared_ptr<T> shared_from( T * p ) | ||||
| { | ||||
|     return shared_ptr<T>( p->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::weak_from_this(), p ); | ||||
| } | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #endif  // #ifndef BOOST_SMART_PTR_ENABLE_SHARED_FROM_HPP_INCLUDED | ||||
| @@ -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; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| /* | ||||
| Copyright 2017 Peter Dimov | ||||
| Copyright 2017 Glen Joseph Fernandes | ||||
| Copyright 2017-2019 Glen Joseph Fernandes | ||||
| (glenjofe@gmail.com) | ||||
|  | ||||
| Distributed under the Boost Software License, Version 1.0. | ||||
| @@ -9,57 +9,64 @@ 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 { | ||||
|  | ||||
| template<class T> | ||||
| inline typename detail::lsp_if_size_array<T>::type | ||||
| 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> | ||||
| inline typename detail::lsp_if_size_array<T>::type | ||||
| make_local_shared(const typename detail::sp_array_element<T>::type& value) | ||||
| 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> | ||||
| inline typename detail::lsp_if_array<T>::type | ||||
| 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> | ||||
| inline typename detail::lsp_if_array<T>::type | ||||
| inline typename enable_if_<is_unbounded_array<T>::value, | ||||
|     local_shared_ptr<T> >::type | ||||
| make_local_shared(std::size_t size, | ||||
|     const typename detail::sp_array_element<T>::type& value) | ||||
|     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> | ||||
| inline typename detail::lsp_if_size_array<T>::type | ||||
| inline typename enable_if_<is_bounded_array<T>::value, | ||||
|     local_shared_ptr<T> >::type | ||||
| make_local_shared_noinit() | ||||
| { | ||||
|     return 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> | ||||
| inline typename detail::lsp_if_array<T>::type | ||||
| inline typename enable_if_<is_unbounded_array<T>::value, | ||||
|     local_shared_ptr<T> >::type | ||||
| make_local_shared_noinit(std::size_t size) | ||||
| { | ||||
|     return 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 */ | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| /* | ||||
| Copyright 2012-2017 Glen Joseph Fernandes | ||||
| Copyright 2012-2019 Glen Joseph Fernandes | ||||
| (glenjofe@gmail.com) | ||||
|  | ||||
| Distributed under the Boost Software License, Version 1.0. | ||||
| @@ -8,57 +8,57 @@ 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 { | ||||
|  | ||||
| template<class T> | ||||
| inline typename detail::sp_if_size_array<T>::type | ||||
| 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 detail::sp_if_size_array<T>::type | ||||
| make_shared(const typename detail::sp_array_element<T>::type& value) | ||||
| 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 detail::sp_if_array<T>::type | ||||
| 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 detail::sp_if_array<T>::type | ||||
| make_shared(std::size_t size, | ||||
|     const typename detail::sp_array_element<T>::type& value) | ||||
| 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 detail::sp_if_size_array<T>::type | ||||
| inline typename enable_if_<is_bounded_array<T>::value, shared_ptr<T> >::type | ||||
| make_shared_noinit() | ||||
| { | ||||
|     return 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 detail::sp_if_array<T>::type | ||||
| inline typename enable_if_<is_unbounded_array<T>::value, shared_ptr<T> >::type | ||||
| make_shared_noinit(std::size_t size) | ||||
| { | ||||
|     return 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 */ | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| /* | ||||
| Copyright 2012-2015 Glen Joseph Fernandes | ||||
| Copyright 2012-2019 Glen Joseph Fernandes | ||||
| (glenjofe@gmail.com) | ||||
|  | ||||
| Distributed under the Boost Software License, Version 1.0. | ||||
| @@ -8,59 +8,18 @@ Distributed under the Boost Software License, Version 1.0. | ||||
| #ifndef BOOST_SMART_PTR_MAKE_UNIQUE_HPP | ||||
| #define BOOST_SMART_PTR_MAKE_UNIQUE_HPP | ||||
|  | ||||
| #include <boost/config.hpp> | ||||
| #include <boost/type_traits/enable_if.hpp> | ||||
| #include <boost/type_traits/is_array.hpp> | ||||
| #include <boost/type_traits/is_unbounded_array.hpp> | ||||
| #include <boost/type_traits/remove_extent.hpp> | ||||
| #include <boost/type_traits/remove_reference.hpp> | ||||
| #include <memory> | ||||
| #include <utility> | ||||
|  | ||||
| namespace boost { | ||||
| namespace detail { | ||||
|  | ||||
| template<class T> | ||||
| struct up_if_object { | ||||
|     typedef std::unique_ptr<T> type; | ||||
| }; | ||||
|  | ||||
| template<class T> | ||||
| struct up_if_object<T[]> { }; | ||||
|  | ||||
| template<class T, std::size_t N> | ||||
| struct up_if_object<T[N]> { }; | ||||
|  | ||||
| template<class T> | ||||
| struct up_if_array { }; | ||||
|  | ||||
| template<class T> | ||||
| struct up_if_array<T[]> { | ||||
|     typedef std::unique_ptr<T[]> type; | ||||
| }; | ||||
|  | ||||
| template<class T> | ||||
| struct up_remove_reference { | ||||
|     typedef T type; | ||||
| }; | ||||
|  | ||||
| template<class T> | ||||
| struct up_remove_reference<T&> { | ||||
|     typedef T type; | ||||
| }; | ||||
|  | ||||
| template<class T> | ||||
| struct up_remove_reference<T&&> { | ||||
|     typedef T type; | ||||
| }; | ||||
|  | ||||
| template<class T> | ||||
| struct up_element { }; | ||||
|  | ||||
| template<class T> | ||||
| struct up_element<T[]> { | ||||
|     typedef T type; | ||||
| }; | ||||
|  | ||||
| } /* detail */ | ||||
|  | ||||
| template<class T> | ||||
| inline typename detail::up_if_object<T>::type | ||||
| inline typename enable_if_<!is_array<T>::value, std::unique_ptr<T> >::type | ||||
| make_unique() | ||||
| { | ||||
|     return std::unique_ptr<T>(new T()); | ||||
| @@ -68,7 +27,7 @@ make_unique() | ||||
|  | ||||
| #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) | ||||
| template<class T, class... Args> | ||||
| inline typename detail::up_if_object<T>::type | ||||
| inline typename enable_if_<!is_array<T>::value, std::unique_ptr<T> >::type | ||||
| make_unique(Args&&... args) | ||||
| { | ||||
|     return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); | ||||
| @@ -76,33 +35,33 @@ make_unique(Args&&... args) | ||||
| #endif | ||||
|  | ||||
| template<class T> | ||||
| inline typename detail::up_if_object<T>::type | ||||
| make_unique(typename detail::up_remove_reference<T>::type&& value) | ||||
| inline typename enable_if_<!is_array<T>::value, std::unique_ptr<T> >::type | ||||
| make_unique(typename remove_reference<T>::type&& value) | ||||
| { | ||||
|     return std::unique_ptr<T>(new T(std::move(value))); | ||||
| } | ||||
|  | ||||
| template<class T> | ||||
| inline typename detail::up_if_object<T>::type | ||||
| inline typename enable_if_<!is_array<T>::value, std::unique_ptr<T> >::type | ||||
| make_unique_noinit() | ||||
| { | ||||
|     return std::unique_ptr<T>(new T); | ||||
| } | ||||
|  | ||||
| template<class T> | ||||
| inline typename detail::up_if_array<T>::type | ||||
| inline typename enable_if_<is_unbounded_array<T>::value, | ||||
|     std::unique_ptr<T> >::type | ||||
| make_unique(std::size_t size) | ||||
| { | ||||
|     return std::unique_ptr<T>(new typename | ||||
|         detail::up_element<T>::type[size]()); | ||||
|     return std::unique_ptr<T>(new typename remove_extent<T>::type[size]()); | ||||
| } | ||||
|  | ||||
| template<class T> | ||||
| inline typename detail::up_if_array<T>::type | ||||
| inline typename enable_if_<is_unbounded_array<T>::value, | ||||
|     std::unique_ptr<T> >::type | ||||
| make_unique_noinit(std::size_t size) | ||||
| { | ||||
|     return std::unique_ptr<T>(new typename | ||||
|         detail::up_element<T>::type[size]); | ||||
|     return std::unique_ptr<T>(new typename remove_extent<T>::type[size]); | ||||
| } | ||||
|  | ||||
| } /* boost */ | ||||
|   | ||||
| @@ -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 | ||||
|  | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -26,7 +26,7 @@ | ||||
| #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/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_disable_deprecated.hpp> | ||||
| @@ -777,12 +777,12 @@ public: | ||||
|         return pn < rhs.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 ); | ||||
|     } | ||||
|  | ||||
|     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 ); | ||||
|     } | ||||
| @@ -797,7 +797,7 @@ public: | ||||
|         return px == r.px && pn == r.pn; | ||||
|     } | ||||
|  | ||||
|     boost::detail::shared_count _internal_count() const BOOST_NOEXCEPT | ||||
|     boost::detail::shared_count _internal_count() const BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|         return pn; | ||||
|     } | ||||
| @@ -1008,7 +1008,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; | ||||
| @@ -1022,7 +1022,7 @@ private: | ||||
|  | ||||
| public: | ||||
|  | ||||
|     esft2_deleter_wrapper() | ||||
|     esft2_deleter_wrapper() BOOST_SP_NOEXCEPT | ||||
|     { | ||||
|     } | ||||
|  | ||||
| @@ -1165,16 +1165,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 ) | ||||
|   | ||||
| @@ -137,6 +137,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 +211,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 +227,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; | ||||
| @@ -249,6 +264,12 @@ 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 | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #endif  // #ifndef BOOST_SMART_PTR_WEAK_PTR_HPP_INCLUDED | ||||
|   | ||||
							
								
								
									
										15
									
								
								test/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								test/CMakeLists.txt
									
									
									
									
									
										Normal 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 Threads::Threads) | ||||
|  | ||||
| endif() | ||||
							
								
								
									
										94
									
								
								test/Jamfile
									
									
									
									
									
								
							
							
						
						
									
										94
									
								
								test/Jamfile
									
									
									
									
									
								
							| @@ -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,34 @@ 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 ; | ||||
|   | ||||
| @@ -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> | ||||
|   | ||||
| @@ -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> | ||||
|   | ||||
| @@ -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> | ||||
|   | ||||
| @@ -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> | ||||
|   | ||||
							
								
								
									
										84
									
								
								test/allocate_unique_aggregate_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								test/allocate_unique_aggregate_test.cpp
									
									
									
									
									
										Normal 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 | ||||
							
								
								
									
										111
									
								
								test/allocate_unique_args_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								test/allocate_unique_args_test.cpp
									
									
									
									
									
										Normal 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 | ||||
							
								
								
									
										166
									
								
								test/allocate_unique_array_construct_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										166
									
								
								test/allocate_unique_array_construct_test.cpp
									
									
									
									
									
										Normal 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 | ||||
							
								
								
									
										228
									
								
								test/allocate_unique_array_noinit_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										228
									
								
								test/allocate_unique_array_noinit_test.cpp
									
									
									
									
									
										Normal 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 | ||||
							
								
								
									
										240
									
								
								test/allocate_unique_array_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										240
									
								
								test/allocate_unique_array_test.cpp
									
									
									
									
									
										Normal 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 | ||||
							
								
								
									
										132
									
								
								test/allocate_unique_array_throws_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								test/allocate_unique_array_throws_test.cpp
									
									
									
									
									
										Normal 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 | ||||
							
								
								
									
										98
									
								
								test/allocate_unique_array_value_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								test/allocate_unique_array_value_test.cpp
									
									
									
									
									
										Normal 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 | ||||
							
								
								
									
										99
									
								
								test/allocate_unique_arrays_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								test/allocate_unique_arrays_test.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,99 @@ | ||||
| /* | ||||
| 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_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; | ||||
| } | ||||
|  | ||||
| int main() | ||||
| { | ||||
|     { | ||||
|         std::unique_ptr<int[][2], | ||||
|             boost::alloc_deleter<int[][2], creator<int> > > result = | ||||
|             boost::allocate_unique<int[][2]>(creator<int>(), 2, {0, 1}); | ||||
|         BOOST_TEST(result[0][0] == 0); | ||||
|         BOOST_TEST(result[0][1] == 1); | ||||
|         BOOST_TEST(result[1][0] == 0); | ||||
|         BOOST_TEST(result[1][1] == 1); | ||||
|     } | ||||
|     { | ||||
|         std::unique_ptr<int[][2], | ||||
|             boost::alloc_deleter<int[2][2], creator<int> > > result = | ||||
|             boost::allocate_unique<int[2][2]>(creator<int>(), {0, 1}); | ||||
|         BOOST_TEST(result[0][0] == 0); | ||||
|         BOOST_TEST(result[0][1] == 1); | ||||
|         BOOST_TEST(result[1][0] == 0); | ||||
|         BOOST_TEST(result[1][1] == 1); | ||||
|     } | ||||
|     { | ||||
|         std::unique_ptr<const int[][2], | ||||
|             boost::alloc_deleter<const int[][2], creator<> > > result = | ||||
|             boost::allocate_unique<const int[][2]>(creator<>(), 2, {0, 1}); | ||||
|         BOOST_TEST(result[0][0] == 0); | ||||
|         BOOST_TEST(result[0][1] == 1); | ||||
|         BOOST_TEST(result[1][0] == 0); | ||||
|         BOOST_TEST(result[1][1] == 1); | ||||
|     } | ||||
|     { | ||||
|         std::unique_ptr<const int[][2], | ||||
|             boost::alloc_deleter<const int[2][2], creator<> > > result = | ||||
|             boost::allocate_unique<const int[2][2]>(creator<>(), {0, 1}); | ||||
|         BOOST_TEST(result[0][0] == 0); | ||||
|         BOOST_TEST(result[0][1] == 1); | ||||
|         BOOST_TEST(result[1][0] == 0); | ||||
|         BOOST_TEST(result[1][1] == 1); | ||||
|     } | ||||
|     return boost::report_errors(); | ||||
| } | ||||
| #else | ||||
| int main() | ||||
| { | ||||
|     return 0; | ||||
| } | ||||
| #endif | ||||
							
								
								
									
										109
									
								
								test/allocate_unique_construct_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								test/allocate_unique_construct_test.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,109 @@ | ||||
| /* | ||||
| 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_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>()); | ||||
|         BOOST_TEST(result.get() != 0); | ||||
|         BOOST_TEST(type::instances == 1); | ||||
|         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<>()); | ||||
|         BOOST_TEST(result.get() != 0); | ||||
|         BOOST_TEST(type::instances == 1); | ||||
|         result.reset(); | ||||
|         BOOST_TEST(type::instances == 0); | ||||
|     } | ||||
|     return boost::report_errors(); | ||||
| } | ||||
| #else | ||||
| int main() | ||||
| { | ||||
|     return 0; | ||||
| } | ||||
| #endif | ||||
							
								
								
									
										126
									
								
								test/allocate_unique_noinit_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										126
									
								
								test/allocate_unique_noinit_test.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,126 @@ | ||||
| /* | ||||
| 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) | ||||
| #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>()); | ||||
|         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<>()); | ||||
|         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>()); | ||||
|         BOOST_TEST(result.get() != 0); | ||||
|         BOOST_TEST(type::instances == 1); | ||||
|         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<>()); | ||||
|         BOOST_TEST(result.get() != 0); | ||||
|         BOOST_TEST(type::instances == 1); | ||||
|         result.reset(); | ||||
|         BOOST_TEST(type::instances == 0); | ||||
|     } | ||||
|     return boost::report_errors(); | ||||
| } | ||||
| #else | ||||
| int main() | ||||
| { | ||||
|     return 0; | ||||
| } | ||||
| #endif | ||||
							
								
								
									
										115
									
								
								test/allocate_unique_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								test/allocate_unique_test.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,115 @@ | ||||
| /* | ||||
| 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) | ||||
| #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() { | ||||
|         ++instances; | ||||
|     } | ||||
|  | ||||
|     ~type() { | ||||
|         --instances; | ||||
|     } | ||||
|  | ||||
| private: | ||||
|     type(const type&); | ||||
|     type& operator=(const type&); | ||||
| }; | ||||
|  | ||||
| unsigned type::instances = 0; | ||||
|  | ||||
| int main() | ||||
| { | ||||
|     { | ||||
|         std::unique_ptr<int, | ||||
|             boost::alloc_deleter<int, creator<int> > > result = | ||||
|             boost::allocate_unique<int>(creator<int>()); | ||||
|         BOOST_TEST(result.get() != 0); | ||||
|         BOOST_TEST(*result == 0); | ||||
|     } | ||||
|     { | ||||
|         std::unique_ptr<const int, | ||||
|             boost::alloc_deleter<const int, creator<> > > result = | ||||
|             boost::allocate_unique<const int>(creator<>()); | ||||
|         BOOST_TEST(result.get() != 0); | ||||
|         BOOST_TEST(*result == 0); | ||||
|     } | ||||
|     BOOST_TEST(type::instances == 0); | ||||
|     { | ||||
|         std::unique_ptr<type, | ||||
|             boost::alloc_deleter<type, creator<type> > > result = | ||||
|             boost::allocate_unique<type>(creator<type>()); | ||||
|         BOOST_TEST(result.get() != 0); | ||||
|         BOOST_TEST(type::instances == 1); | ||||
|         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<>()); | ||||
|         BOOST_TEST(result.get() != 0); | ||||
|         BOOST_TEST(type::instances == 1); | ||||
|         result.reset(); | ||||
|         BOOST_TEST(type::instances == 0); | ||||
|     } | ||||
|     return boost::report_errors(); | ||||
| } | ||||
| #else | ||||
| int main() | ||||
| { | ||||
|     return 0; | ||||
| } | ||||
| #endif | ||||
							
								
								
									
										96
									
								
								test/allocate_unique_throws_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								test/allocate_unique_throws_test.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,96 @@ | ||||
| /* | ||||
| 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) | ||||
| #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 == 0) { | ||||
|             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>()); | ||||
|         BOOST_ERROR("allocate_unique did not throw"); | ||||
|     } catch (...) { | ||||
|         BOOST_TEST(type::instances == 0); | ||||
|     } | ||||
|     try { | ||||
|         boost::allocate_unique<const type>(creator<>()); | ||||
|         BOOST_ERROR("allocate_unique did not throw"); | ||||
|     } catch (...) { | ||||
|         BOOST_TEST(type::instances == 0); | ||||
|     } | ||||
|     return boost::report_errors(); | ||||
| } | ||||
| #else | ||||
| int main() | ||||
| { | ||||
|     return 0; | ||||
| } | ||||
| #endif | ||||
							
								
								
									
										103
									
								
								test/allocate_unique_value_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								test/allocate_unique_value_test.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,103 @@ | ||||
| /* | ||||
| 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) | ||||
| #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: | ||||
|     type(int x, int y) | ||||
|         : value_(x + y) { } | ||||
|  | ||||
|     int sum() const { | ||||
|         return value_; | ||||
|     } | ||||
|  | ||||
| private: | ||||
|     int value_; | ||||
| }; | ||||
|  | ||||
| int main() | ||||
| { | ||||
|     { | ||||
|         std::unique_ptr<int, | ||||
|             boost::alloc_deleter<int, creator<int> > > result = | ||||
|             boost::allocate_unique<int>(creator<int>(), 1); | ||||
|         BOOST_TEST(result.get() != 0); | ||||
|         BOOST_TEST(*result == 1); | ||||
|     } | ||||
|     { | ||||
|         std::unique_ptr<const int, | ||||
|             boost::alloc_deleter<const int, creator<> > > result = | ||||
|             boost::allocate_unique<const int>(creator<>(), 1); | ||||
|         BOOST_TEST(result.get() != 0); | ||||
|         BOOST_TEST(*result == 1); | ||||
|     } | ||||
|     { | ||||
|         std::unique_ptr<type, | ||||
|             boost::alloc_deleter<type, creator<type> > > result = | ||||
|             boost::allocate_unique<type>(creator<type>(), type(1, 2)); | ||||
|         BOOST_TEST(result.get() != 0); | ||||
|         BOOST_TEST(result->sum() == 3); | ||||
|     } | ||||
|     { | ||||
|         std::unique_ptr<const type, | ||||
|             boost::alloc_deleter<const type, creator<> > > result = | ||||
|             boost::allocate_unique<const type>(creator<>(), type(1, 2)); | ||||
|         BOOST_TEST(result.get() != 0); | ||||
|         BOOST_TEST(result->sum() == 3); | ||||
|     } | ||||
|     return boost::report_errors(); | ||||
| } | ||||
| #else | ||||
| int main() | ||||
| { | ||||
|     return 0; | ||||
| } | ||||
| #endif | ||||
| @@ -9,7 +9,7 @@ | ||||
| // | ||||
|  | ||||
| #include <boost/detail/atomic_count.hpp> | ||||
| #include <boost/detail/lightweight_test.hpp> | ||||
| #include <boost/core/lightweight_test.hpp> | ||||
|  | ||||
| int main() | ||||
| { | ||||
|   | ||||
| @@ -9,7 +9,7 @@ | ||||
| // | ||||
|  | ||||
| #include <boost/detail/atomic_count.hpp> | ||||
| #include <boost/detail/lightweight_test.hpp> | ||||
| #include <boost/core/lightweight_test.hpp> | ||||
|  | ||||
| int main() | ||||
| { | ||||
|   | ||||
| @@ -18,10 +18,10 @@ | ||||
| BOOST_PRAGMA_MESSAGE("Skipping test due to BOOST_NO_CXX11_CONSTEXPR") | ||||
| int main() {} | ||||
|  | ||||
| #elif BOOST_WORKAROUND( BOOST_MSVC, < 1920 ) | ||||
| #elif BOOST_WORKAROUND( BOOST_MSVC, < 1930 ) | ||||
|  | ||||
| // MSVC does not implement static initialization for constexpr | ||||
| BOOST_PRAGMA_MESSAGE("Skipping test due to BOOST_MSVC < 1920") | ||||
| // MSVC does not implement static initialization for constexpr constructors | ||||
| BOOST_PRAGMA_MESSAGE("Skipping test due to BOOST_MSVC < 1930") | ||||
| int main() {} | ||||
|  | ||||
| #elif defined(__clang__) && defined( BOOST_NO_CXX14_CONSTEXPR ) | ||||
|   | ||||
| @@ -19,7 +19,7 @@ int main() | ||||
| #else | ||||
|  | ||||
| #include <boost/shared_ptr.hpp> | ||||
| #include <boost/detail/lightweight_test.hpp> | ||||
| #include <boost/core/lightweight_test.hpp> | ||||
| #include <memory> | ||||
|  | ||||
| struct X | ||||
|   | ||||
							
								
								
									
										18
									
								
								test/cmake_install_test/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								test/cmake_install_test/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | ||||
| # 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 | ||||
|  | ||||
| cmake_minimum_required(VERSION 3.5...3.16) | ||||
|  | ||||
| project(cmake_subdir_test LANGUAGES CXX) | ||||
|  | ||||
| find_package(boost_smart_ptr REQUIRED) | ||||
| find_package(boost_core REQUIRED) | ||||
|  | ||||
| add_executable(quick ../quick.cpp) | ||||
| target_link_libraries(quick Boost::smart_ptr Boost::core) | ||||
|  | ||||
| enable_testing() | ||||
| add_test(quick quick) | ||||
|  | ||||
| add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -C $<CONFIG>) | ||||
| @@ -2,7 +2,7 @@ | ||||
| # 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 | ||||
|  | ||||
| cmake_minimum_required(VERSION 3.5) | ||||
| cmake_minimum_required(VERSION 3.5...3.16) | ||||
|  | ||||
| project(cmake_subdir_test LANGUAGES CXX) | ||||
|  | ||||
| @@ -11,7 +11,6 @@ add_subdirectory(../../../assert boostorg/assert) | ||||
| add_subdirectory(../../../config boostorg/config) | ||||
| add_subdirectory(../../../core boostorg/core) | ||||
| add_subdirectory(../../../move boostorg/move) | ||||
| add_subdirectory(../../../predef boostorg/predef) | ||||
| add_subdirectory(../../../static_assert boostorg/static_assert) | ||||
| add_subdirectory(../../../throw_exception boostorg/throw_exception) | ||||
| add_subdirectory(../../../type_traits boostorg/type_traits) | ||||
|   | ||||
| @@ -11,7 +11,7 @@ | ||||
| #include <boost/pointer_cast.hpp> | ||||
|  | ||||
| #include <boost/config.hpp> | ||||
| #include <boost/detail/lightweight_test.hpp> | ||||
| #include <boost/core/lightweight_test.hpp> | ||||
| #include <boost/get_pointer.hpp> | ||||
| #include <boost/shared_ptr.hpp> | ||||
|  | ||||
|   | ||||
| @@ -14,7 +14,7 @@ | ||||
| #include <boost/enable_shared_from_this.hpp> | ||||
| #include <boost/shared_ptr.hpp> | ||||
| #include <boost/weak_ptr.hpp> | ||||
| #include <boost/detail/lightweight_test.hpp> | ||||
| #include <boost/core/lightweight_test.hpp> | ||||
| #include <boost/config.hpp> | ||||
| #include <memory> | ||||
| #include <string> | ||||
|   | ||||
| @@ -14,7 +14,7 @@ | ||||
|  | ||||
| #include <boost/enable_shared_from_this.hpp> | ||||
| #include <boost/shared_ptr.hpp> | ||||
| #include <boost/detail/lightweight_test.hpp> | ||||
| #include <boost/core/lightweight_test.hpp> | ||||
|  | ||||
| // | ||||
|  | ||||
|   | ||||
| @@ -11,7 +11,7 @@ | ||||
|  | ||||
| #include <boost/enable_shared_from_this.hpp> | ||||
| #include <boost/shared_ptr.hpp> | ||||
| #include <boost/detail/lightweight_test.hpp> | ||||
| #include <boost/core/lightweight_test.hpp> | ||||
|  | ||||
| // | ||||
|  | ||||
|   | ||||
| @@ -9,7 +9,7 @@ | ||||
| // | ||||
|  | ||||
| #include <boost/shared_array.hpp> | ||||
| #include <boost/detail/lightweight_test.hpp> | ||||
| #include <boost/core/lightweight_test.hpp> | ||||
|  | ||||
| struct deleter | ||||
| { | ||||
|   | ||||
| @@ -9,7 +9,7 @@ | ||||
| // | ||||
|  | ||||
| #include <boost/shared_ptr.hpp> | ||||
| #include <boost/detail/lightweight_test.hpp> | ||||
| #include <boost/core/lightweight_test.hpp> | ||||
|  | ||||
| struct deleter | ||||
| { | ||||
|   | ||||
| @@ -26,7 +26,7 @@ | ||||
| // http://www.boost.org/LICENSE_1_0.txt) | ||||
| // | ||||
|  | ||||
| #include <boost/detail/lightweight_test.hpp> | ||||
| #include <boost/core/lightweight_test.hpp> | ||||
| #include <boost/intrusive_ptr.hpp> | ||||
| #include <boost/detail/atomic_count.hpp> | ||||
| #include <boost/config.hpp> | ||||
| @@ -41,7 +41,7 @@ class base | ||||
| { | ||||
| private: | ||||
|  | ||||
|     boost::detail::atomic_count use_count_; | ||||
|     mutable boost::detail::atomic_count use_count_; | ||||
|  | ||||
|     base(base const &); | ||||
|     base & operator=(base const &); | ||||
| @@ -69,24 +69,24 @@ public: | ||||
|  | ||||
| #if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) | ||||
|  | ||||
|     inline friend void intrusive_ptr_add_ref(base * p) | ||||
|     inline friend void intrusive_ptr_add_ref(base const * p) | ||||
|     { | ||||
|         ++p->use_count_; | ||||
|     } | ||||
|  | ||||
|     inline friend void intrusive_ptr_release(base * p) | ||||
|     inline friend void intrusive_ptr_release(base const * p) | ||||
|     { | ||||
|         if(--p->use_count_ == 0) delete p; | ||||
|     } | ||||
|  | ||||
| #else | ||||
|  | ||||
|     void add_ref() | ||||
|     void add_ref() const | ||||
|     { | ||||
|         ++use_count_; | ||||
|     } | ||||
|  | ||||
|     void release() | ||||
|     void release() const | ||||
|     { | ||||
|         if(--use_count_ == 0) delete this; | ||||
|     } | ||||
| @@ -103,12 +103,12 @@ long base::instances = 0; | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| inline void intrusive_ptr_add_ref(N::base * p) | ||||
| inline void intrusive_ptr_add_ref(N::base const * p) | ||||
| { | ||||
|     p->add_ref(); | ||||
| } | ||||
|  | ||||
| inline void intrusive_ptr_release(N::base * p) | ||||
| inline void intrusive_ptr_release(N::base const * p) | ||||
| { | ||||
|     p->release(); | ||||
| } | ||||
| @@ -209,6 +209,58 @@ int main() | ||||
|         BOOST_TEST( N::base::instances == 0 ); | ||||
|     } | ||||
|  | ||||
|     { | ||||
|         boost::intrusive_ptr<X> px( new Y ); | ||||
|  | ||||
|         X * px2 = px.get(); | ||||
|  | ||||
|         boost::intrusive_ptr<Y> py = boost::static_pointer_cast<Y>( std::move( px ) ); | ||||
|         BOOST_TEST( py.get() == px2 ); | ||||
|         BOOST_TEST( px.get() == 0 ); | ||||
|         BOOST_TEST( py->use_count() == 1 ); | ||||
|     } | ||||
|  | ||||
|     BOOST_TEST( N::base::instances == 0 ); | ||||
|  | ||||
|     { | ||||
|         boost::intrusive_ptr<X const> px( new X ); | ||||
|  | ||||
|         X const * px2 = px.get(); | ||||
|  | ||||
|         boost::intrusive_ptr<X> px3 = boost::const_pointer_cast<X>( std::move( px ) ); | ||||
|         BOOST_TEST( px3.get() == px2 ); | ||||
|         BOOST_TEST( px.get() == 0 ); | ||||
|         BOOST_TEST( px3->use_count() == 1 ); | ||||
|     } | ||||
|  | ||||
|     BOOST_TEST( N::base::instances == 0 ); | ||||
|  | ||||
|     { | ||||
|         boost::intrusive_ptr<X> px( new Y ); | ||||
|  | ||||
|         X * px2 = px.get(); | ||||
|  | ||||
|         boost::intrusive_ptr<Y> py = boost::dynamic_pointer_cast<Y>( std::move( px ) ); | ||||
|         BOOST_TEST( py.get() == px2 ); | ||||
|         BOOST_TEST( px.get() == 0 ); | ||||
|         BOOST_TEST( py->use_count() == 1 ); | ||||
|     } | ||||
|  | ||||
|     BOOST_TEST( N::base::instances == 0 ); | ||||
|  | ||||
|     { | ||||
|         boost::intrusive_ptr<X> px( new X ); | ||||
|  | ||||
|         X * px2 = px.get(); | ||||
|  | ||||
|         boost::intrusive_ptr<Y> py = boost::dynamic_pointer_cast<Y>( std::move( px ) ); | ||||
|         BOOST_TEST( py.get() == 0 ); | ||||
|         BOOST_TEST( px.get() == px2 ); | ||||
|         BOOST_TEST( px->use_count() == 1 ); | ||||
|     } | ||||
|  | ||||
|     BOOST_TEST( N::base::instances == 0 ); | ||||
|  | ||||
|     return boost::report_errors(); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -26,7 +26,7 @@ | ||||
| // http://www.boost.org/LICENSE_1_0.txt) | ||||
| // | ||||
|  | ||||
| #include <boost/detail/lightweight_test.hpp> | ||||
| #include <boost/core/lightweight_test.hpp> | ||||
| #include <boost/intrusive_ptr.hpp> | ||||
| #include <boost/detail/atomic_count.hpp> | ||||
| #include <boost/config.hpp> | ||||
| @@ -42,7 +42,7 @@ class base | ||||
| { | ||||
| private: | ||||
|  | ||||
|     boost::detail::atomic_count use_count_; | ||||
|     mutable boost::detail::atomic_count use_count_; | ||||
|  | ||||
|     base(base const &); | ||||
|     base & operator=(base const &); | ||||
| @@ -70,24 +70,24 @@ public: | ||||
|  | ||||
| #if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) | ||||
|  | ||||
|     inline friend void intrusive_ptr_add_ref(base * p) | ||||
|     inline friend void intrusive_ptr_add_ref(base const * p) | ||||
|     { | ||||
|         ++p->use_count_; | ||||
|     } | ||||
|  | ||||
|     inline friend void intrusive_ptr_release(base * p) | ||||
|     inline friend void intrusive_ptr_release(base const * p) | ||||
|     { | ||||
|         if(--p->use_count_ == 0) delete p; | ||||
|     } | ||||
|  | ||||
| #else | ||||
|  | ||||
|     void add_ref() | ||||
|     void add_ref() const | ||||
|     { | ||||
|         ++use_count_; | ||||
|     } | ||||
|  | ||||
|     void release() | ||||
|     void release() const | ||||
|     { | ||||
|         if(--use_count_ == 0) delete this; | ||||
|     } | ||||
| @@ -104,12 +104,12 @@ long base::instances = 0; | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| inline void intrusive_ptr_add_ref(N::base * p) | ||||
| inline void intrusive_ptr_add_ref(N::base const * p) | ||||
| { | ||||
|     p->add_ref(); | ||||
| } | ||||
|  | ||||
| inline void intrusive_ptr_release(N::base * p) | ||||
| inline void intrusive_ptr_release(N::base const * p) | ||||
| { | ||||
|     p->release(); | ||||
| } | ||||
| @@ -303,14 +303,211 @@ namespace n_assignment | ||||
|  | ||||
| void copy_assignment() | ||||
| { | ||||
|     BOOST_TEST( N::base::instances == 0 ); | ||||
|  | ||||
|     { | ||||
|         boost::intrusive_ptr<X> p1; | ||||
|  | ||||
|         p1 = p1; | ||||
|  | ||||
|         BOOST_TEST(p1 == p1); | ||||
|         BOOST_TEST(p1? false: true); | ||||
|         BOOST_TEST(!p1); | ||||
|         BOOST_TEST(p1.get() == 0); | ||||
|  | ||||
|         boost::intrusive_ptr<X> p2; | ||||
|  | ||||
|         p1 = p2; | ||||
|  | ||||
|         BOOST_TEST(p1 == p2); | ||||
|         BOOST_TEST(p1? false: true); | ||||
|         BOOST_TEST(!p1); | ||||
|         BOOST_TEST(p1.get() == 0); | ||||
|  | ||||
|         boost::intrusive_ptr<X> p3(p1); | ||||
|  | ||||
|         p1 = p3; | ||||
|  | ||||
|         BOOST_TEST(p1 == p3); | ||||
|         BOOST_TEST(p1? false: true); | ||||
|         BOOST_TEST(!p1); | ||||
|         BOOST_TEST(p1.get() == 0); | ||||
|  | ||||
|         BOOST_TEST(N::base::instances == 0); | ||||
|  | ||||
|         boost::intrusive_ptr<X> p4(new X); | ||||
|  | ||||
|         BOOST_TEST(N::base::instances == 1); | ||||
|  | ||||
|         p1 = p4; | ||||
|  | ||||
|         BOOST_TEST(N::base::instances == 1); | ||||
|  | ||||
|         BOOST_TEST(p1 == p4); | ||||
|  | ||||
|         BOOST_TEST(p1->use_count() == 2); | ||||
|  | ||||
|         p1 = p2; | ||||
|  | ||||
|         BOOST_TEST(p1 == p2); | ||||
|         BOOST_TEST(N::base::instances == 1); | ||||
|  | ||||
|         p4 = p3; | ||||
|  | ||||
|         BOOST_TEST(p4 == p3); | ||||
|         BOOST_TEST(N::base::instances == 0); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void conversion_assignment() | ||||
| { | ||||
|     BOOST_TEST( N::base::instances == 0 ); | ||||
|  | ||||
|     { | ||||
|         boost::intrusive_ptr<X> p1; | ||||
|  | ||||
|         boost::intrusive_ptr<Y> p2; | ||||
|  | ||||
|         p1 = p2; | ||||
|  | ||||
|         BOOST_TEST(p1 == p2); | ||||
|         BOOST_TEST(p1? false: true); | ||||
|         BOOST_TEST(!p1); | ||||
|         BOOST_TEST(p1.get() == 0); | ||||
|  | ||||
|         BOOST_TEST(N::base::instances == 0); | ||||
|  | ||||
|         boost::intrusive_ptr<Y> p4(new Y); | ||||
|  | ||||
|         BOOST_TEST(N::base::instances == 1); | ||||
|         BOOST_TEST(p4->use_count() == 1); | ||||
|  | ||||
|         boost::intrusive_ptr<X> p5(p4); | ||||
|         BOOST_TEST(p4->use_count() == 2); | ||||
|  | ||||
|         p1 = p4; | ||||
|  | ||||
|         BOOST_TEST(N::base::instances == 1); | ||||
|  | ||||
|         BOOST_TEST(p1 == p4); | ||||
|  | ||||
|         BOOST_TEST(p1->use_count() == 3); | ||||
|         BOOST_TEST(p4->use_count() == 3); | ||||
|  | ||||
|         p1 = p2; | ||||
|  | ||||
|         BOOST_TEST(p1 == p2); | ||||
|         BOOST_TEST(N::base::instances == 1); | ||||
|         BOOST_TEST(p4->use_count() == 2); | ||||
|  | ||||
|         p4 = p2; | ||||
|         p5 = p2; | ||||
|  | ||||
|         BOOST_TEST(p4 == p2); | ||||
|         BOOST_TEST(N::base::instances == 0); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void pointer_assignment() | ||||
| { | ||||
|     BOOST_TEST( N::base::instances == 0 ); | ||||
|  | ||||
|     { | ||||
|         boost::intrusive_ptr<X> p1; | ||||
|  | ||||
|         p1 = p1.get(); | ||||
|  | ||||
|         BOOST_TEST(p1 == p1); | ||||
|         BOOST_TEST(p1? false: true); | ||||
|         BOOST_TEST(!p1); | ||||
|         BOOST_TEST(p1.get() == 0); | ||||
|  | ||||
|         boost::intrusive_ptr<X> p2; | ||||
|  | ||||
|         p1 = p2.get(); | ||||
|  | ||||
|         BOOST_TEST(p1 == p2); | ||||
|         BOOST_TEST(p1? false: true); | ||||
|         BOOST_TEST(!p1); | ||||
|         BOOST_TEST(p1.get() == 0); | ||||
|  | ||||
|         boost::intrusive_ptr<X> p3(p1); | ||||
|  | ||||
|         p1 = p3.get(); | ||||
|  | ||||
|         BOOST_TEST(p1 == p3); | ||||
|         BOOST_TEST(p1? false: true); | ||||
|         BOOST_TEST(!p1); | ||||
|         BOOST_TEST(p1.get() == 0); | ||||
|  | ||||
|         BOOST_TEST(N::base::instances == 0); | ||||
|  | ||||
|         boost::intrusive_ptr<X> p4(new X); | ||||
|  | ||||
|         BOOST_TEST(N::base::instances == 1); | ||||
|  | ||||
|         p1 = p4.get(); | ||||
|  | ||||
|         BOOST_TEST(N::base::instances == 1); | ||||
|  | ||||
|         BOOST_TEST(p1 == p4); | ||||
|  | ||||
|         BOOST_TEST(p1->use_count() == 2); | ||||
|  | ||||
|         p1 = p2.get(); | ||||
|  | ||||
|         BOOST_TEST(p1 == p2); | ||||
|         BOOST_TEST(N::base::instances == 1); | ||||
|  | ||||
|         p4 = p3.get(); | ||||
|  | ||||
|         BOOST_TEST(p4 == p3); | ||||
|         BOOST_TEST(N::base::instances == 0); | ||||
|     } | ||||
|  | ||||
|     { | ||||
|         boost::intrusive_ptr<X> p1; | ||||
|  | ||||
|         boost::intrusive_ptr<Y> p2; | ||||
|  | ||||
|         p1 = p2.get(); | ||||
|  | ||||
|         BOOST_TEST(p1 == p2); | ||||
|         BOOST_TEST(p1? false: true); | ||||
|         BOOST_TEST(!p1); | ||||
|         BOOST_TEST(p1.get() == 0); | ||||
|  | ||||
|         BOOST_TEST(N::base::instances == 0); | ||||
|  | ||||
|         boost::intrusive_ptr<Y> p4(new Y); | ||||
|  | ||||
|         BOOST_TEST(N::base::instances == 1); | ||||
|         BOOST_TEST(p4->use_count() == 1); | ||||
|  | ||||
|         boost::intrusive_ptr<X> p5(p4); | ||||
|         BOOST_TEST(p4->use_count() == 2); | ||||
|  | ||||
|         p1 = p4.get(); | ||||
|  | ||||
|         BOOST_TEST(N::base::instances == 1); | ||||
|  | ||||
|         BOOST_TEST(p1 == p4); | ||||
|  | ||||
|         BOOST_TEST(p1->use_count() == 3); | ||||
|         BOOST_TEST(p4->use_count() == 3); | ||||
|  | ||||
|         p1 = p2.get(); | ||||
|  | ||||
|         BOOST_TEST(p1 == p2); | ||||
|         BOOST_TEST(N::base::instances == 1); | ||||
|         BOOST_TEST(p4->use_count() == 2); | ||||
|  | ||||
|         p4 = p2.get(); | ||||
|         p5 = p2.get(); | ||||
|  | ||||
|         BOOST_TEST(p4 == p2); | ||||
|         BOOST_TEST(N::base::instances == 0); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void test() | ||||
| @@ -707,15 +904,137 @@ namespace n_static_cast | ||||
|  | ||||
| void test() | ||||
| { | ||||
|     { | ||||
|         boost::intrusive_ptr<X> px(new Y); | ||||
|  | ||||
|         boost::intrusive_ptr<Y> py = boost::static_pointer_cast<Y>(px); | ||||
|         BOOST_TEST(px.get() == py.get()); | ||||
|         BOOST_TEST(px->use_count() == 2); | ||||
|         BOOST_TEST(py->use_count() == 2); | ||||
|  | ||||
|         boost::intrusive_ptr<X> px2(py); | ||||
|         BOOST_TEST(px2.get() == px.get()); | ||||
|     } | ||||
|  | ||||
|     BOOST_TEST( N::base::instances == 0 ); | ||||
|  | ||||
|     { | ||||
|         boost::intrusive_ptr<Y> py = boost::static_pointer_cast<Y>( boost::intrusive_ptr<X>(new Y) ); | ||||
|         BOOST_TEST(py.get() != 0); | ||||
|         BOOST_TEST(py->use_count() == 1); | ||||
|     } | ||||
|  | ||||
|     BOOST_TEST( N::base::instances == 0 ); | ||||
| } | ||||
|  | ||||
| } // namespace n_static_cast | ||||
|  | ||||
| namespace n_const_cast | ||||
| { | ||||
|  | ||||
| void test() | ||||
| { | ||||
|     { | ||||
|         boost::intrusive_ptr<X const> px; | ||||
|  | ||||
|         boost::intrusive_ptr<X> px2 = boost::const_pointer_cast<X>(px); | ||||
|         BOOST_TEST(px2.get() == 0); | ||||
|     } | ||||
|  | ||||
|     { | ||||
|         boost::intrusive_ptr<X> px2 = boost::const_pointer_cast<X>( boost::intrusive_ptr<X const>() ); | ||||
|         BOOST_TEST(px2.get() == 0); | ||||
|     } | ||||
|  | ||||
|     BOOST_TEST( N::base::instances == 0 ); | ||||
|  | ||||
|     { | ||||
|         boost::intrusive_ptr<X const> px(new X); | ||||
|  | ||||
|         boost::intrusive_ptr<X> px2 = boost::const_pointer_cast<X>(px); | ||||
|         BOOST_TEST(px2.get() == px.get()); | ||||
|         BOOST_TEST(px2->use_count() == 2); | ||||
|         BOOST_TEST(px->use_count() == 2); | ||||
|     } | ||||
|  | ||||
|     BOOST_TEST( N::base::instances == 0 ); | ||||
|  | ||||
|     { | ||||
|         boost::intrusive_ptr<X> px = boost::const_pointer_cast<X>( boost::intrusive_ptr<X const>(new X) ); | ||||
|         BOOST_TEST(px.get() != 0); | ||||
|         BOOST_TEST(px->use_count() == 1); | ||||
|     } | ||||
|  | ||||
|     BOOST_TEST( N::base::instances == 0 ); | ||||
| } | ||||
|  | ||||
| } // namespace n_const_cast | ||||
|  | ||||
| namespace n_dynamic_cast | ||||
| { | ||||
|  | ||||
| void test() | ||||
| { | ||||
|     { | ||||
|         boost::intrusive_ptr<X> px; | ||||
|  | ||||
|         boost::intrusive_ptr<Y> py = boost::dynamic_pointer_cast<Y>(px); | ||||
|         BOOST_TEST(py.get() == 0); | ||||
|     } | ||||
|  | ||||
|     { | ||||
|         boost::intrusive_ptr<Y> py = boost::dynamic_pointer_cast<Y>( boost::intrusive_ptr<X>() ); | ||||
|         BOOST_TEST(py.get() == 0); | ||||
|     } | ||||
|  | ||||
|     { | ||||
|         boost::intrusive_ptr<X> px(static_cast<X*>(0)); | ||||
|  | ||||
|         boost::intrusive_ptr<Y> py = boost::dynamic_pointer_cast<Y>(px); | ||||
|         BOOST_TEST(py.get() == 0); | ||||
|     } | ||||
|  | ||||
|     { | ||||
|         boost::intrusive_ptr<Y> py = boost::dynamic_pointer_cast<Y>( boost::intrusive_ptr<X>(static_cast<X*>(0)) ); | ||||
|         BOOST_TEST(py.get() == 0); | ||||
|     } | ||||
|  | ||||
|     { | ||||
|         boost::intrusive_ptr<X> px(new X); | ||||
|  | ||||
|         boost::intrusive_ptr<Y> py = boost::dynamic_pointer_cast<Y>(px); | ||||
|         BOOST_TEST(py.get() == 0); | ||||
|     } | ||||
|  | ||||
|     BOOST_TEST( N::base::instances == 0 ); | ||||
|  | ||||
|     { | ||||
|         boost::intrusive_ptr<Y> py = boost::dynamic_pointer_cast<Y>( boost::intrusive_ptr<X>(new X) ); | ||||
|         BOOST_TEST(py.get() == 0); | ||||
|     } | ||||
|  | ||||
|     BOOST_TEST( N::base::instances == 0 ); | ||||
|  | ||||
|     { | ||||
|         boost::intrusive_ptr<X> px(new Y); | ||||
|  | ||||
|         boost::intrusive_ptr<Y> py = boost::dynamic_pointer_cast<Y>(px); | ||||
|         BOOST_TEST(py.get() == px.get()); | ||||
|         BOOST_TEST(py->use_count() == 2); | ||||
|         BOOST_TEST(px->use_count() == 2); | ||||
|     } | ||||
|  | ||||
|     BOOST_TEST( N::base::instances == 0 ); | ||||
|  | ||||
|     { | ||||
|         boost::intrusive_ptr<X> px(new Y); | ||||
|  | ||||
|         boost::intrusive_ptr<Y> py = boost::dynamic_pointer_cast<Y>( boost::intrusive_ptr<X>(new Y) ); | ||||
|         BOOST_TEST(py.get() != 0); | ||||
|         BOOST_TEST(py->use_count() == 1); | ||||
|     } | ||||
|  | ||||
|     BOOST_TEST( N::base::instances == 0 ); | ||||
| } | ||||
|  | ||||
| } // namespace n_dynamic_cast | ||||
| @@ -779,6 +1098,7 @@ int main() | ||||
|     n_swap::test(); | ||||
|     n_comparison::test(); | ||||
|     n_static_cast::test(); | ||||
|     n_const_cast::test(); | ||||
|     n_dynamic_cast::test(); | ||||
|  | ||||
|     n_transitive::test(); | ||||
|   | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user