Compare commits

...

51 Commits

Author SHA1 Message Date
Peter Dimov
54b5498208 Manually convince clang-cl to fail shared_from_fail and weak_from_fail 2020-04-02 04:01:21 +03:00
Peter Dimov
da81452f1f Make shared_from_this and weak_from_this private in enable_shared_from. Fixes #75. 2020-04-02 02:16:59 +03:00
Peter Dimov
7b9a969215 Add deduction guides to shared_ptr and weak_ptr. Fixes #73. 2020-04-02 00:28:02 +03:00
Glen Fernandes
91cd83e5bf Correct make_unique_noinit example 2020-02-13 21:36:58 -05:00
Peter Dimov
2fdb8c4b0a Fix Travis issues; remove unnecessary jobs 2020-01-14 19:16:05 +02:00
Peter Dimov
e806b53433 Update Travis 2020-01-14 17:04:51 +02:00
Peter Dimov
e0c7bd9a7e Don't build tests when installing; link to Threads::Threads in tests because of lw_thread_test.cpp 2020-01-10 00:54:01 +02:00
Peter Dimov
766ab05a12 Update submodule libs/preprocessor on Travis (needed by CMake tests) 2020-01-09 15:53:38 +02:00
Peter Dimov
05cbefd28e Update submodule tools/cmake on Travis 2020-01-09 01:41:15 +02:00
Peter Dimov
bfbdf4f45f Add CMake install support, tests 2020-01-08 05:08:37 +02:00
Peter Dimov
169c0cd52a Remove lwm_nop.hpp; add lwm_std_mutex.hpp 2020-01-08 03:57:13 +02:00
Peter Dimov
7d70691a16 Remove Windows Runtime workaround from yield_k.hpp; it's no longer relevant, Sleep is available 2020-01-08 03:09:11 +02:00
Peter Dimov
90c27d7cfa Remove Windows Runtime workaround from lwm_win32_cs.hpp; it's no longer relevant, InitializeCriticalSection is available 2020-01-08 02:55:14 +02:00
Glen Fernandes
43d1fe12c5 Include lightweight_test from core and workaround from config 2020-01-01 08:31:25 -05:00
Peter Dimov
a2749dddb4 Disable 32 bit clang-win to avoid mspdbcore.dll errors 2019-12-05 15:49:48 +02:00
Peter Dimov
a71e62146c Add VS2019 to Appveyor; separate clang-win into its own job 2019-11-24 00:05:38 +02:00
Glen Fernandes
274ec17836 Even more documentation corrections 2019-09-15 02:06:23 -04:00
Glen Fernandes
a7341070f1 More documentation corrections 2019-09-03 11:53:42 -04:00
Glen Fernandes
a6323354cd Update constraints and synopsis in documentation 2019-09-02 22:10:09 -04:00
Glen Fernandes
f788448101 Document alloc_deleter 2019-08-30 12:52:50 -04:00
Glen Fernandes
283f2d2a11 Simplify synopsis using alias template 2019-08-30 12:04:09 -04:00
Glen Fernandes
034f94617d Workaround for VC10 unique_ptr operator-> 2019-08-30 12:03:36 -04:00
Glen Fernandes
6a5f67b3a2 Disable tests on VC10 which lacks conforming unique_ptr 2019-08-30 10:50:56 -04:00
Glen Fernandes
dcd3c8ef80 In test cases, include allocate_unique first 2019-08-30 08:17:54 -04:00
Glen Fernandes
bb2a453ff6 Add additional test cases 2019-08-30 08:16:11 -04:00
Glen Fernandes
e56eec70ca Call to_address in the scalar destroy case too 2019-08-30 07:39:02 -04:00
Glen Fernandes
60c26acab8 Implement allocate_unique 2019-08-30 00:31:28 -04:00
Peter Dimov
00f6b5dcb0 Split gcc 8/9 Travis jobs (again) due to log size 2019-08-29 13:20:36 +03:00
Peter Dimov
6195ae1eb0 Disable -Wdelete-non-virtual-dtor 2019-08-29 12:27:51 +03:00
Peter Dimov
30291c406a Update .travis.yml 2019-08-29 01:01:52 +03:00
Peter Dimov
610f19f247 Merge pull request #69 from CJBussey/feature/fix_warning_implicit_conversion
atomic_count_std_atomic: static_cast v to std::int_least32_t
2019-06-23 04:21:52 -07:00
Carl Bussey
876d40a9ab atomic_count_std_atomic: static_cast v to std::int_least32_t
* fix implicit conversion warning
2019-06-18 11:44:17 +02:00
Peter Dimov
e4d642c46a Revert Travis to Trusty 2019-05-30 02:42:39 +03:00
Glen Fernandes
3dffa64f58 Bind allocator to element type, not scalar type 2019-05-15 07:33:04 -04:00
Glen Fernandes
af92bd89ef allocation_ptr will be modified, renamed, and moved to detail 2019-05-05 22:21:22 -04:00
Glen Fernandes
4742143605 Support allocation_ptr of const and volatile types 2019-05-04 09:43:11 -04:00
Glen Fernandes
872bf10347 Move construct and destroy from Smart_Ptr to Core 2019-05-03 17:39:25 -04:00
Glen Fernandes
c0ae9b3728 Implement allocation_ptr 2019-05-02 19:26:29 -04:00
Glen Fernandes
1298c2e8e5 Include sp_noexcept.hpp in sp_construct.hpp 2019-05-02 18:00:53 -04:00
Glen Fernandes
d593061b15 Move construct and destroy utilities to common header 2019-05-02 09:48:45 -04:00
Glen Fernandes
5072045f12 Use boost::noinit_adapt free function 2019-04-29 00:37:55 -04:00
Glen Fernandes
442e179920 Simplify implementation in terms of noinit_adaptor 2019-04-28 22:42:37 -04:00
Peter Dimov
9544a8cb91 Add revision history for 1.65 2019-04-24 17:21:37 +03:00
Peter Dimov
5823d6bcc9 Document enable_shared_from 2019-04-24 05:16:03 +03:00
Peter Dimov
f56e609757 Fix mistake in weak_from_this_test 2019-04-24 04:57:37 +03:00
Peter Dimov
8df63a3d0e Add tests for enable_shared_from 2019-04-24 04:50:59 +03:00
Peter Dimov
4b6cb1223b Add boost/smart_ptr/enable_shared_from.hpp 2019-04-24 04:50:30 +03:00
Peter Dimov
719e819570 Under g++ 4.4, <memory> doesn't compile with rtti=off 2019-04-22 15:57:56 +03:00
Peter Dimov
a571b3a250 Only include core/typeinfo.hpp when needed 2019-04-22 06:07:36 +03:00
Peter Dimov
f17c5e8e3b Add a few no_rtti tests 2019-04-22 05:43:08 +03:00
Peter Dimov
e306b30dcf Use a private detail/sp_typeinfo header instead of the deprecated Core one 2019-04-22 05:25:07 +03:00
165 changed files with 3810 additions and 774 deletions

View File

@@ -1,10 +1,10 @@
# Copyright 2016-2019 Peter Dimov
# Copyright 2016-2020 Peter Dimov
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
language: cpp
sudo: false
dist: xenial
branches:
only:
@@ -23,8 +23,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
@@ -125,6 +136,26 @@ matrix:
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
@@ -136,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:
@@ -148,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:
@@ -157,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
@@ -176,7 +203,6 @@ matrix:
- clang-3.6
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.6
- os: linux
compiler: clang++-3.7
@@ -187,7 +213,6 @@ matrix:
- clang-3.7
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.7
- os: linux
compiler: clang++-3.8
@@ -196,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
@@ -208,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
@@ -222,7 +243,6 @@ matrix:
- clang-4.0
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-4.0
- os: linux
compiler: clang++-5.0
@@ -233,7 +253,6 @@ matrix:
- clang-5.0
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-5.0
- os: linux
compiler: clang++-6.0
@@ -244,7 +263,6 @@ matrix:
- clang-6.0
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-6.0
- os: linux
compiler: clang++-7
@@ -255,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:
@@ -278,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:
@@ -289,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
@@ -298,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 ..
@@ -319,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

View File

@@ -1,12 +1,10 @@
# Copyright 2018 Mike Dev
# Copyright 2018-2020 Peter Dimov
# Distributed under the Boost Software License, Version 1.0.
# See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt
# Partial (add_subdirectory only) and experimental CMake support
# Subject to change; please do not rely on the contents of this file yet
cmake_minimum_required(VERSION 3.5...3.16)
cmake_minimum_required(VERSION 3.5)
project(BoostSmartPtr LANGUAGES CXX)
project(boost_smart_ptr VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX)
add_library(boost_smart_ptr INTERFACE)
add_library(Boost::smart_ptr ALIAS boost_smart_ptr)
@@ -19,8 +17,20 @@ target_link_libraries(boost_smart_ptr
Boost::config
Boost::core
Boost::move
Boost::predef
Boost::static_assert
Boost::throw_exception
Boost::type_traits
)
if(BOOST_SUPERPROJECT_VERSION)
include(BoostInstall)
boost_install(TARGETS boost_smart_ptr HEADER_DIRECTORY include/)
endif()
if(BUILD_TESTING)
add_subdirectory(test)
endif()

View File

@@ -20,7 +20,15 @@ environment:
TOOLSET: msvc-12.0,msvc-14.0
ADDRMD: 32,64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
TOOLSET: msvc-14.1,clang-win
TOOLSET: msvc-14.1
CXXSTD: 14,17
ADDRMD: 32,64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
TOOLSET: clang-win
CXXSTD: 14,17
ADDRMD: 64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
TOOLSET: msvc-14.2
CXXSTD: 14,17
ADDRMD: 32,64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015

View File

@@ -33,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[]

View File

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

View File

@@ -13,7 +13,17 @@ http://www.boost.org/LICENSE_1_0.txt
: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`

View File

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

View File

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

View File

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

View File

@@ -41,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;

View File

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

View File

@@ -55,43 +55,43 @@ types.
[subs=+quotes]
```
namespace boost {
`// only if T is not an array type`
`// T is not an array`
template<class T, class... Args>
shared_ptr<T> make_shared(Args&&... args);
template<class T, class A, class... Args>
shared_ptr<T> allocate_shared(const A& a, Args&&... args);
`// only if T is an array type of the form U[]`
`// T is an array of unknown bounds`
template<class T>
shared_ptr<T> make_shared(std::size_t n);
template<class T, class A>
shared_ptr<T> allocate_shared(const A& a, std::size_t n);
`// only if T is an array type of the form U[N]`
`// T is an array of known bounds`
template<class T>
shared_ptr<T> make_shared();
template<class T, class A>
shared_ptr<T> allocate_shared(const A& a);
`// only if T is an array type of the form U[]`
`// T is an array of unknown bounds`
template<class T> shared_ptr<T>
make_shared(std::size_t n, const remove_extent_t<T>& v);
template<class T, class A> shared_ptr<T>
allocate_shared(const A& a, std::size_t n, const remove_extent_t<T>& v);
`// only if T is an array type of the form U[N]`
`// T is an array of known bounds`
template<class T>
shared_ptr<T> make_shared(const remove_extent_t<T>& v);
template<class T, class A>
shared_ptr<T> allocate_shared(const A& a, const remove_extent_t<T>& v);
`// only if T is not an array type of the form U[]`
`// T is not an array of unknown bounds`
template<class T>
shared_ptr<T> make_shared_noinit();
template<class T, class A>
shared_ptr<T> allocate_shared_noinit(const A& a);
`// only if T is an array type of the form U[N]`
`// T is an array of unknown bounds`
template<class T>
shared_ptr<T> make_shared_noinit(std::size_t n);
template<class T, class A>
@@ -144,7 +144,7 @@ perform this initialization via the expression
`std::allocator_traits<A2>::construct(a2, p, expr)` (where
`_expr_` is `v` or `std::forward<Args>(args)\...)` respectively), `p`
points to storage suitable to hold an object of type `U`, and `a2` of
type `A2` is a rebound copy `a` such that its `value_type` is `U`.
type `A2` is a potentially rebound copy of `a`.
* When a (sub)object of non-array type `U` is specified to be
default-initialized, `make_shared_noinit` and `allocate_shared_noinit` shall
perform this initialization via the expression `::new(p) U`, where
@@ -158,7 +158,7 @@ storage suitable to hold an object of type `U`.
value-initialized, `allocate_shared` shall perform this initialization via the
expression `std::allocator_traits<A2>::construct(a2, p)`, where
`p` points to storage suitable to hold an object of type `U` and `a2` of
type `A2` is a rebound copy of `a` such that its value_type is `U`.
type `A2` is a potentially rebound copy of `a`.
* Array elements are initialized in ascending order of their addresses.
* When the lifetime of the object managed by the return value ends, or when
the initialization of an array element throws an exception, the initialized
@@ -181,8 +181,7 @@ template<class T, class A, class... Args>
[none]
* {blank}
+
Remarks:: These overloads shall only participate in overload resolution when
`T` is not an array type.
Constraints:: `T` is not an array.
Returns:: A `shared_ptr` to an object of type `T`, constructed from
`args\...`.
Examples::
@@ -200,10 +199,9 @@ template<class T, class A>
[none]
* {blank}
+
Remarks:: These overloads shall only participate in overload resolution when
`T` is an array type of the form `U[]`.
Constraints:: `T` is an array of unknown bounds.
Returns:: A `shared_ptr` to a sequence of `n` value-initialized objects of
type `U`.
type `remove_extent_t<T>`.
Examples::
* `auto p = make_shared<double[]>(1024);`
* `auto p = make_shared<double[][2][2]>(6);`
@@ -219,10 +217,9 @@ template<class T, class A>
[none]
* {blank}
+
Remarks:: These overloads shall only participate in overload resolution when
`T` is an array type of the form `U[N]`.
Returns:: A `shared_ptr` to a sequence of `N` value-initialized objects of
type `U`.
Constraints:: `T` is an array of known bounds.
Returns:: A `shared_ptr` to a sequence of `extent_v<T>` value-initialized
objects of type `remove_extent_t<T>`.
Examples::
* `auto p = make_shared<double[1024]>();`
* `auto p = make_shared<double[6][2][2]>();`
@@ -238,10 +235,9 @@ template<class T, class A> shared_ptr<T>
[none]
* {blank}
+
Remarks:: These overloads shall only participate in overload resolution when
`T` is an array type of the form `U[]`.
Returns:: A `shared_ptr` to a sequence of `n` objects of type `U`, each
initialized to `v`.
Constraints:: `T` is an array of unknown bounds.
Returns:: A `shared_ptr` to a sequence of `n` objects of type
`remove_extent_t<T>`, each initialized to `v`.
Examples::
* `auto p = make_shared<double[]>(1024, 1.0);`
* `auto p = make_shared<double[][2]>(6, {1.0, 0.0});`
@@ -258,10 +254,9 @@ template<class T, class A>
[none]
* {blank}
+
Remarks:: These overloads shall only participate in overload resolution when
`T` is an array type of the form `U[N]`.
Returns:: A `shared_ptr` to a sequence of `N` objects of type `U`, each
initialized to `v`.
Constraints:: `T` is an array of known bounds.
Returns:: A `shared_ptr` to a sequence of `extent_v<T>` objects of type
`remove_extent_t<T>`, each initialized to `v`.
Examples::
* `auto p = make_shared<double[1024]>(1.0);`
* `auto p = make_shared<double[6][2]>({1.0, 0.0});`
@@ -278,10 +273,10 @@ template<class T, class A>
[none]
* {blank}
+
Remarks:: These overloads shall only participate in overload resolution when
`T` is not an array type, or an array type of the `U[N]`.
Constraints:: `T` is not an array, or is an array of known bounds.
Returns:: A `shared_ptr` to a default-initialized object of type `T`, or a
sequence of `N` default-initialized objects of type `U`, respectively.
sequence of `extent_v<T>` default-initialized objects of type
`remove_extent_t<T>`, respectively.
Example:: `auto p = make_shared_noinit<double[1024]>();`
```
@@ -295,8 +290,7 @@ template<class T, class A>
[none]
* {blank}
+
Remarks:: These overloads shall only participate in overload resolution when
`T` is an array type of the form `U[]`.
Constraints:: `T` is an array of unknown bounds.
Returns:: A `shared_ptr` to a sequence of `_n_` default-initialized objects
of type `U`.
of type `remove_extent_t<T>`.
Example:: `auto p = make_shared_noinit<double[]>(1024);`

View File

@@ -40,23 +40,23 @@ feature with `std::make_unique`.
[subs=+quotes]
```
namespace boost {
`// only if T is not an array type`
`// T is not an array`
template<class T, class... Args>
std::unique_ptr<T> make_unique(Args&&... args);
`// only if T is not an array type`
`// T is not an array`
template<class T>
std::unique_ptr<T> make_unique(remove_reference_t<T>&& v);
std::unique_ptr<T> make_unique(type_identity_t<T>&& v);
`// only if T is an array type of the form U[]`
`// T is an array of unknown bounds`
template<class T>
std::unique_ptr<T> make_unique(std::size_t n);
`// only if T is not an array type`
`// T is not an array`
template<class T>
std::unique_ptr<T> make_unique_noinit();
`// only if T is an array type of the form U[]`
`// T is an array of unknown bounds`
template<class T>
std::unique_ptr<T> make_unique_noinit(std::size_t n);
}
@@ -71,20 +71,18 @@ template<class T, class... Args>
[none]
* {blank}
+
Remarks:: These overloads shall only participate in overload resolution when
`T` is not an array type.
Constraints:: `T` is not an array.
Returns:: `std::unique_ptr<T>(new T(std::forward<Args>(args)\...)`.
Example:: `auto p = make_unique<int>();`
```
template<class T>
std::unique_ptr<T> make_unique(remove_reference_t<T>&& v);
std::unique_ptr<T> make_unique(type_identity_t<T>&& v);
```
[none]
* {blank}
+
Remarks:: These overloads shall only participate in overload resolution when
`T` is not an array type.
Constraints:: `T` is not an array.
Returns:: `std::unique_ptr<T>(new T(std::move(v))`.
Example:: `auto p = make_unique<std::vector<int> >({1, 2});`
@@ -95,9 +93,8 @@ template<class T>
[none]
* {blank}
+
Remarks:: These overloads shall only participate in overload resolution when
`T` is an array type of the form `U[]`.
Returns:: `std::unique_ptr<U[]>(new U[n]())`.
Constraints:: `T` is an array of unknown bounds.
Returns:: `std::unique_ptr<T>(new remove_extent_t<T>[n]())`.
Example:: `auto p = make_unique<double[]>(1024);`
```
@@ -107,10 +104,9 @@ template<class T>
[none]
* {blank}
+
Remarks:: These overloads shall only participate in overload resolution when
`T` is not an array type.
Constraints:: `T` is not an array.
Returns:: `std::unique_ptr<T>(new T)`.
Example:: `auto p = make_unique_noinit<double[1024]>();`
Example:: `auto p = make_unique_noinit<std::array<double, 1024> >();`
```
template<class T>
@@ -119,7 +115,6 @@ template<class T>
[none]
* {blank}
+
Remarks:: These overloads shall only participate in overload resolution when
`T` is an array type of the form `U[]`.
Returns:: `std::unique_ptr<U[]>(new U[n])`.
Constraints:: `T` is an array of unknown bounds.
Returns:: `std::unique_ptr<T>(new remove_extent_t<T>[n])`.
Example:: `auto p = make_unique_noinit<double[]>(1024);`

View File

@@ -72,21 +72,19 @@ inline typename enable_if_<is_unbounded_array<T>::value,
local_shared_ptr<T> >::type
allocate_local_shared(const A& allocator, std::size_t count)
{
typedef typename remove_extent<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
typedef typename detail::sp_array_element<T>::type element;
typedef typename 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, scalar>::value;
detail::sp_array_result<other, base> result(allocator, size);
detail::sp_array_result<other, base> result(allocator, count);
base* node = result.get();
scalar* start = detail::sp_array_start<base, scalar>(node);
::new(static_cast<void*>(node)) base(allocator, size, start);
element* start = detail::sp_array_start<element>(node);
::new(static_cast<void*>(node)) base(allocator, start, count);
detail::lsp_array_base& local = node->state().base();
local.set(node);
result.release();
return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(),
reinterpret_cast<type*>(start), &local);
return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), start,
&local);
}
template<class T, class A>
@@ -94,23 +92,22 @@ inline typename enable_if_<is_bounded_array<T>::value,
local_shared_ptr<T> >::type
allocate_local_shared(const A& allocator)
{
typedef typename remove_extent<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
enum {
size = detail::sp_array_count<T, scalar>::value
count = extent<T>::value
};
typedef detail::lsp_size_array_state<other, size> state;
typedef typename detail::sp_array_element<T>::type element;
typedef typename 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>
@@ -119,25 +116,19 @@ inline typename enable_if_<is_unbounded_array<T>::value,
allocate_local_shared(const A& allocator, std::size_t count,
const typename remove_extent<T>::type& value)
{
typedef typename remove_extent<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
typedef typename detail::sp_array_element<T>::type element;
typedef typename detail::sp_bind_allocator<A, element>::type other;
typedef detail::lsp_array_state<other> state;
typedef detail::sp_array_base<state> base;
enum {
total = detail::sp_array_count<type, scalar>::value
};
std::size_t size = count * total;
detail::sp_array_result<other, base> result(allocator, size);
detail::sp_array_result<other, base> result(allocator, count);
base* node = result.get();
scalar* start = detail::sp_array_start<base, scalar>(node);
::new(static_cast<void*>(node)) base(allocator, size,
reinterpret_cast<const scalar*>(&value), total, start);
element* start = detail::sp_array_start<element>(node);
::new(static_cast<void*>(node)) base(allocator, start, count, value);
detail::lsp_array_base& local = node->state().base();
local.set(node);
result.release();
return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(),
reinterpret_cast<type*>(start), &local);
return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), start,
&local);
}
template<class T, class A>
@@ -146,25 +137,22 @@ inline typename enable_if_<is_bounded_array<T>::value,
allocate_local_shared(const A& allocator,
const typename remove_extent<T>::type& value)
{
typedef typename remove_extent<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
enum {
size = detail::sp_array_count<T, scalar>::value
count = extent<T>::value
};
typedef detail::lsp_size_array_state<other, size> state;
typedef typename detail::sp_array_element<T>::type element;
typedef typename 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, scalar>::value, start);
element* start = detail::sp_array_start<element>(node);
::new(static_cast<void*>(node)) base(allocator, start, count, value);
detail::lsp_array_base& local = node->state().base();
local.set(node);
result.release();
return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(),
reinterpret_cast<type*>(start), &local);
return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(), start,
&local);
}
template<class T, class A>
@@ -172,22 +160,8 @@ inline typename enable_if_<is_unbounded_array<T>::value,
local_shared_ptr<T> >::type
allocate_local_shared_noinit(const A& allocator, std::size_t count)
{
typedef typename remove_extent<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
typedef detail::lsp_array_state<other> state;
typedef detail::sp_array_base<state, false> base;
std::size_t size = count * detail::sp_array_count<type, scalar>::value;
detail::sp_array_result<other, base> result(allocator, size);
base* node = result.get();
scalar* start = detail::sp_array_start<base, scalar>(node);
::new(static_cast<void*>(node)) base(detail::sp_default(), allocator,
size, start);
detail::lsp_array_base& local = node->state().base();
local.set(node);
result.release();
return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(),
reinterpret_cast<type*>(start), &local);
return boost::allocate_local_shared<T>(boost::noinit_adapt(allocator),
count);
}
template<class T, class A>
@@ -195,24 +169,7 @@ inline typename enable_if_<is_bounded_array<T>::value,
local_shared_ptr<T> >::type
allocate_local_shared_noinit(const A& allocator)
{
typedef typename remove_extent<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
enum {
size = detail::sp_array_count<T, scalar>::value
};
typedef detail::lsp_size_array_state<other, size> state;
typedef detail::sp_array_base<state, false> base;
detail::sp_array_result<other, base> result(allocator, size);
base* node = result.get();
scalar* start = detail::sp_array_start<base, scalar>(node);
::new(static_cast<void*>(node)) base(detail::sp_default(), allocator,
size, start);
detail::lsp_array_base& local = node->state().base();
local.set(node);
result.release();
return local_shared_ptr<T>(detail::lsp_internal_constructor_tag(),
reinterpret_cast<type*>(start), &local);
return boost::allocate_local_shared<T>(boost::noinit_adapt(allocator));
}
} /* boost */

View File

@@ -8,15 +8,14 @@ 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/enable_if.hpp>
#include <boost/type_traits/extent.hpp>
#include <boost/type_traits/is_bounded_array.hpp>
#include <boost/type_traits/is_unbounded_array.hpp>
#include <boost/type_traits/has_trivial_assign.hpp>
#include <boost/type_traits/has_trivial_constructor.hpp>
#include <boost/type_traits/has_trivial_destructor.hpp>
#include <boost/type_traits/remove_all_extents.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/remove_extent.hpp>
#include <boost/type_traits/type_with_alignment.hpp>
@@ -25,15 +24,22 @@ namespace boost {
namespace detail {
template<class T>
struct sp_array_scalar {
struct sp_array_element {
typedef typename boost::remove_cv<typename
boost::remove_all_extents<T>::type>::type type;
boost::remove_extent<T>::type>::type type;
};
template<class T, class U>
template<class T>
struct sp_array_count {
enum {
value = sizeof(T) / sizeof(U)
value = 1
};
};
template<class T, std::size_t N>
struct sp_array_count<T[N]> {
enum {
value = N * sp_array_count<T>::value
};
};
@@ -70,154 +76,6 @@ sp_objects(std::size_t size) BOOST_SP_NOEXCEPT
return (size + sizeof(T) - 1) / sizeof(T);
}
template<bool E, class A, class T>
inline typename boost::enable_if_<!E &&
boost::has_trivial_destructor<T>::value>::type
sp_array_destroy(A&, T*, std::size_t) BOOST_SP_NOEXCEPT { }
template<bool E, class A, class T>
inline typename boost::enable_if_<!E &&
!boost::has_trivial_destructor<T>::value>::type
sp_array_destroy(A&, T* ptr, std::size_t size)
{
while (size > 0) {
ptr[--size].~T();
}
}
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
template<bool E, class A, class T>
inline typename boost::enable_if_<E>::type
sp_array_destroy(A& allocator, T* ptr, std::size_t size)
{
while (size > 0) {
std::allocator_traits<A>::destroy(allocator, ptr + --size);
}
}
#endif
template<bool E, class A, class T>
class sp_destroyer {
public:
sp_destroyer(A& allocator, T* ptr) BOOST_SP_NOEXCEPT
: allocator_(allocator),
ptr_(ptr),
size_(0) { }
~sp_destroyer() {
sp_array_destroy<E>(allocator_, ptr_, size_);
}
std::size_t& size() BOOST_SP_NOEXCEPT {
return size_;
}
private:
sp_destroyer(const sp_destroyer&);
sp_destroyer& operator=(const sp_destroyer&);
A& allocator_;
T* ptr_;
std::size_t size_;
};
template<bool E, class A, class T>
inline typename boost::enable_if_<!E &&
boost::has_trivial_constructor<T>::value &&
boost::has_trivial_assign<T>::value &&
boost::has_trivial_destructor<T>::value>::type
sp_array_construct(A&, T* ptr, std::size_t size)
{
for (std::size_t i = 0; i < size; ++i) {
ptr[i] = T();
}
}
template<bool E, class A, class T>
inline typename boost::enable_if_<!E &&
boost::has_trivial_constructor<T>::value &&
boost::has_trivial_assign<T>::value &&
boost::has_trivial_destructor<T>::value>::type
sp_array_construct(A&, T* ptr, std::size_t size, const T* list,
std::size_t count)
{
for (std::size_t i = 0; i < size; ++i) {
ptr[i] = list[i % count];
}
}
template<bool E, class A, class T>
inline typename boost::enable_if_<!E &&
!(boost::has_trivial_constructor<T>::value &&
boost::has_trivial_assign<T>::value &&
boost::has_trivial_destructor<T>::value)>::type
sp_array_construct(A& none, T* ptr, std::size_t size)
{
sp_destroyer<E, A, T> hold(none, ptr);
for (std::size_t& i = hold.size(); i < size; ++i) {
::new(static_cast<void*>(ptr + i)) T();
}
hold.size() = 0;
}
template<bool E, class A, class T>
inline typename boost::enable_if_<!E &&
!(boost::has_trivial_constructor<T>::value &&
boost::has_trivial_assign<T>::value &&
boost::has_trivial_destructor<T>::value)>::type
sp_array_construct(A& none, T* ptr, std::size_t size, const T* list,
std::size_t count)
{
sp_destroyer<E, A, T> hold(none, ptr);
for (std::size_t& i = hold.size(); i < size; ++i) {
::new(static_cast<void*>(ptr + i)) T(list[i % count]);
}
hold.size() = 0;
}
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
template<bool E, class A, class T>
inline typename boost::enable_if_<E>::type
sp_array_construct(A& allocator, T* ptr, std::size_t size)
{
sp_destroyer<E, A, T> hold(allocator, ptr);
for (std::size_t& i = hold.size(); i < size; ++i) {
std::allocator_traits<A>::construct(allocator, ptr + i);
}
hold.size() = 0;
}
template<bool E, class A, class T>
inline typename boost::enable_if_<E>::type
sp_array_construct(A& allocator, T* ptr, std::size_t size, const T* list,
std::size_t count)
{
sp_destroyer<E, A, T> hold(allocator, ptr);
for (std::size_t& i = hold.size(); i < size; ++i) {
std::allocator_traits<A>::construct(allocator, ptr + i,
list[i % count]);
}
hold.size() = 0;
}
#endif
template<class A, class T>
inline typename
boost::enable_if_<boost::has_trivial_constructor<T>::value>::type
sp_array_default(A&, T*, std::size_t) BOOST_SP_NOEXCEPT { }
template<class A, class T>
inline typename
boost::enable_if_<!boost::has_trivial_constructor<T>::value>::type
sp_array_default(A& none, T* ptr, std::size_t size)
{
sp_destroyer<false, A, T> hold(none, ptr);
for (std::size_t& i = hold.size(); i < size; ++i) {
::new(static_cast<void*>(ptr + i)) T;
}
hold.size() = 0;
}
template<class A>
class sp_array_state {
public:
@@ -262,29 +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 {
@@ -300,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_));
@@ -347,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;
@@ -358,23 +184,22 @@ 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 {
@@ -382,8 +207,9 @@ public:
}
virtual void dispose() BOOST_SP_NOEXCEPT {
sp_array_destroy<E>(state_.allocator(),
sp_array_start<sp_array_base, type>(this), state_.size());
boost::alloc_destroy_n(state_.allocator(),
boost::first_scalar(sp_array_start<type>(this)),
state_.size() * sp_array_count<type>::value);
}
virtual void destroy() BOOST_SP_NOEXCEPT {
@@ -393,11 +219,11 @@ public:
other.destroy(this);
}
virtual void* get_deleter(const sp_typeinfo&) BOOST_SP_NOEXCEPT {
virtual void* get_deleter(const sp_typeinfo_&) BOOST_SP_NOEXCEPT {
return 0;
}
virtual void* get_local_deleter(const sp_typeinfo&) BOOST_SP_NOEXCEPT {
virtual void* get_local_deleter(const sp_typeinfo_&) BOOST_SP_NOEXCEPT {
return 0;
}
@@ -423,11 +249,11 @@ public:
}
}
T* get() const {
T* get() const BOOST_SP_NOEXCEPT {
return result_;
}
void release() {
void release() BOOST_SP_NOEXCEPT {
result_ = 0;
}
@@ -445,40 +271,37 @@ template<class T, class A>
inline typename enable_if_<is_unbounded_array<T>::value, shared_ptr<T> >::type
allocate_shared(const A& allocator, std::size_t count)
{
typedef typename remove_extent<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
typedef typename detail::sp_array_element<T>::type element;
typedef typename 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, scalar>::value;
detail::sp_array_result<other, base> result(allocator, size);
detail::sp_counted_base* node = result.get();
scalar* start = detail::sp_array_start<base, scalar>(node);
::new(static_cast<void*>(node)) base(allocator, size, start);
detail::sp_array_result<other, base> result(allocator, count);
base* node = result.get();
element* start = detail::sp_array_start<element>(node);
::new(static_cast<void*>(node)) base(allocator, start, count);
result.release();
return shared_ptr<T>(detail::sp_internal_constructor_tag(),
reinterpret_cast<type*>(start), detail::shared_count(node));
return shared_ptr<T>(detail::sp_internal_constructor_tag(), start,
detail::shared_count(static_cast<detail::sp_counted_base*>(node)));
}
template<class T, class A>
inline typename enable_if_<is_bounded_array<T>::value, shared_ptr<T> >::type
allocate_shared(const A& allocator)
{
typedef typename remove_extent<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
enum {
size = detail::sp_array_count<T, scalar>::value
count = extent<T>::value
};
typedef detail::sp_size_array_state<other, size> state;
typedef typename detail::sp_array_element<T>::type element;
typedef typename 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>
@@ -486,23 +309,17 @@ inline typename enable_if_<is_unbounded_array<T>::value, shared_ptr<T> >::type
allocate_shared(const A& allocator, std::size_t count,
const typename remove_extent<T>::type& value)
{
typedef typename remove_extent<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
typedef typename detail::sp_array_element<T>::type element;
typedef typename detail::sp_bind_allocator<A, element>::type other;
typedef detail::sp_array_state<other> state;
typedef detail::sp_array_base<state> base;
enum {
total = detail::sp_array_count<type, scalar>::value
};
std::size_t size = count * total;
detail::sp_array_result<other, base> result(allocator, size);
detail::sp_counted_base* node = result.get();
scalar* start = detail::sp_array_start<base, scalar>(node);
::new(static_cast<void*>(node)) base(allocator, size,
reinterpret_cast<const scalar*>(&value), total, start);
detail::sp_array_result<other, base> result(allocator, count);
base* node = result.get();
element* start = detail::sp_array_start<element>(node);
::new(static_cast<void*>(node)) base(allocator, start, count, value);
result.release();
return shared_ptr<T>(detail::sp_internal_constructor_tag(),
reinterpret_cast<type*>(start), detail::shared_count(node));
return shared_ptr<T>(detail::sp_internal_constructor_tag(), start,
detail::shared_count(static_cast<detail::sp_counted_base*>(node)));
}
template<class T, class A>
@@ -510,65 +327,34 @@ inline typename enable_if_<is_bounded_array<T>::value, shared_ptr<T> >::type
allocate_shared(const A& allocator,
const typename remove_extent<T>::type& value)
{
typedef typename remove_extent<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
enum {
size = detail::sp_array_count<T, scalar>::value
count = extent<T>::value
};
typedef detail::sp_size_array_state<other, size> state;
typedef typename detail::sp_array_element<T>::type element;
typedef typename 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, scalar>::value, start);
detail::sp_array_result<other, base> result(allocator, count);
base* node = result.get();
element* start = detail::sp_array_start<element>(node);
::new(static_cast<void*>(node)) base(allocator, start, count, value);
result.release();
return shared_ptr<T>(detail::sp_internal_constructor_tag(),
reinterpret_cast<type*>(start), detail::shared_count(node));
return shared_ptr<T>(detail::sp_internal_constructor_tag(), start,
detail::shared_count(static_cast<detail::sp_counted_base*>(node)));
}
template<class T, class A>
inline typename enable_if_<is_unbounded_array<T>::value, shared_ptr<T> >::type
allocate_shared_noinit(const A& allocator, std::size_t count)
{
typedef typename remove_extent<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
typedef detail::sp_array_state<other> state;
typedef detail::sp_array_base<state, false> base;
std::size_t size = count * detail::sp_array_count<type, scalar>::value;
detail::sp_array_result<other, base> result(allocator, size);
detail::sp_counted_base* node = result.get();
scalar* start = detail::sp_array_start<base, scalar>(node);
::new(static_cast<void*>(node)) base(detail::sp_default(), allocator,
size, start);
result.release();
return shared_ptr<T>(detail::sp_internal_constructor_tag(),
reinterpret_cast<type*>(start), detail::shared_count(node));
return boost::allocate_shared<T>(boost::noinit_adapt(allocator), count);
}
template<class T, class A>
inline typename enable_if_<is_bounded_array<T>::value, shared_ptr<T> >::type
allocate_shared_noinit(const A& allocator)
{
typedef typename remove_extent<T>::type type;
typedef typename detail::sp_array_scalar<T>::type scalar;
typedef typename detail::sp_bind_allocator<A, scalar>::type other;
enum {
size = detail::sp_array_count<T, scalar>::value
};
typedef detail::sp_size_array_state<other, size> state;
typedef detail::sp_array_base<state, false> base;
detail::sp_array_result<other, base> result(allocator, size);
detail::sp_counted_base* node = result.get();
scalar* start = detail::sp_array_start<base, scalar>(node);
::new(static_cast<void*>(node)) base(detail::sp_default(), allocator,
size, start);
result.release();
return shared_ptr<T>(detail::sp_internal_constructor_tag(),
reinterpret_cast<type*>(start), detail::shared_count(node));
return boost::allocate_shared<T>(boost::noinit_adapt(allocator));
}
} /* boost */

View File

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

View File

@@ -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 ) )
{
}

View File

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

View File

@@ -1,37 +0,0 @@
#ifndef BOOST_SMART_PTR_DETAIL_LWM_NOP_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_LWM_NOP_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// boost/detail/lwm_nop.hpp
//
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
namespace boost
{
namespace detail
{
class lightweight_mutex
{
public:
typedef lightweight_mutex scoped_lock;
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_LWM_NOP_HPP_INCLUDED

View File

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

View File

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

View File

@@ -499,12 +499,12 @@ public:
return std::less<sp_counted_base *>()( a.pi_, b.pi_ );
}
void * get_deleter( sp_typeinfo const & ti ) const BOOST_SP_NOEXCEPT
void * get_deleter( sp_typeinfo_ const & ti ) const BOOST_SP_NOEXCEPT
{
return pi_? pi_->get_deleter( ti ): 0;
}
void * get_local_deleter( sp_typeinfo const & ti ) const BOOST_SP_NOEXCEPT
void * get_local_deleter( sp_typeinfo_ const & ti ) const BOOST_SP_NOEXCEPT
{
return pi_? pi_->get_local_deleter( ti ): 0;
}

View File

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

View File

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

View File

@@ -15,7 +15,7 @@
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/detail/sp_typeinfo.hpp>
#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/smart_ptr/detail/sp_noexcept.hpp>
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
@@ -99,8 +99,8 @@ public:
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) BOOST_SP_NOEXCEPT = 0;
virtual void * get_local_deleter( sp_typeinfo const & ti ) BOOST_SP_NOEXCEPT = 0;
virtual void * get_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT = 0;
virtual void * get_local_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT = 0;
virtual void * get_untyped_deleter() BOOST_SP_NOEXCEPT = 0;
void add_ref_copy() BOOST_SP_NOEXCEPT

View File

@@ -24,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()

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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/sp_noexcept.hpp>
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
@@ -61,8 +61,8 @@ public:
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) BOOST_SP_NOEXCEPT = 0;
virtual void * get_local_deleter( sp_typeinfo const & ti ) BOOST_SP_NOEXCEPT = 0;
virtual void * get_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT = 0;
virtual void * get_local_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT = 0;
virtual void * get_untyped_deleter() BOOST_SP_NOEXCEPT = 0;
void add_ref_copy() BOOST_SP_NOEXCEPT

View File

@@ -18,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()

View File

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

View File

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

View File

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

View File

@@ -15,7 +15,7 @@
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/detail/sp_typeinfo.hpp>
#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/smart_ptr/detail/sp_noexcept.hpp>
#include <boost/config.hpp>
#include <atomic>
@@ -91,8 +91,8 @@ public:
delete this;
}
virtual void * get_deleter( sp_typeinfo const & ti ) BOOST_SP_NOEXCEPT = 0;
virtual void * get_local_deleter( sp_typeinfo const & ti ) BOOST_SP_NOEXCEPT = 0;
virtual void * get_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT = 0;
virtual void * get_local_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT = 0;
virtual void * get_untyped_deleter() BOOST_SP_NOEXCEPT = 0;
void add_ref_copy() BOOST_SP_NOEXCEPT

View File

@@ -15,7 +15,7 @@
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/detail/sp_typeinfo.hpp>
#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/config.hpp>
#include <limits.h>
@@ -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()

View File

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

View File

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

View File

@@ -93,12 +93,12 @@ public:
boost::checked_delete( px_ );
}
virtual void * get_deleter( sp_typeinfo const & ) BOOST_SP_NOEXCEPT
virtual void * get_deleter( sp_typeinfo_ const & ) BOOST_SP_NOEXCEPT
{
return 0;
}
virtual void * get_local_deleter( sp_typeinfo const & ) BOOST_SP_NOEXCEPT
virtual void * get_local_deleter( sp_typeinfo_ const & ) BOOST_SP_NOEXCEPT
{
return 0;
}
@@ -173,14 +173,14 @@ public:
del( ptr );
}
virtual void * get_deleter( sp_typeinfo const & ti ) BOOST_SP_NOEXCEPT
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 ) BOOST_SP_NOEXCEPT
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() BOOST_SP_NOEXCEPT
@@ -266,14 +266,14 @@ public:
a2.deallocate( this, 1 );
}
virtual void * get_deleter( sp_typeinfo const & ti ) BOOST_SP_NOEXCEPT
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 ) BOOST_SP_NOEXCEPT
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() BOOST_SP_NOEXCEPT

View File

@@ -0,0 +1,58 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_TYPEINFO_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_TYPEINFO_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
// smart_ptr/detail/sp_typeinfo_.hpp
//
// Copyright 2007, 2019 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/config.hpp>
#if defined( BOOST_NO_TYPEID ) || defined( BOOST_NO_STD_TYPEINFO )
#include <boost/core/typeinfo.hpp>
namespace boost
{
namespace detail
{
typedef boost::core::typeinfo sp_typeinfo_;
} // namespace detail
} // namespace boost
#define BOOST_SP_TYPEID_(T) BOOST_CORE_TYPEID(T)
#else // defined( BOOST_NO_TYPEID ) || defined( BOOST_NO_STD_TYPEINFO )
#include <typeinfo>
namespace boost
{
namespace detail
{
typedef std::type_info sp_typeinfo_;
} // namespace detail
} // namespace boost
#define BOOST_SP_TYPEID_(T) typeid(T)
#endif // defined( BOOST_NO_TYPEID ) || defined( BOOST_NO_STD_TYPEINFO )
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_TYPEINFO_HPP_INCLUDED

View File

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

View File

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

View File

@@ -16,7 +16,7 @@
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/assert.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/config/workaround.hpp>
namespace boost
{

View File

@@ -16,7 +16,7 @@
#include <boost/config.hpp>
#include <boost/assert.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/config/workaround.hpp>
#include <boost/smart_ptr/detail/sp_convertible.hpp>
#include <boost/smart_ptr/detail/sp_nullptr_t.hpp>
#include <boost/smart_ptr/detail/sp_noexcept.hpp>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -264,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
View File

@@ -0,0 +1,15 @@
# Copyright 2018, 2019 Peter Dimov
# Distributed under the Boost Software License, Version 1.0.
# See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt
include(BoostTestJamfile OPTIONAL RESULT_VARIABLE HAVE_BOOST_TEST)
if(HAVE_BOOST_TEST)
# for lw_thread_test.cpp
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads)
boost_test_jamfile(FILE Jamfile LINK_LIBRARIES Boost::smart_ptr Boost::core Boost::align Boost::atomic Boost::container_hash Threads::Threads)
endif()

View File

@@ -57,7 +57,8 @@ 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 : : :
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 ;
@@ -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 : : : <toolset>msvc-8.0:<build>no ;
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 : : : <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 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 : : : <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_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 : : : <toolset>msvc-8.0:<build>no ;
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 : : : <toolset>msvc-8.0:<build>no ;
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 ;
@@ -309,3 +328,34 @@ run abi_test_main.cpp abi_test_mt/<cxxstd>98 : : : <cxxstd>0x : abi_test_11_03 ;
run weak_ptr_alias_test.cpp ;
run weak_ptr_alias_move_test.cpp ;
run sp_typeinfo_test.cpp : : : <rtti>off : sp_typeinfo_test_no_rtti ;
run get_deleter_test.cpp : : : <rtti>off <toolset>gcc-4.4.7,<cxxstd>0x:<build>no : get_deleter_test_no_rtti ;
run get_deleter_test2.cpp : : : <rtti>off <toolset>gcc-4.4.7,<cxxstd>0x:<build>no : get_deleter_test2_no_rtti ;
run get_deleter_test3.cpp : : : <rtti>off <toolset>gcc-4.4.7,<cxxstd>0x:<build>no : get_deleter_test3_no_rtti ;
run shared_from_test.cpp ;
run weak_from_test.cpp ;
run weak_from_test2.cpp ;
run allocate_unique_aggregate_test.cpp ;
run allocate_unique_args_test.cpp ;
run allocate_unique_array_construct_test.cpp ;
run allocate_unique_array_noinit_test.cpp ;
run allocate_unique_arrays_test.cpp ;
run allocate_unique_array_test.cpp ;
run allocate_unique_array_throws_test.cpp ;
run allocate_unique_array_value_test.cpp ;
run allocate_unique_construct_test.cpp ;
run allocate_unique_noinit_test.cpp ;
run allocate_unique_test.cpp ;
run allocate_unique_throws_test.cpp ;
run allocate_unique_value_test.cpp ;
run sp_guides_test.cpp ;
run sp_guides_test2.cpp ;
run wp_guides_test.cpp ;
compile-fail shared_from_fail.cpp ;
compile-fail weak_from_fail.cpp ;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View 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

View 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

View 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

View 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

View 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

View 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

View File

@@ -9,7 +9,7 @@
//
#include <boost/detail/atomic_count.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <boost/core/lightweight_test.hpp>
int main()
{

View File

@@ -9,7 +9,7 @@
//
#include <boost/detail/atomic_count.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <boost/core/lightweight_test.hpp>
int main()
{

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -9,7 +9,7 @@
//
#include <boost/shared_array.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <boost/core/lightweight_test.hpp>
struct deleter
{

View File

@@ -9,7 +9,7 @@
//
#include <boost/shared_ptr.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <boost/core/lightweight_test.hpp>
struct deleter
{

View File

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

View File

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

View File

@@ -33,7 +33,7 @@
#include <cstddef>
#include <boost/smart_ptr/intrusive_ref_counter.hpp>
#include <boost/intrusive_ptr.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <boost/core/lightweight_test.hpp>
namespace N1 {

View File

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

View File

@@ -10,7 +10,7 @@
#include <boost/intrusive_ptr.hpp>
#include <boost/functional/hash.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <boost/core/lightweight_test.hpp>
class base
{

View File

@@ -9,7 +9,7 @@
//
#include <boost/smart_ptr/local_shared_ptr.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <boost/core/lightweight_test.hpp>
struct X
{

View File

@@ -11,7 +11,7 @@
#include <boost/smart_ptr/local_shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <boost/core/lightweight_test.hpp>
#include <memory>
#include <utility>

View File

@@ -11,7 +11,7 @@
#include <boost/smart_ptr/local_shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <boost/core/lightweight_test.hpp>
#include <memory>
#include <utility>

View File

@@ -5,7 +5,7 @@
// Distributed under the Boost Software License, Version 1.0.
#include <boost/detail/lightweight_thread.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/smart_ptr/detail/atomic_count.hpp>
boost::detail::atomic_count count( 0 );

View File

@@ -8,7 +8,7 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/config.hpp>
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <boost/detail/lightweight_test.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/smart_ptr/make_local_shared.hpp>
class type {

View File

@@ -8,7 +8,7 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/config.hpp>
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <boost/detail/lightweight_test.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/smart_ptr/make_local_shared.hpp>
int main()

View File

@@ -5,7 +5,7 @@ Copyright 2012-2015 Glen Joseph Fernandes
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#include <boost/detail/lightweight_test.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/smart_ptr/make_shared.hpp>
class type {

View File

@@ -5,7 +5,7 @@ Copyright 2012-2015 Glen Joseph Fernandes
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#include <boost/detail/lightweight_test.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/smart_ptr/make_shared.hpp>
int main()

View File

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

View File

@@ -9,7 +9,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/move/core.hpp>
#include <boost/move/utility_core.hpp>

View File

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

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