1
0
forked from boostorg/core

Compare commits

..

111 Commits

Author SHA1 Message Date
Peter Dimov
2778c5cca6 Rename BOOST_CORE_SNPRINTF to BOOST_CORE_DETAIL_SNPRINTF 2022-12-07 22:33:17 +02:00
Matt Borland
d5b7c3c0dc Add snprintf macro 2022-12-06 08:11:22 -08:00
Matt Borland
db916e4673 Correct test macro and add undef 2022-12-06 08:10:14 -08:00
Matt Borland
3eaba7afc0 Fix for sprintf deprecation warning 2022-12-05 20:34:46 -08:00
Andrey Semashev
ad20fadde7 Added missing release notes for Boost 1.80.0. 2022-12-04 03:52:31 +03:00
Andrey Semashev
a67ec1f75c Corrected Boost release version, added links in changelog. 2022-12-04 02:02:40 +03:00
Peter Dimov
5e95d28eb6 Update revision history 2022-12-01 13:59:53 +02:00
Andrey Semashev
65377a2e13 Updated to GHA checkout@v3 to avoid deprecation warnings. 2022-10-18 17:55:59 +03:00
Peter Dimov
b407b5d87d Change bit_width to return int, LWG3656 has been applied as a DR to C++20 2022-09-22 01:31:01 +03:00
Peter Dimov
013c7856ce Merge branch 'develop' into feature/bit 2022-09-21 21:41:43 +03:00
Andrey Semashev
1c79871f0f Added dependency on Boost.Config to fclose_deleter_test CMake target. 2022-09-21 21:20:40 +03:00
Andrey Semashev
09f2aa123a Enabled parallel build in CMake CI jobs. 2022-09-21 21:14:13 +03:00
Andrey Semashev
9cbf3ac420 Fixed fclose_deleter test failing to build with CMake.
Jamfile parser created incorrect test for fclose_deleter_test,
which resulted in a compiler error. Prevent the parser from creating
the test target by reformatting the Jamfile and create a CMake
target with proper dependencies.
2022-09-21 21:05:27 +03:00
Andrey Semashev
fd615f3bfe Use depinst in AppVeyor CI as well. 2022-09-21 20:00:24 +03:00
Andrey Semashev
a7f76af262 Fixed unintentional change to CMake configure step in GHA config. 2022-09-21 20:00:24 +03:00
Andrey Semashev
860eed6baf Use depinst to install library dependencies in GHA config. 2022-09-21 19:19:38 +03:00
Peter Dimov
66a742f41e Statically assert the unsigned integer requirements in bit.hpp. Fixes #129. 2022-09-21 19:19:02 +03:00
Peter Dimov
2cc3e23447 Add test/bit_width_fail (refs #129) 2022-09-21 19:19:02 +03:00
Andrey Semashev
00f4f11f14 Added a check for NULL pointer in fclose_deleter.
The deleter can be called on a null pointer by shared_ptr.

Also added tests with unique_ptr from Boost.Move and shared_ptr
from Boost.SmartPtr.
2022-09-21 18:09:42 +03:00
Andrey Semashev
3510f6244b Added fclose_deleter.
fclose_deleter can be used as a deleter function object for std::FILE
pointers returned by std::fopen.
2022-09-21 13:50:22 +03:00
tocic
89852794ca Fix typos in docs (#127)
* Fix typos in docs

Use "Acknowledgments" everywhere for consistency.

* amend! Fix typos in docs

Fix typos in docs

Use "Acknowledgements" everywhere for consistency.
2022-09-19 12:53:00 +03:00
Peter Dimov
0ac87736f8 Explicitly disable sv_nullptr_fail when BOOST_NO_CXX11_NULLPTR is defined, because libc++ seems to have nullptr even in C++03 mode 2022-09-18 21:10:18 +03:00
Peter Dimov
1fa592c9ec Add a deleted constructor from nullptr_t to string_view; closes #113 2022-09-18 13:53:55 +03:00
Andrey Semashev
162a4e1d24 Disabled warnings about deprecated builtins on clang-15.
The warnings are caused by Boost.TypeTraits:

https://github.com/boostorg/type_traits/issues/173
2022-09-10 02:49:25 +03:00
Andrey Semashev
68f8f36b04 GitHub Actions config update.
- Added clang-15 jobs.
- Added C++23 testing for gcc and clang on Linux.
- Updated clang version for UBSAN job.
- Removed clang-12 libc++ job - libc++ is now tested with clang-15.
- Updated Ubuntu version for clang jobs to avoid having to use external APT
  repository.
- Updated python package installation for compatibility with Ubuntu 22.04.
2022-09-10 00:55:04 +03:00
Andrey Semashev
414dfb4668 Removed ubuntu-18.04 image from CMake tests in GHA config as this image is deprecated. 2022-08-14 18:27:48 +03:00
Andrey Semashev
1b3a907394 Switched gcc-9 to ubuntu-20.04 GHA CI image. 2022-08-14 17:51:54 +03:00
Andrey Semashev
ab23246301 Replaced ubuntu-18.04 GHA CI images with containers.
Also use ubuntu-latest image for jobs that are running in a container.
2022-08-14 14:24:08 +03:00
Glen Fernandes
48bc47cce2 Update empty_value docs 2022-08-06 21:24:09 -04:00
Glen Fernandes
e3745b2072 Add constexpr support to empty_value 2022-08-06 21:20:55 -04:00
Peter Dimov
4162dbed57 Merge pull request #120 from renbaoshuo/patch-1
chore: bump macos runner version
2022-07-25 12:50:49 +03:00
Baoshuo Ren
38937b0fa3 chore: bump macos runner version
GitHub Action is sunsetting the macOS 10.15 Actions runner. It will stop working intermittently until being completely removed by 2022-8-30: https://github.blog/changelog/2022-07-20-github-actions-the-macos-10-15-actions-runner-image-is-being-deprecated-and-will-be-removed-by-8-30-22
2022-07-25 14:35:22 +08:00
Glen Fernandes
8503c536dc Add documentation for rebind C++03 compatibility 2022-07-17 17:18:54 -04:00
Glen Fernandes
7100c05490 In C++03 use rebind<U>::other instead of rebind<U> 2022-07-17 10:06:51 -04:00
Peter Dimov
ac9d79992e Update ci.yml 2022-06-24 14:09:47 +03:00
Peter Dimov
b6c3190468 Add tn_holder specializations for __int128 (avoids macOS link errors for missing typeinfo for same) 2022-05-30 04:03:18 +03:00
Peter Dimov
f941d2e1f7 Add tests for __int128 to type_name_test.cpp 2022-05-30 03:00:37 +03:00
Glen Fernandes
c0e2211c2b Simplify test 2022-05-14 13:05:56 -04:00
Glen Fernandes
eec8689d58 Merge pull request #116 from boostorg/feature/span_boost_begin_test
Add test around the MSVC defect
2022-05-14 01:59:39 -04:00
Glen Fernandes
45e5b1ebcf Add test around the MSVC defect 2022-05-14 00:51:05 -04:00
Peter Dimov
8645bcb06e Merge pull request #101 from boostorg/feature/bit_use_if_constexpr
bit.hpp: Use C++17 if constexpr where possible
2022-05-14 04:35:13 +03:00
Glen Fernandes
ebff02a932 Merge pull request #115 from glenfe/develop
Remove inline friend begin and end functions
2022-05-13 20:45:27 -04:00
Glen Fernandes
42ed795866 Remove inline friend begin and end functions 2022-05-13 18:26:08 -04:00
Peter Dimov
0212774324 Avoid -Wshadow warning under g++ 4.8 2022-04-29 02:43:37 +03:00
Peter Dimov
43d0da03f3 Remove msvc-14.1 from ci.yml 2022-04-28 21:28:11 +03:00
Peter Dimov
0011697492 Add hash_value (refs #110) 2022-04-28 20:42:48 +03:00
Glen Fernandes
d74140983d Correct definition of C++11 alias rebind 2022-04-26 14:11:31 -04:00
Glen Fernandes
1e5c86eb9d Add tests for the C++11 alias rebind 2022-04-26 14:10:21 -04:00
Andrey Semashev
00cc660f28 Merge pull request #108 from Aiee/fix-typo
[Minor] Fix typo
2022-04-19 11:17:52 +03:00
Yichen Wang
44610b65ba Fix typo 2022-04-19 15:26:36 +08:00
Glen Fernandes
5e0ff1680f Use a different workaround for supporting noinit_adaptor in C++03 2022-03-15 14:47:39 -04:00
Glen Fernandes
4defdfd233 Add allocator_construct_n to allocator_access and deprecate alloc_construct 2022-03-12 10:45:05 -05:00
Glen Fernandes
c4deb479fd Add detection support for single argument construct and destroy 2022-03-12 01:31:31 -05:00
Glen Fernandes
f326683d42 Add allocator_construct and allocator_destroy tests to Jamfile 2022-03-12 00:51:52 -05:00
Peter Dimov
dbefea9631 Update revision history 2022-02-15 20:54:37 +02:00
Peter Dimov
a32c1ee7ac Disable test under CMake, CTest doesn't like crashing tests 2022-02-15 06:49:46 +02:00
Peter Dimov
230dd83002 Add newlines, fflush 2022-02-15 06:49:46 +02:00
Peter Dimov
ec91f29d56 Disable msvc warnings 2022-02-15 06:49:46 +02:00
Peter Dimov
188ca25bf3 Mark verbose_terminate_handler as inline 2022-02-15 06:49:46 +02:00
Peter Dimov
ed84fc4e23 Document verbose_terminate_handler 2022-02-15 06:49:46 +02:00
Peter Dimov
622b7a398a Add core/verbose_terminate_handler.hpp 2022-02-15 06:49:46 +02:00
Peter Dimov
35a4e09854 Add clang-win to GHA 2022-02-15 05:46:09 +02:00
Peter Dimov
b7c987f83c Mark quick_exit as inline 2022-02-15 02:08:30 +02:00
Peter Dimov
89d8efb7ff Avoid -Wlong-long in bit_ceil_test.cpp 2022-02-08 22:58:45 +02:00
Peter Dimov
f12eeb6b9f Avoid -Wlong-long in bit_rotate_test.cpp 2022-02-08 22:55:08 +02:00
Peter Dimov
ad63dcda9f Fix -Wlong-long warnings in splitmix64.hpp 2022-02-08 22:49:44 +02:00
Peter Dimov
6a5f726602 Add splitmix64_test.cpp 2022-02-08 22:48:01 +02:00
Peter Dimov
cf619432a7 Fix GCC -Wlong-long warnings 2022-02-08 22:00:42 +02:00
Peter Dimov
b38c148969 Enable -pedantic for the cmath.hpp and bit.hpp tests 2022-02-08 21:37:34 +02:00
Peter Dimov
bae7c049b0 Avoid conversion warning in bit_width 2022-01-19 17:20:39 +02:00
Glen Fernandes
ea7b623b7d Use consistent section titles in documentation 2022-01-07 11:16:44 -05:00
Andrey Semashev
6ae6ff79f1 Deprecated boost/iterator.hpp, emit warnings on inclusion.
The header defines boost::iterator template, which is an alias for
std::iterator, which is itself deprecated since C++17.

Updated test to avoid testing the definition in C++17 onwards
to avoid failures due to deprecation warnings from libc++-13.
2021-12-23 16:46:29 +03:00
Andrey Semashev
06976ccad7 Use path-constant to specify path to headers in docs Jamfile. 2021-12-23 15:10:58 +03:00
Andrey Semashev
65723e0e1f Added clang-13 CI jobs. 2021-12-23 14:50:35 +03:00
Peter Dimov
df3b9827cf Enclose std::min in parentheses to guard against <windows.h> 2021-12-20 01:35:55 +02:00
Peter Dimov
392cc988dd Add sv_windows_h_test 2021-12-20 01:30:32 +02:00
Peter Dimov
0ef1c06fd8 Add cxxstd=20 to msvc-14.2, msvc-14.3 2021-12-18 21:59:21 +02:00
Peter Dimov
0b9624d047 Add sv_common_reference_test2 2021-12-18 18:53:42 +02:00
Peter Dimov
574c7cf86e Update string_view.hpp to use BOOST_NO_CXX20_HDR_CONCEPTS 2021-12-18 18:39:03 +02:00
Peter Dimov
6e6af5fc90 Update sv_common_reference_test to check BOOST_NO_CXX20_HDR_CONCEPTS 2021-12-18 18:18:19 +02:00
Peter Dimov
95f2a76c90 Specialize std::basic_common_reference to enable std::common_reference and std::common_reference_with 2021-12-18 07:43:33 +02:00
Peter Dimov
28d26d13f1 Add sv_common_reference_test 2021-12-18 07:34:16 +02:00
Peter Dimov
ac71c55b4e Remove msvc-14.2 from appveyor.yml (in GHA); use clang-win from VS2019 2021-12-18 05:07:12 +02:00
Peter Dimov
c83e682b7e Update ci.yml 2021-12-18 05:05:36 +02:00
Peter Dimov
7a79d17da2 Add conversions from and to boost::string_view 2021-12-18 04:15:06 +02:00
Glen Fernandes
02b3f91fc3 Use same style of detection in pointer_traits and allocator_traits 2021-12-15 15:30:57 -05:00
Glen Fernandes
a2b37091eb Update documentation 2021-12-15 11:36:02 -05:00
Glen Fernandes
78dd0cce2f Make pointer_to SFINAE friendlier 2021-12-15 09:31:34 -05:00
Glen Fernandes
a121ab0278 Update release notes for 1.79 2021-12-14 07:52:42 -05:00
Glen Fernandes
0e62373aa2 Make pointer_traits SFINAE friendly 2021-12-13 13:13:12 -05:00
Glen Fernandes
6da7958281 Update unit tests 2021-12-08 10:26:49 -05:00
Glen Fernandes
c8479b4eca Simplify C++03 detection traits slightly 2021-12-07 21:17:28 -05:00
Glen Fernandes
f5ab83efe8 Merge pull request #104 from boostorg/feature/allocator_access
Support additional is_empty intrinsics
2021-12-07 11:02:04 -05:00
Glen Fernandes
eb7bc1ff53 Support additional is_empty intrinsics 2021-12-07 10:10:07 -05:00
Glen Fernandes
d038633f98 Correct spelling of detail macro 2021-12-07 02:57:14 -05:00
Glen Fernandes
ac4bdcc4c5 Update documentation 2021-12-06 23:43:03 -05:00
Glen Fernandes
85a3183c01 Update bool constant 2021-12-06 23:36:48 -05:00
Glen Fernandes
0c9675cf56 Add partial C++03 support for C++11 allocator model 2021-12-06 19:56:57 -05:00
Glen Fernandes
5abadf4472 Change A::value_type to allocator_value_type 2021-12-06 16:41:16 -05:00
Glen Fernandes
6b3fb219cc Minor refactoring in allocator access 2021-12-06 15:58:48 -05:00
Glen Fernandes
febc195093 Add default_allocator allocate hint overload in C++03 mode 2021-12-04 14:41:23 -05:00
Glen Fernandes
8985ce604e Simplify test 2021-12-04 14:39:36 -05:00
Glen Fernandes
15c884438c Correct note in documentation 2021-12-04 14:38:18 -05:00
Glen Fernandes
15f7fb7eaa Move Notes to a top level section 2021-12-04 00:32:27 -05:00
Glen Fernandes
46f37b2f16 Make max_size noexcept 2021-12-04 00:24:45 -05:00
Glen Fernandes
c1be2097d7 Minor documentation changes 2021-12-04 00:22:51 -05:00
Glen Fernandes
c8b989d80b Add allocator_traits that uses allocator_access 2021-12-03 23:55:40 -05:00
Glen Fernandes
74c770206a Allow all individual traits to be specialized 2021-12-02 23:09:09 -05:00
Andrey Semashev
a1ad1784bf Updated check for apt-add-repository capabilities.
In Ubuntu 20.04 there appeared an updated version of the
software-properties-common package in focal-updates, which ships a newer
apt-add-repository version that doesn't support -P/-S/-U command line arguments.

Since we cannot rely on package version checks to determine apt-add-repository
capabilities, we have to parse its --help output instead.

Also, made source list processing more protected against spaces.
2021-11-16 00:36:15 +03:00
Andrey Semashev
213e4695bf Use C++17 if constexpr where possible. 2021-11-01 22:35:28 +03:00
Glen Fernandes
a4172b4319 MSVC warning workaround for empty_value 2021-11-01 06:33:44 -04:00
87 changed files with 2858 additions and 1009 deletions

View File

@@ -1,5 +1,5 @@
# Copyright 2020-2021 Peter Dimov
# Copyright 2021 Andrey Semashev
# Copyright 2021-2022 Andrey Semashev
#
# 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)
@@ -32,7 +32,7 @@ jobs:
# Linux, gcc
- toolset: gcc-4.4
cxxstd: "98,0x"
os: ubuntu-20.04
os: ubuntu-latest
container: ubuntu:16.04
install:
- g++-4.4
@@ -40,7 +40,7 @@ jobs:
- "ppa:ubuntu-toolchain-r/test"
- toolset: gcc-4.6
cxxstd: "03,0x"
os: ubuntu-20.04
os: ubuntu-latest
container: ubuntu:16.04
install:
- g++-4.6
@@ -48,45 +48,49 @@ jobs:
- "ppa:ubuntu-toolchain-r/test"
- toolset: gcc-4.7
cxxstd: "03,11"
os: ubuntu-20.04
os: ubuntu-latest
container: ubuntu:16.04
install:
- g++-4.7
- toolset: gcc-4.8
cxxstd: "03,11"
os: ubuntu-18.04
os: ubuntu-latest
container: ubuntu:18.04
install:
- g++-4.8
- toolset: gcc-4.9
cxxstd: "03,11"
os: ubuntu-20.04
os: ubuntu-latest
container: ubuntu:16.04
install:
- g++-4.9
- toolset: gcc-5
cxxstd: "03,11,14,1z"
os: ubuntu-20.04
os: ubuntu-latest
container: ubuntu:16.04
install:
- g++-5
- toolset: gcc-6
cxxstd: "03,11,14,1z"
os: ubuntu-18.04
os: ubuntu-latest
container: ubuntu:18.04
install:
- g++-6
- toolset: gcc-7
cxxstd: "03,11,14,17"
os: ubuntu-18.04
os: ubuntu-latest
container: ubuntu:18.04
install:
- g++-7
- toolset: gcc-8
cxxstd: "03,11,14,17,2a"
os: ubuntu-18.04
os: ubuntu-latest
container: ubuntu:18.04
install:
- g++-8
- toolset: gcc-9
cxxstd: "03,11,14,17,2a"
os: ubuntu-18.04
os: ubuntu-20.04
install:
- g++-9
- toolset: gcc-10
@@ -95,86 +99,93 @@ jobs:
install:
- g++-10
- toolset: gcc-11
cxxstd: "03,11,14,17,20"
os: ubuntu-20.04
cxxstd: "03,11,14,17,20,23"
os: ubuntu-22.04
install:
- g++-11
sources:
- "ppa:ubuntu-toolchain-r/test"
- toolset: gcc-12
cxxstd: "03,11,14,17,20,23"
os: ubuntu-22.04
install:
- g++-12
- name: UBSAN
toolset: gcc-11
cxxstd: "03,11,14,17,20"
toolset: gcc-12
cxxstd: "03,11,14,17,20,23"
ubsan: 1
os: ubuntu-20.04
os: ubuntu-22.04
install:
- g++-11
sources:
- "ppa:ubuntu-toolchain-r/test"
- g++-12
# Linux, clang
- toolset: clang
compiler: clang++-3.5
cxxstd: "03,11"
os: ubuntu-20.04
os: ubuntu-latest
container: ubuntu:16.04
install:
- clang-3.5
- toolset: clang
compiler: clang++-3.6
cxxstd: "03,11,14"
os: ubuntu-20.04
os: ubuntu-latest
container: ubuntu:16.04
install:
- clang-3.6
- toolset: clang
compiler: clang++-3.7
cxxstd: "03,11,14"
os: ubuntu-20.04
os: ubuntu-latest
container: ubuntu:16.04
install:
- clang-3.7
- toolset: clang
compiler: clang++-3.8
cxxstd: "03,11,14"
os: ubuntu-20.04
os: ubuntu-latest
container: ubuntu:16.04
install:
- clang-3.8
- toolset: clang
compiler: clang++-3.9
cxxstd: "03,11,14"
os: ubuntu-18.04
os: ubuntu-latest
container: ubuntu:18.04
install:
- clang-3.9
- toolset: clang
compiler: clang++-4.0
cxxstd: "03,11,14"
os: ubuntu-18.04
os: ubuntu-latest
container: ubuntu:18.04
install:
- clang-4.0
- toolset: clang
compiler: clang++-5.0
cxxstd: "03,11,14,1z"
os: ubuntu-18.04
os: ubuntu-latest
container: ubuntu:18.04
install:
- clang-5.0
- toolset: clang
compiler: clang++-6.0
cxxstd: "03,11,14,17"
os: ubuntu-18.04
os: ubuntu-latest
container: ubuntu:18.04
install:
- clang-6.0
- toolset: clang
compiler: clang++-7
cxxstd: "03,11,14,17"
os: ubuntu-18.04
os: ubuntu-latest
container: ubuntu:18.04
install:
- clang-7
# Note: clang-8 does not fully support C++20, so it is not compatible with libstdc++-8 in this mode
- toolset: clang
compiler: clang++-8
cxxstd: "03,11,14,17,2a"
os: ubuntu-18.04
os: ubuntu-latest
container: ubuntu:18.04
install:
- clang-8
- g++-7
@@ -194,45 +205,67 @@ jobs:
- toolset: clang
compiler: clang++-11
cxxstd: "03,11,14,17,20"
os: ubuntu-20.04
os: ubuntu-22.04
install:
- clang-11
- toolset: clang
compiler: clang++-12
cxxstd: "03,11,14,17,20"
os: ubuntu-20.04
cxxstd: "03,11,14,17,20,2b"
os: ubuntu-22.04
install:
- clang-12
- toolset: clang
compiler: clang++-12
cxxstd: "03,11,14,17,20"
compiler: clang++-13
cxxstd: "03,11,14,17,20,2b"
os: ubuntu-22.04
install:
- clang-13
- toolset: clang
compiler: clang++-14
cxxstd: "03,11,14,17,20,2b"
os: ubuntu-22.04
install:
- clang-14
- toolset: clang
compiler: clang++-15
cxxstd: "03,11,14,17,20,2b"
os: ubuntu-22.04
install:
- clang-15
sources:
- "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-15 main"
source_keys:
- "https://apt.llvm.org/llvm-snapshot.gpg.key"
- toolset: clang
compiler: clang++-15
cxxstd: "03,11,14,17,20,2b"
os: ubuntu-22.04
install:
- clang-15
- libc++-15-dev
- libc++abi-15-dev
sources:
- "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-15 main"
source_keys:
- "https://apt.llvm.org/llvm-snapshot.gpg.key"
cxxflags: -stdlib=libc++
linkflags: -stdlib=libc++
os: ubuntu-20.04
install:
- clang-12
- libc++-12-dev
- libc++abi-12-dev
- name: UBSAN
toolset: clang
compiler: clang++-12
cxxstd: "03,11,14,17,20"
compiler: clang++-14
cxxstd: "03,11,14,17,20,2b"
cxxflags: -stdlib=libc++
linkflags: -stdlib=libc++
ubsan: 1
os: ubuntu-20.04
os: ubuntu-22.04
install:
- clang-12
- libc++-12-dev
- libc++abi-12-dev
- clang-14
- libc++-14-dev
- libc++abi-14-dev
- toolset: clang
cxxstd: "03,11,14,17,2a"
os: macos-10.15
- name: CMake tests
cmake_tests: 1
os: ubuntu-20.04
os: macos-11
timeout-minutes: 120
runs-on: ${{matrix.os}}
@@ -252,38 +285,48 @@ jobs:
if [ -f "/etc/debian_version" ]
then
apt-get -o Acquire::Retries=$NET_RETRY_COUNT update
apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y sudo software-properties-common tzdata wget curl apt-transport-https ca-certificates make build-essential g++ python python3 git cmake
if [ "$(apt-cache search "^python-is-python3$" | wc -l)" -ne 0 ]
then
PYTHON_PACKAGE="python-is-python3"
else
PYTHON_PACKAGE="python"
fi
apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y sudo software-properties-common tzdata wget curl apt-transport-https ca-certificates make build-essential g++ $PYTHON_PACKAGE python3 perl git cmake
fi
fi
git config --global pack.threads 0
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Install packages
if: matrix.install
run: |
SOURCE_KEYS=(${{join(matrix.source_keys, ' ')}})
SOURCES=(${{join(matrix.sources, ' ')}})
declare -a SOURCE_KEYS SOURCES
if [ -n "${{join(matrix.source_keys, ' ')}}" ]
then
SOURCE_KEYS=("${{join(matrix.source_keys, '" "')}}")
fi
if [ -n "${{join(matrix.sources, ' ')}}" ]
then
SOURCES=("${{join(matrix.sources, '" "')}}")
fi
for key in "${SOURCE_KEYS[@]}"
do
for i in {1..$NET_RETRY_COUNT}
do
echo "Adding key: $key"
wget -O - "$key" | sudo apt-key add - && break || sleep 2
done
done
if [ ${#SOURCES[@]} -gt 0 ]
then
APT_ADD_REPO_COMMON_ARGS=("-y")
APT_ADD_REPO_HAS_SOURCE_ARGS=0
SOFTWARE_PROPERTIES_VERSION="$(dpkg-query --showformat='${Version}' --show software-properties-common)"
if dpkg --compare-versions "$SOFTWARE_PROPERTIES_VERSION" ge "0.96.24.20"
APT_ADD_REPO_SUPPORTED_ARGS="$(apt-add-repository --help | perl -ne 'if (/^\s*-n/) { print "n"; } elsif (/^\s*-P/) { print "P"; } elsif (/^\s*-S/) { print "S"; } elsif (/^\s*-U/) { print "U"; }')"
if [ -n "$APT_ADD_REPO_SUPPORTED_ARGS" -a -z "${APT_ADD_REPO_SUPPORTED_ARGS##*n*}" ]
then
APT_ADD_REPO_COMMON_ARGS+=("-n")
fi
if dpkg --compare-versions "$SOFTWARE_PROPERTIES_VERSION" ge "0.98.10"
then
APT_ADD_REPO_HAS_SOURCE_ARGS=1
fi
APT_ADD_REPO_HAS_SOURCE_ARGS="$([ -n "$APT_ADD_REPO_SUPPORTED_ARGS" -a -z "${APT_ADD_REPO_SUPPORTED_ARGS##*P*}" -a -z "${APT_ADD_REPO_SUPPORTED_ARGS##*S*}" -a -z "${APT_ADD_REPO_SUPPORTED_ARGS##*U*}" ] && echo 1 || echo 0)"
for source in "${SOURCES[@]}"
do
for i in {1..$NET_RETRY_COUNT}
@@ -304,6 +347,7 @@ jobs:
esac
fi
APT_ADD_REPO_ARGS+=("$source")
echo "apt-add-repository ${APT_ADD_REPO_ARGS[@]}"
sudo -E apt-add-repository "${APT_ADD_REPO_ARGS[@]}" && break || sleep 2
done
done
@@ -334,11 +378,12 @@ jobs:
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
REF=${REF#refs/heads/}
echo REF: $REF
BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true
BOOST_BRANCH=develop && [ "$REF" = "master" ] && BOOST_BRANCH=master || true
echo BOOST_BRANCH: $BOOST_BRANCH
BUILD_JOBS=$((nproc || sysctl -n hw.ncpu) 2> /dev/null)
echo "BUILD_JOBS=$BUILD_JOBS" >> $GITHUB_ENV
echo "CMAKE_BUILD_PARALLEL_LEVEL=$BUILD_JOBS" >> $GITHUB_ENV
DEPINST_ARGS=()
GIT_VERSION="$(git --version | sed -e 's/git version //')"
GIT_HAS_JOBS=1
if [ -f "/etc/debian_version" ]
@@ -365,36 +410,26 @@ jobs:
fi
if [ "$GIT_HAS_JOBS" -ne 0 ]
then
GIT_ARGS="--jobs $GIT_FETCH_JOBS"
DEPINST_ARGS+=("--git_args" "--jobs $GIT_FETCH_JOBS")
fi
cd ..
git clone -b "$BOOST_BRANCH" --depth 1 "https://github.com/boostorg/boost.git" "boost-root"
cd boost-root
mkdir -p libs/$LIBRARY
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
git submodule init tools/boost_install
git submodule init libs/headers
git submodule init tools/build
git submodule init tools/cmake
git submodule init libs/assert
git submodule init libs/config
git submodule init libs/static_assert
git submodule init libs/throw_exception
git submodule init libs/type_traits
git submodule update $GIT_ARGS
if [ -z "${{matrix.cmake_tests}}" ]
git submodule update --init tools/boostdep
DEPINST_ARGS+=("$LIBRARY")
python tools/boostdep/depinst/depinst.py "${DEPINST_ARGS[@]}"
./bootstrap.sh
./b2 headers
if [ -n "${{matrix.compiler}}" -o -n "$GCC_TOOLCHAIN_ROOT" ]
then
./bootstrap.sh
./b2 headers
if [ -n "${{matrix.compiler}}" -o -n "$GCC_TOOLCHAIN_ROOT" ]
echo -n "using ${{matrix.toolset}} : : ${{matrix.compiler}}" > ~/user-config.jam
if [ -n "$GCC_TOOLCHAIN_ROOT" ]
then
echo -n "using ${{matrix.toolset}} : : ${{matrix.compiler}}" > ~/user-config.jam
if [ -n "$GCC_TOOLCHAIN_ROOT" ]
then
echo -n " : <compileflags>\"--gcc-toolchain=$GCC_TOOLCHAIN_ROOT\" <linkflags>\"--gcc-toolchain=$GCC_TOOLCHAIN_ROOT\"" >> ~/user-config.jam
fi
echo " ;" >> ~/user-config.jam
echo -n " : <compileflags>\"--gcc-toolchain=$GCC_TOOLCHAIN_ROOT\" <linkflags>\"--gcc-toolchain=$GCC_TOOLCHAIN_ROOT\"" >> ~/user-config.jam
fi
echo " ;" >> ~/user-config.jam
fi
- name: Run tests
@@ -428,51 +463,24 @@ jobs:
B2_ARGS+=("libs/$LIBRARY/test")
./b2 "${B2_ARGS[@]}"
- name: Run CMake tests
if: matrix.cmake_tests != ''
run: |
cd ../boost-root
mkdir __build_cmake_test__ && cd __build_cmake_test__
cmake -DBUILD_TESTING=ON -DBOOST_INCLUDE_LIBRARIES=$LIBRARY ..
cmake --build . --target tests
ctest --output-on-failure
- name: Run CMake subdir tests
if: matrix.cmake_tests != ''
run: |
cd ../boost-root/libs/$LIBRARY/test/cmake_subdir_test
mkdir __build_cmake_subdir_test__ && cd __build_cmake_subdir_test__
cmake ..
cmake --build .
cmake --build . --target check
- name: Run CMake install tests
if: matrix.cmake_tests != ''
run: |
cd ../boost-root
mkdir __build_cmake_install_test__ && cd __build_cmake_install_test__
cmake -DBOOST_INCLUDE_LIBRARIES=$LIBRARY -DCMAKE_INSTALL_PREFIX=~/.local ..
cmake --build . --target install
cd ../libs/$LIBRARY/test/cmake_install_test
mkdir __build_cmake_install_test__ && cd __build_cmake_install_test__
cmake -DCMAKE_INSTALL_PREFIX=~/.local ..
cmake --build .
cmake --build . --target check
windows:
strategy:
fail-fast: false
matrix:
include:
- toolset: msvc-14.1
cxxstd: "14,17,latest"
- toolset: msvc-14.0
cxxstd: "14"
addrmd: 32,64
os: windows-2016
os: windows-2019
- toolset: msvc-14.2
cxxstd: "14,17,latest"
cxxstd: "14,17,20,latest"
addrmd: 32,64
os: windows-2019
- toolset: msvc-14.3
cxxstd: "14,17,20,latest"
addrmd: 32,64
os: windows-2022
- toolset: clang-win
cxxstd: "14,17,latest"
addrmd: 32,64
os: windows-2022
@@ -484,7 +492,7 @@ jobs:
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Setup Boost
shell: cmd
@@ -503,16 +511,8 @@ jobs:
git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
xcopy /s /e /q %GITHUB_WORKSPACE% libs\%LIBRARY%\
git submodule init tools/boost_install
git submodule init libs/headers
git submodule init tools/build
git submodule init tools/cmake
git submodule init libs/assert
git submodule init libs/config
git submodule init libs/static_assert
git submodule init libs/throw_exception
git submodule init libs/type_traits
git submodule update --jobs %GIT_FETCH_JOBS%
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py --git_args "--jobs %GIT_FETCH_JOBS%" %LIBRARY%
cmd /c bootstrap
b2 -d0 headers
@@ -520,4 +520,160 @@ jobs:
shell: cmd
run: |
cd ../boost-root
b2 -j %NUMBER_OF_PROCESSORS% libs/%LIBRARY%/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release
b2 -j %NUMBER_OF_PROCESSORS% libs/%LIBRARY%/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release embed-manifest-via=linker
posix-cmake-subdir:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-20.04
- os: ubuntu-22.04
- os: macos-11
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v3
- name: Install packages
if: matrix.install
run: sudo apt install ${{matrix.install}}
- name: Setup Boost
run: |
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
LIBRARY=${GITHUB_REPOSITORY#*/}
echo LIBRARY: $LIBRARY
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
echo GITHUB_REF: $GITHUB_REF
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
REF=${REF#refs/heads/}
echo REF: $REF
BOOST_BRANCH=develop && [ "$REF" = "master" ] && BOOST_BRANCH=master || true
echo BOOST_BRANCH: $BOOST_BRANCH
cd ..
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py --git_args "--jobs $GIT_FETCH_JOBS" $LIBRARY
- name: Use library with add_subdirectory
run: |
cd ../boost-root/libs/$LIBRARY/test/cmake_subdir_test
mkdir __build__ && cd __build__
cmake ..
cmake --build . -- -j $BUILD_JOBS
ctest --output-on-failure --no-tests=error
posix-cmake-install:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-20.04
- os: ubuntu-22.04
- os: macos-11
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v3
- name: Install packages
if: matrix.install
run: sudo apt install ${{matrix.install}}
- name: Setup Boost
run: |
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
LIBRARY=${GITHUB_REPOSITORY#*/}
echo LIBRARY: $LIBRARY
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
echo GITHUB_REF: $GITHUB_REF
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
REF=${REF#refs/heads/}
echo REF: $REF
BOOST_BRANCH=develop && [ "$REF" = "master" ] && BOOST_BRANCH=master || true
echo BOOST_BRANCH: $BOOST_BRANCH
cd ..
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py --git_args "--jobs $GIT_FETCH_JOBS" $LIBRARY
- name: Configure
run: |
cd ../boost-root
mkdir __build__ && cd __build__
cmake -DBOOST_INCLUDE_LIBRARIES=$LIBRARY -DCMAKE_INSTALL_PREFIX=~/.local ..
- name: Install
run: |
cd ../boost-root/__build__
cmake --build . --target install -- -j $BUILD_JOBS
- name: Use the installed library
run: |
cd ../boost-root/libs/$LIBRARY/test/cmake_install_test && mkdir __build__ && cd __build__
cmake -DCMAKE_INSTALL_PREFIX=~/.local ..
cmake --build . -- -j $BUILD_JOBS
ctest --output-on-failure --no-tests=error
posix-cmake-test:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-20.04
- os: ubuntu-22.04
- os: macos-11
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v3
- name: Install packages
if: matrix.install
run: sudo apt install ${{matrix.install}}
- name: Setup Boost
run: |
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
LIBRARY=${GITHUB_REPOSITORY#*/}
echo LIBRARY: $LIBRARY
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
echo GITHUB_REF: $GITHUB_REF
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
REF=${REF#refs/heads/}
echo REF: $REF
BOOST_BRANCH=develop && [ "$REF" = "master" ] && BOOST_BRANCH=master || true
echo BOOST_BRANCH: $BOOST_BRANCH
cd ..
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py --git_args "--jobs $GIT_FETCH_JOBS" $LIBRARY
- name: Configure
run: |
cd ../boost-root
mkdir __build__ && cd __build__
cmake -DBOOST_INCLUDE_LIBRARIES=$LIBRARY -DBUILD_TESTING=ON ..
- name: Build tests
run: |
cd ../boost-root/__build__
cmake --build . --target tests -- -j $BUILD_JOBS
- name: Run tests
run: |
cd ../boost-root/__build__
ctest --output-on-failure --no-tests=error

View File

@@ -1,4 +1,4 @@
# Copyright 2016-2019 Peter Dimov
# Copyright 2016-2021 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)
@@ -29,14 +29,9 @@ environment:
# clang-win 32 bit fails to link with "unable to load mspdbcore.dll (error code: 126)"
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
TOOLSET: clang-win
ADDRMD: 64
CXXSTD: 14,17
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
TOOLSET: msvc-14.2
ADDRMD: 32,64
CXXSTD: 14,17,latest
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
@@ -65,22 +60,15 @@ environment:
CXXSTD: 03,11,14,1z
install:
- set GIT_FETCH_JOBS=8
- set BOOST_BRANCH=develop
- if "%APPVEYOR_REPO_BRANCH%" == "master" set BOOST_BRANCH=master
- cd ..
- git clone -b %BOOST_BRANCH% https://github.com/boostorg/boost.git boost-root
- cd boost-root
- git submodule init libs/headers
- git submodule init libs/assert
- git submodule init libs/config
- git submodule init libs/predef
- git submodule init libs/static_assert
- git submodule init libs/throw_exception
- git submodule init libs/type_traits
- git submodule init tools/build
- git submodule init tools/boost_install
- git submodule update --jobs 4
- git submodule update --init tools/boostdep
- xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\core\
- python tools/boostdep/depinst/depinst.py --git_args "--jobs %GIT_FETCH_JOBS%" core
- cmd /c bootstrap
- b2 headers
@@ -90,4 +78,4 @@ test_script:
- PATH=%ADDPATH%%PATH%
- if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
- if not "%ADDRMD%" == "" set ADDRMD=address-model=%ADDRMD%
- b2 -j %NUMBER_OF_PROCESSORS% libs/core/test toolset=%TOOLSET% %CXXSTD% %ADDRMD% variant=debug,release
- b2 -j %NUMBER_OF_PROCESSORS% libs/core/test toolset=%TOOLSET% %CXXSTD% %ADDRMD% variant=debug,release embed-manifest-via=linker

View File

@@ -5,12 +5,15 @@
# Version 1.0. (See accompanying file LICENSE_1_0.txt
# or copy at http://boost.org/LICENSE_1_0.txt)
import project ;
import doxygen ;
import quickbook ;
path-constant INCLUDES : ../../.. ;
doxygen ref_reference
:
[ glob ../../../boost/core/ref.hpp ]
$(INCLUDES)/boost/core/ref.hpp
:
<doxygen:param>ENABLE_PREPROCESSING=YES
<doxygen:param>EXPAND_ONLY_PREDEF=YES

View File

@@ -1,149 +0,0 @@
[/
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)
]
[section:alloc_construct alloc_construct, alloc_destroy]
[simplesect Authors]
* Glen Fernandes
[endsimplesect]
[section Overview]
The header <boost/core/alloc_construct.hpp> provides function templates
`alloc_construct`, `alloc_construct_n`, `alloc_destroy`, and `alloc_destroy_n`
for allocator aware and exception safe construction and destruction of objects
and arrays.
[endsect]
[section Example]
The following example allocates storage for an array of `n` elements of `T`
using an allocator `a` and constructs `T` elements in that storage. If any
exception was thrown during construction of an element, the constructed
elements are destroyed in reverse order.
```
template<class A>
auto create(A& a, std::size_t n)
{
auto p = a.allocate(n);
try {
boost::alloc_construct_n(a, boost::to_address(p), n);
} catch (...) {
a.deallocate(p, n);
throw;
}
return p;
}
```
[endsect]
[section Reference]
```
namespace boost {
template<class A, class T>
void alloc_destroy(A& a, T* p);
template<class A, class T>
void alloc_destroy_n(A& a, T* p, std::size_t n);
template<class A, class T, class Args>
void alloc_construct(A& a, T* p, Args&&... args);
template<class A, class T>
void alloc_construct_n(A& a, T* p, std::size_t n);
template<class A, class T>
void alloc_construct_n(A& a, T* p, std::size_t n, const T* l, std::size_t m);
template<class A, class T, class I>
void alloc_construct_n(A& a, T* p, std::size_t n, I begin);
} /* boost */
```
[section Functions]
[variablelist
[[`template<class A, class T> void alloc_destroy(A& a, T* p);`]
[[variablelist
[[Requires][`A` is an /Allocator/]]
[[Effects][`std::allocator_traits<A>::destroy(a, p)`.]]]]]
[[`template<class A, class T> void alloc_destroy_n(A& a, T* p,
std::size_t n);`]
[[variablelist
[[Requires][`A` is an /Allocator/]]
[[Effects]
[Destroys each `i`-th element in reverse order by calling
`std::allocator_traits<A>::destroy(a, &p[i])`.]]]]]
[[`template<class A, class T, class Args> void alloc_construct(A& a, T* p,
Args&&... args);`]
[[variablelist
[[Requires][`A` is an /Allocator/]]
[[Effects]
[`std::allocator_traits<A>::construct(a, p, std::forward<Args>(args)...)`.]]]]]
[[`template<class A, class T> void alloc_construct_n(A& a, T* p,
std::size_t n);`]
[[variablelist
[[Requires][`A` is an /Allocator/]]
[[Effects]
[Constructs each `i`-th element in order by calling
`std::allocator_traits<A>::construct(a, &p[i])`.]]
[[Remarks]
[If an exception is thrown destroys each already constructed `j`-th element in
reverse order by calling `std::allocator_traits<A>::destroy(a, &p[j])`.]]]]]
[[`template<class A, class T> void alloc_construct_n(A& a, T* p, std::size_t n,
const T* l, std::size_t m);`]
[[variablelist
[[Requires][`A` is an /Allocator/]]
[[Effects]
[Constructs each `i`-th element in order by calling
`std::allocator_traits<A>::construct(a, &p[i], l[i % m])`.]]
[[Remarks]
[If an exception is thrown destroys each already constructed `j`-th element in
reverse order by calling `std::allocator_traits<A>::destroy(a, &p[j])`.]]]]]
[[`template<class A, class T, class I> void alloc_construct_n(A& a, T* p,
std::size_t n, I begin);`]
[[variablelist
[[Requires]
[[itemized_list
[`A` is an /Allocator/][`I` is an /InputIterator/]]]]
[[Effects]
[Constructs each `i`-th element in order by calling
`std::allocator_traits<A>::construct(a, &p[i], *begin++])`.]]
[[Remarks]
[If an exception is thrown destroys each already constructed `j`-th element in
reverse order by calling `std::allocator_traits<A>::destroy(a, &p[j])`.]]]]]]
[endsect]
[endsect]
[section Compatibility]
When `BOOST_NO_CXX11_ALLOCATOR` is defined, and the C++11 allocator model is
not supported, these functions invoke constructors and destructors directly
without going through the supplied allocator.
[endsect]
[section Acknowledgments]
Glen Fernandes originally implemented this functionality in Boost.Smart_Ptr and
later moved these functions to Boost.Core for use in other Boost libraries,
such as Boost.Multi_Array and Boost.Histogram.
[endsect]
[endsect]

View File

@@ -1,12 +1,12 @@
[/
Copyright 2020 Glen Joseph Fernandes
Copyright 2020-2022 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
]
[section Allocator Access]
[section allocator_access]
[simplesect Authors]
@@ -21,6 +21,9 @@ templates to simplify allocator use. It provides the same functionality as the
C++ standard library `std::allocator_traits` but with individual templates for
each allocator feature.
It also adds additional functionality for allocator aware exception safe
construction and destruction of arrays.
These facilities also simplify existing libraries by avoiding having to check
for `BOOST_NO_CXX11_ALLOCATOR` and conditionally use `std::allocator_traits`.
@@ -51,6 +54,26 @@ public:
In C++11 or above, aliases such as `boost::allocator_pointer_t<A>` can be used
instead of `typename boost::allocator_pointer<A>::type`.
The following example allocates storage for an array of `n` elements of `T`
using an allocator `a` and constructs `T` elements in that storage. If any
exception was thrown during construction of an element, the constructed
elements are destroyed in reverse order.
```
template<class A>
auto create(A& a, std::size_t n)
{
auto p = a.allocate(n);
try {
boost::allocator_construct_n(a, boost::to_address(p), n);
} catch (...) {
a.deallocate(p, n);
throw;
}
return p;
}
```
[endsect]
[section Reference]
@@ -150,9 +173,22 @@ void allocator_deallocate(A& a, allocator_pointer_t<A> p,
template<class A, class T, class... Args>
void allocator_construct(A& a, T* p, Args&&... args);
template<class A, class T>
void allocator_construct_n(A& a, T* p, std::size_t n);
template<class A, class T>
void allocator_construct_n(A& a, T* p, std::size_t n, const T* l,
std::size_t m);
template<class A, class T, class I>
void allocator_construct_n(A& a, T* p, std::size_t n, I begin);
template<class A, class T>
void allocator_destroy(A& a, T* p);
template<class A, class T>
void allocator_destroy_n(A& a, T* p, std::size_t n);
template<class A>
allocator_size_type_t<A> allocator_max_size(const A& a);
@@ -168,7 +204,8 @@ A allocator_select_on_container_copy_construction(const A& a);
[[`template<class A> struct allocator_value_type;`]
[The member `type` is `A::value_type`.]]
[[`template<class A> struct allocator_pointer;`]
[The member `type` is `A::pointer` if valid, otherwise `A::value_type*`.]]
[The member `type` is `A::pointer` if valid, otherwise
`allocator_value_type_t<A>*`.]]
[[`template<class A> struct allocator_const_pointer;`]
[The member `type` is `A::const_pointer` if valid, otherwise
`pointer_traits<allocator_pointer_t<A> >::rebind<const
@@ -219,12 +256,34 @@ allocator_size_type_t<A> n);`]
void allocator_construct(A& a, T*p, Args&&... args);`]
[Calls `a.construct(p, std::forward<Args>(args)...)` if valid, otherwise calls
`::new(static_cast<void*>(p)) T(std::forward<Args>(args)...)`.]]
[[`template<class A, class T>
void alloc_construct_n(A& a, T* p, std::size_t n);`]
[Constructs each `i`-th element in order by calling
`boost::allocator_construct(a, &p[i])`.
If an exception is thrown destroys each already constructed `j`-th element in
reverse order by calling `boost::allocator_destroy(a, &p[j])`.]]
[[`template<class A, class T>
void alloc_construct_n(A& a, T* p, std::size_t n, const T* l, std::size_t m);`]
[Constructs each `i`-th element in order by calling
`boost::allocator_construct(a, &p[i], l[i % m])`.
If an exception is thrown destroys each already constructed `j`-th element in
reverse order by calling `boost::allocator_destroy(a, &p[j])`.]]
[[`template<class A, class T, class I>
void alloc_construct_n(A& a, T* p, std::size_t n, I begin);`]
[Constructs each `i`-th element in order by calling
`boost::allocator_construct(a, &p[i], *begin++)`.
If an exception is thrown destroys each already constructed `j`-th element in
reverse order by calling `boost::allocator_destroy(a, &p[j])`.]]
[[`template<class A, class T> void allocator_destroy(A& a, T* p);`]
[Calls `a.destroy(p)` if valid, otherwise calls `p->~T()`.]]
[[`template<class A, class T>
void allocator_destroy_n(A& a, T* p, std::size_t n);`]
[Destroys each `i`-th element in reverse order by calling
`boost::allocator_destroy(a, &p[i])`.]]
[[`template<class A> allocator_size_type_t<A> allocator_max_size(const A& a);`]
[Returns `a.max_size()` if valid, otherwise returns
`std::numeric_limits<allocator_size_type_t<A> >::max() /
sizeof(A::value_type)`.]]
sizeof(allocator_value_type_t<A>)`.]]
[[`template<class A> A allocator_select_on_container_copy_construction(const
A& a);`]
[Returns `a.select_on_container_copy_construction()` if valid, otherwise
@@ -234,7 +293,7 @@ returns `a`.]]]
[endsect]
[section Acknowledgments]
[section Acknowledgements]
Glen Fernandes implemented the allocator access utilities.

116
doc/allocator_traits.qbk Normal file
View File

@@ -0,0 +1,116 @@
[/
Copyright 2021 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
]
[section:allocator_traits allocator_traits]
[simplesect Authors]
* Glen Fernandes
[endsimplesect]
[section Overview]
This header <boost/core/allocator_traits.hpp> provides an implementation of the
C++ standard library class template `allocator_traits` based on the facilities
in [link core.allocator_access Allocator Access]. Users should still prefer the
individual traits, but this utility exists to simplify migration.
[endsect]
[section Reference]
```
namespace boost {
template<class A>
struct allocator_traits {
using allocator_type = A;
using value_type = allocator_value_type_t<A>;
using pointer = allocator_pointer_t<A>;
using const_pointer = allocator_const_pointer_t<A>;
using void_pointer = allocator_void_pointer_t<A>;
using const_pointer = allocator_const_void_pointer_t<A>;
using difference_type = allocator_difference_type_t<A>;
using size_type = allocator_size_type_t<A>;
using propagate_on_container_copy_assignment =
allocator_propagate_on_container_copy_assignment_t<A>;
using propagate_on_container_move_assignment =
allocator_propagate_on_container_move_assignment_t<A>;
using propagate_on_container_swap =
allocator_propagate_on_container_swap_t<A>;
using is_always_equal = allocator_is_always_equal_t<A>;
template<class T>
using rebind_traits = allocator_traits<allocator_rebind_t<A, T> >;
static pointer allocate(A& a, size_type n);
static pointer allocate(A& a, size_type n, const_void_pointer h);
static void deallocate(A& a, pointer p, size_type n);
template<class T, class... Args>
static void construct(A& a, T* p, Args&&... args);
static void destroy(A& a, T* p);
static size_type max_size(const A& a) noexcept;
static A select_on_container_copy_construction(const A& a);
};
} /* boost */
```
[section Static member functions]
[variablelist
[[`static pointer allocate(A& a, size_type n);`]
[Equivalent to: `return boost::allocator_allocate(a, n);`]]
[[`static pointer allocate(A& a, size_type n, const_void_pointer h);`]
[Equivalent to: `return boost::allocator_allocate(a, n, h);`]]
[[`static void deallocate(A& a, pointer p, size_type n);`]
[Equivalent to: `boost::allocator_deallocate(a, n, h);`]]
[[`template<class T, class... Args>
static void construct(A& a, T* p, Args&&... args);`]
[Equivalent to:
`boost::allocator_construct(a, p, std::forward<Args>(args)...);`]]
[[`static void destroy(A& a, T* p);`]
[Equivalent to: `boost::allocator_destroy(a, p);`]]
[[`static size_type max_size(const A& a) noexcept;`]
[Equivalent to: `return boost::allocator_max_size(a);`]]
[[`static A select_on_container_copy_construction(const A& a);`]
[Equivalent to:
`return boost::allocator_select_on_container_copy_construction(a);`]]]
[endsect]
[endsect]
[section Notes]
# The member `rebind_alloc` is not provided for parity with C++03 where it is
unimplementable. Instead of `allocator_traits<A>::rebind_alloc<U>` you can
express the same with `allocator_traits<A>::rebind_traits<U>::allocator_type`
or more simply with `allocator_rebind_t<A, U>`.
[endsect]
[endsect]

View File

@@ -45,7 +45,7 @@ template<class T>
constexpr T bit_floor(T x) noexcept;
template<class T>
constexpr T bit_width(T x) noexcept;
constexpr int bit_width(T x) noexcept;
// Rotating
@@ -119,7 +119,7 @@ constant expression context.
* *Requires:* `T` must be an unsigned integer type.
* *Returns:* If `x == 0`, 0; otherwise the maximal value `y` such that `has_single_bit(y)` is `true` and `y <= x`.
`template<class T> constexpr T bit_width(T x) noexcept;`
`template<class T> constexpr int bit_width(T x) noexcept;`
* *Requires:* `T` must be an unsigned integer type.
* *Returns:* If `x == 0`, 0; otherwise one plus the base-2 logarithm of `x`, with any fractional part discarded.

View File

@@ -6,6 +6,45 @@
[section Revision History]
[section Changes in 1.81.0]
* [link core.empty_value `empty_value`] members are now marked as `constexpr`.
* Added [link core.fclose_deleter `fclose_deleter`], a deleter that calls `std::fclose` on a pointer to `std::FILE`.
* Bit manipulation utilities in [link core.bit `boost/core/bit.hpp`] now explicitly require unsigned integers on input.
([@https://github.com/boostorg/core/issues/129 #129])
* `bit_width` now returns `int` instead of a value of the input argument type. This follows the
resolution of [@https://cplusplus.github.io/LWG/issue3656 LWG3656].
[endsect]
[section Changes in 1.80.0]
* In [link core.allocator_access `boost/core/allocator_access.hpp`], added detection of `construct` and `destroy`
members of an allocator.
* `boost/core/alloc_construct.hpp` header is now deprecated and will be removed in a future release. Its functionality
was moved to [link core.allocator_access `boost/core/allocator_access.hpp`]. In particular, new methods
`allocator_construct_n` and `allocator_destroy_n` were added for allocating and destroying arrays.
* Worked around MSVC bug that failed to compile [link core.span `span`] in C++17 mode when Boost.Range headers were included.
([@https://github.com/boostorg/core/issues/105 #105], [@https://github.com/boostorg/core/pull/115 PR#115])
* Added support for 128-bit integer types in [link core.type_name `type_name`].
* In [link core.pointer_traits `pointer_traits`], pointer rebinding now supports C++03 compilers.
[endsect]
[section Changes in 1.79.0]
* Added `boost::allocator_traits`, an implementation of `std::allocator_traits`.
* Made `boost::pointer_traits` SFINAE friendly.
* `boost/iterator.hpp` is deprecated and will be removed in a future release. The header defines the
`boost::iterator` template, which is equivalent to `std::iterator` in the `<iterator>` header. However,
since `std::iterator` is itself deprecated in C++17, users are advised to remove the use of `boost::iterator`
or `std::iterator` from their code.
* Added `boost::core::verbose_terminate_handler`, a utility function intended
to be passed to `std::set_terminate` that prints information about the
uncaught exception to `stderr`.
[endsect]
[section Changes in 1.78.0]
* Added a generic implementation to `boost/core/cmath.hpp`, enabled when `BOOST_CORE_USE_GENERIC_CMATH`

View File

@@ -34,7 +34,7 @@ criteria for inclusion is that the utility component be:
* simple,
* used by other Boost libraries, and
* not dependent on any other Boost modules except Core
itself, Config, Assert, or Static Assert.
itself, Config, Assert, StaticAssert, or ThrowException.
[endsect]
@@ -42,7 +42,7 @@ criteria for inclusion is that the utility component be:
[include addressof.qbk]
[include allocator_access.qbk]
[include alloc_construct.qbk]
[include allocator_traits.qbk]
[include bit.qbk]
[include checked_delete.qbk]
[include cmath.qbk]
@@ -60,6 +60,7 @@ criteria for inclusion is that the utility component be:
[include noinit_adaptor.qbk]
[include noncopyable.qbk]
[include null_deleter.qbk]
[include fclose_deleter.qbk]
[include nvp.qbk]
[include pointer_traits.qbk]
[include quick_exit.qbk]
@@ -71,3 +72,4 @@ criteria for inclusion is that the utility component be:
[include type_name.qbk]
[include uncaught_exceptions.qbk]
[include use_default.qbk]
[include verbose_terminate_handler.qbk]

View File

@@ -125,7 +125,7 @@ return `nullptr` if demangling failed.
[endsect]
[section Acknowledgments]
[section Acknowledgements]
The implementation of `core::demangle` was taken from
`boost/exception/detail/type_info.hpp`, which in turn was adapted

View File

@@ -90,11 +90,11 @@ public:
empty_value() = default;
template<class... Args>
empty_value(empty_init_t, Args&&... args);
constepxr empty_value(empty_init_t, Args&&... args);
const T& get() const noexcept;
constepxr const T& get() const noexcept;
T& get() noexcept;
constepxr T& get() noexcept;
};
inline constexpr empty_init_t empty_init{ };
@@ -121,8 +121,9 @@ inline constexpr empty_init_t empty_init{ };
[section Constructors]
[variablelist
[[`empty_value() = default;`][Default initialize the value]]
[[`template<class... Args> empty_value(empty_init_t, Args&&... args);`]
[[`constepxr empty_value() = default;`][Default initialize the value]]
[[`template<class... Args>
constepxr empty_value(empty_init_t, Args&&... args);`]
[Initialize the value with `std::forward<Args>(args)...`]]]
[endsect]
@@ -130,8 +131,8 @@ inline constexpr empty_init_t empty_init{ };
[section Member functions]
[variablelist
[[`const T& get() const noexcept;`][Returns the value]]
[[`T& get() noexcept;`][Returns the value]]]
[[`constepxr const T& get() const noexcept;`][Returns the value]]
[[`constepxr T& get() noexcept;`][Returns the value]]]
[endsect]

View File

@@ -304,8 +304,8 @@ depends on the template arguments of the class. Note that
again, the second argument to `enable_if` is not needed; the
default (`void`) is the correct value.
The `enable_if_has_type` template is usable this scenario but instead of
using a type traits to enable or disable a specialization, it use a
The `enable_if_has_type` template is usable in this scenario but instead of
using a type trait to enable or disable a specialization, it uses a
SFINAE context to check for the existence of a dependent type inside
its parameter. For example, the following structure extracts a dependent
`value_type` from T if and only if `T::value_type` exists.

34
doc/fclose_deleter.qbk Normal file
View File

@@ -0,0 +1,34 @@
[/
/ Copyright (c) 2022 Andrey Semashev
/
/ 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)
/]
[section:fclose_deleter fclose_deleter]
[simplesect Authors]
* Andrey Semashev
[endsimplesect]
[section Header <boost/core/fclose_deleter.hpp>]
The header `<boost/core/fclose_deleter.hpp>` defines the `boost::fclose_deleter` function object,
which can be used as a deleter with smart pointers such as `unique_ptr` or `shared_ptr` pointing to `std::FILE`.
structures returned by `std::fopen` calls. The deleter calls `std::fclose` on the passed pointer, causing
the file stream to be flushed and closed.
[section Example]
``
std::unique_ptr< std::FILE, boost::fclose_deleter > make_file(const char* filename, const char* open_mode)
{
return { std::fopen(filename, open_mode) };
}
``
[endsect]
[endsect]
[endsect]

View File

@@ -51,7 +51,7 @@ int fun( int foo, int bar )
[endsect]
[section Acknowledgments]
[section Acknowledgements]
`boost::ignore_unused()` was contributed by Adam Wulkiewicz.

View File

@@ -1,5 +1,5 @@
[/
Copyright 2017-2018 Glen Joseph Fernandes
Copyright 2017-2021 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
@@ -47,68 +47,91 @@ void function(Allocator& a)
```
namespace boost {
template<class T> struct pointer_traits {
template<class T>
struct pointer_traits {
typedef T pointer;
typedef ``['see below]`` element_type;
typedef ``['see below]`` difference_type;
template<class U> struct rebind_to { typedef ``['see below]`` type; };
template<class U> using rebind = typename rebind_to<U>::type;
template<class U>
struct rebind_to {
typedef ``['see below]`` type;
};
static pointer pointer_to(``['see below]`` v);
};
template<class U>
using rebind = typename rebind_to<U>::type;
template<class T> struct pointer_traits<T*> {
static pointer pointer_to(element_type& v);
};
template<class T>
struct pointer_traits<T*> {
typedef T* pointer;
typedef T element_type;
typedef std::ptrdiff_t difference_type;
template<class U> struct rebind_to { typedef U* type; };
template<class U> using rebind = typename rebind_to<U>::type;
template<class U>
struct rebind_to {
typedef U* type;
};
template<class U>
using rebind = typename rebind_to<U>::type;
static pointer pointer_to(``['see below]`` v) noexcept;
};
};
template<class T>
constexpr T* to_address(T* v) noexcept;
template<class T>
constexpr T* to_address(T* v) noexcept;
template<class T>
auto to_address(const T& v) noexcept;
}
template<class T>
auto to_address(const T& v) noexcept;
} // boost
```
[section Overview]
If the member type `element_type` is not defined, then all other members are
also not defined (`pointer_traits` is SFINAE-friendly).
[endsect]
[section Member types]
[variablelist
[[`typedef` ['see below] `element_type;`]
[`T::element_type` if such a type exists; otherwise `U` if `T` is a class
template instantiation of the form `Pointer<U, Args>`, where `Args` is zero
or more type arguments; otherwise the specialization is ill-formed.]]
or more type arguments; otherwise the member is not defined.]]
[[`typedef` ['see below] `difference_type;`]
[`T::difference_type` if such a type exists; otherwise `std::ptrdiff_t`.]]
[[`template<class U> struct rebind_to { typedef` ['see below] `type; };`]
[`type` is `T::rebind<U>` if such a type exists; otherwise, `Pointer<V, Args>`
if `T` is a class template instantiation of the form `Pointer<T, Args>`,
where `Args` is zero or more type arguments; otherwise, the instantiation of
`rebind_to` is ill-formed.]]]
where `Args` is zero or more type arguments; otherwise, the member is not
defined.]]]
[note When C++11 template aliases are not supported, the `type` for `rebind` is
`T::rebind<U>::other` if such a type exists.]
[endsect]
[section Member functions]
[variablelist
[[`static pointer pointer_traits::pointer_to(`['see below] `v);`]
[[`static pointer pointer_traits::pointer_to(element_type& v);`]
[[variablelist
[[Remark]
[If `element_type` is a void type, the type of `v` is unspecified; otherwise,
it is `element_type&`.]]
[If `element_type` is a void type, or if `T::pointer_to(v)` is not well-formed,
this member is not defined.]]
[[Returns]
[A pointer to `v` obtained by calling `T::pointer_to(v)`.]]]]]
[[`static pointer pointer_traits<T*>::pointer_to(`['see below] `v) noexcept;`]
[[`static pointer pointer_traits<T*>::pointer_to(element_type& v) noexcept;`]
[[variablelist
[[Remark]
[If `element_type` is a void type, the type of `v` is unspecified; otherwise,
it is `element_type&`.]]
[If `element_type` is a void type, this member is not defined.]]
[[Returns][`addressof(v)`.]]]]]]
[endsect]
@@ -142,7 +165,7 @@ namespace boost {
[endsect]
[section Acknowledgments]
[section Acknowledgements]
Glen Fernandes implemented `pointer_traits` and `to_address` with reviews and
guidance from Peter Dimov.

View File

@@ -68,7 +68,7 @@ The type-expression `boost::unwrap_reference<T>::type` is
[xinclude ref_reference.xml]
[section Acknowledgments]
[section Acknowledgements]
`ref` and `cref` were originally part of the Tuple library by
Jaakko J\u00E4rvi. They were "promoted to `boost::` status" by

View File

@@ -46,7 +46,7 @@ The user can portably declare such enumeration as follows:
}
BOOST_SCOPED_ENUM_DECLARE_END(future_errc)
These macros allows to use `future_errc` in almost all the cases as an scoped enum.
These macros allow using `future_errc` in almost all the cases as a scoped enum.
future_errc ev = future_errc::no_state;
@@ -179,7 +179,7 @@ such cases.
[endsect]
[section Acknowledgments]
[section Acknowledgements]
This scoped enum emulation was developed by Beman Dawes, Vicente J. Botet Escriba and Anthony Williams.

View File

@@ -134,14 +134,6 @@ public:
constexpr const_iterator cend() const noexcept;
constexpr const_reverse_iterator crbegin() const noexcept;
constexpr const_reverse_iterator crend() const noexcept;
friend constexpr iterator begin(span s) noexcept {
return s.begin();
}
friend constexpr iterator end(span s) noexcept {
return s.end();
}
};
template<class I, class L>

View File

@@ -11,7 +11,7 @@ Distributed under the Boost Software License, Version 1.0.
[section Overview]
The header <boost/core/use_default.hpp> provides the type `boost::use_default`
which is used by other Boost libraries as a sentinel type in a templates to
which is used by other Boost libraries as a sentinel type in templates to
indicate defaults.
[endsect]

View File

@@ -0,0 +1,70 @@
[/
Copyright 2022 Peter Dimov
Distributed under the Boost Software License, Version 1.0.
https://boost.org/LICENSE_1_0.txt
]
[section:verbose_terminate_handler verbose_terminate_handler]
[simplesect Authors]
* Peter Dimov
[endsimplesect]
[section Header <boost/core/verbose_terminate_handler.hpp>]
The header `<boost/core/verbose_terminate_handler.hpp>` defines
the function `void boost::core::verbose_terminate_handler()`. Its
purpose is to be set as a terminate handler as in
```
std::set_terminate( boost::core::verbose_terminate_handler );
```
When invoked, the function prints information about the current
uncaught exception to `stderr` and then calls `std::abort`.
[section Synopsis]
``
namespace boost
{
namespace core
{
[[noreturn]] void verbose_terminate_handler();
} // namespace core
} // namespace boost
``
[endsect]
[section Example]
```
#include <boost/core/verbose_terminate_handler.hpp>
#include <boost/throw_exception.hpp>
#include <exception>
int main()
{
std::set_terminate( boost::core::verbose_terminate_handler );
boost::throw_with_location( std::exception() );
}
```
Sample output:
```
std::terminate called after throwing an exception:
type: class boost::detail::with_throw_location<class std::exception>
what(): Unknown exception
location: example.cpp:8:12 in function 'main'
```
[endsect]
[endsect]
[endsect]

View File

@@ -8,6 +8,9 @@ Distributed under the Boost Software License, Version 1.0.
#ifndef BOOST_CORE_ALLOC_CONSTRUCT_HPP
#define BOOST_CORE_ALLOC_CONSTRUCT_HPP
/*
This functionality is now in <boost/core/allocator_access.hpp>.
*/
#include <boost/core/noinit_adaptor.hpp>
namespace boost {
@@ -23,56 +26,9 @@ template<class A, class T>
inline void
alloc_destroy_n(A& a, T* p, std::size_t n)
{
while (n > 0) {
boost::allocator_destroy(a, p + --n);
}
boost::allocator_destroy_n(a, p, n);
}
template<class A, class T>
inline void
alloc_destroy(noinit_adaptor<A>&, T* p)
{
p->~T();
}
template<class A, class T>
inline void
alloc_destroy_n(noinit_adaptor<A>&, T* p, std::size_t n)
{
while (n > 0) {
p[--n].~T();
}
}
namespace detail {
template<class A, class T>
class alloc_destroyer {
public:
alloc_destroyer(A& a, T* p) BOOST_NOEXCEPT
: a_(a),
p_(p),
n_(0) { }
~alloc_destroyer() {
boost::alloc_destroy_n(a_, p_, n_);
}
std::size_t& size() BOOST_NOEXCEPT {
return n_;
}
private:
alloc_destroyer(const alloc_destroyer&);
alloc_destroyer& operator=(const alloc_destroyer&);
A& a_;
T* p_;
std::size_t n_;
};
} /* detail */
template<class A, class T>
inline void
alloc_construct(A& a, T* p)
@@ -117,51 +73,21 @@ template<class A, class T>
inline void
alloc_construct_n(A& a, T* p, std::size_t n)
{
detail::alloc_destroyer<A, T> hold(a, p);
for (std::size_t& i = hold.size(); i < n; ++i) {
boost::allocator_construct(a, p + i);
}
hold.size() = 0;
boost::allocator_construct_n(a, p, n);
}
template<class A, class T>
inline void
alloc_construct_n(A& a, T* p, std::size_t n, const T* l, std::size_t m)
{
detail::alloc_destroyer<A, T> hold(a, p);
for (std::size_t& i = hold.size(); i < n; ++i) {
boost::allocator_construct(a, p + i, l[i % m]);
}
hold.size() = 0;
boost::allocator_construct_n(a, p, n, l, m);
}
template<class A, class T, class I>
inline void
alloc_construct_n(A& a, T* p, std::size_t n, I b)
{
detail::alloc_destroyer<A, T> hold(a, p);
for (std::size_t& i = hold.size(); i < n; void(++i), void(++b)) {
boost::allocator_construct(a, p + i, *b);
}
hold.size() = 0;
}
template<class A, class T>
inline void
alloc_construct(noinit_adaptor<A>&, T* p)
{
::new(static_cast<void*>(p)) T;
}
template<class A, class T>
inline void
alloc_construct_n(noinit_adaptor<A>& a, T* p, std::size_t n)
{
detail::alloc_destroyer<noinit_adaptor<A>, T> hold(a, p);
for (std::size_t& i = hold.size(); i < n; ++i) {
::new(static_cast<void*>(p + i)) T;
}
hold.size() = 0;
boost::allocator_construct_n(a, p, n, b);
}
} /* boost */

View File

@@ -1,5 +1,5 @@
/*
Copyright 2020-2021 Glen Joseph Fernandes
Copyright 2020-2022 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
@@ -9,16 +9,34 @@ Distributed under the Boost Software License, Version 1.0.
#define BOOST_CORE_ALLOCATOR_ACCESS_HPP
#include <boost/config.hpp>
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
#include <boost/core/pointer_traits.hpp>
#include <limits>
#include <new>
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
#include <type_traits>
#endif
#include <new>
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
#include <utility>
#endif
#if defined(BOOST_GCC_VERSION) && (BOOST_GCC_VERSION >= 40300)
#define BOOST_DETAIL_ALLOC_EMPTY(T) __is_empty(T)
#elif defined(BOOST_INTEL) && defined(_MSC_VER) && (_MSC_VER >= 1500)
#define BOOST_DETAIL_ALLOC_EMPTY(T) __is_empty(T)
#elif defined(BOOST_MSVC) && (BOOST_MSVC >= 1400)
#define BOOST_DETAIL_ALLOC_EMPTY(T) __is_empty(T)
#elif defined(BOOST_CLANG) && !defined(__CUDACC__)
#if __has_feature(is_empty)
#define BOOST_DETAIL_ALLOC_EMPTY(T) __is_empty(T)
#endif
#elif defined(__SUNPRO_CC) && (__SUNPRO_CC >= 0x5130)
#define BOOST_DETAIL_ALLOC_EMPTY(T) __oracle_is_empty(T)
#elif defined(__ghs__) && (__GHS_VERSION_NUMBER >= 600)
#define BOOST_DETAIL_ALLOC_EMPTY(T) __is_empty(T)
#elif defined(BOOST_CODEGEARC)
#define BOOST_DETAIL_ALLOC_EMPTY(T) __is_empty(T)
#endif
#if defined(_LIBCPP_SUPPRESS_DEPRECATED_PUSH)
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
#endif
@@ -37,244 +55,311 @@ struct allocator_value_type {
typedef typename A::value_type type;
};
#if defined(BOOST_NO_CXX11_ALLOCATOR)
template<class A>
struct allocator_pointer {
typedef typename A::pointer type;
};
#else
template<class A, class = void>
struct allocator_pointer {
typedef typename A::value_type* type;
};
namespace detail {
template<class A, class = void>
struct alloc_ptr {
typedef typename boost::allocator_value_type<A>::type* type;
};
template<class>
struct alloc_void {
typedef void type;
};
} /* detail */
template<class A>
struct allocator_pointer<A,
typename detail::alloc_void<typename A::pointer>::type> {
struct alloc_ptr<A,
typename alloc_void<typename A::pointer>::type> {
typedef typename A::pointer type;
};
#endif
#if defined(BOOST_NO_CXX11_ALLOCATOR)
template<class A>
struct allocator_const_pointer {
typedef typename A::const_pointer type;
};
#else
template<class A, class = void>
struct allocator_const_pointer {
typedef typename pointer_traits<typename
allocator_pointer<A>::type>::template
rebind_to<const typename A::value_type>::type type;
};
} /* detail */
template<class A>
struct allocator_const_pointer<A,
typename detail::alloc_void<typename A::const_pointer>::type> {
typedef typename A::const_pointer type;
};
#endif
#if defined(BOOST_NO_CXX11_ALLOCATOR)
template<class A>
struct allocator_void_pointer {
typedef typename A::template rebind<void>::other::pointer type;
};
#else
template<class A, class = void>
struct allocator_void_pointer {
typedef typename pointer_traits<typename
allocator_pointer<A>::type>::template
rebind_to<void>::type type;
struct allocator_pointer {
typedef typename detail::alloc_ptr<A>::type type;
};
template<class A>
struct allocator_void_pointer<A,
typename detail::alloc_void<typename A::void_pointer>::type> {
typedef typename A::void_pointer type;
};
#endif
#if defined(BOOST_NO_CXX11_ALLOCATOR)
template<class A>
struct allocator_const_void_pointer {
typedef typename A::template rebind<void>::other::const_pointer type;
};
#else
template<class A, class = void>
struct allocator_const_void_pointer {
typedef typename pointer_traits<typename
allocator_pointer<A>::type>::template
rebind_to<const void>::type type;
};
template<class A>
struct allocator_const_void_pointer<A,
typename detail::alloc_void<typename A::const_void_pointer>::type> {
typedef typename A::const_void_pointer type;
};
#endif
#if defined(BOOST_NO_CXX11_ALLOCATOR)
template<class A>
struct allocator_difference_type {
typedef typename A::difference_type type;
};
#else
template<class A, class = void>
struct allocator_difference_type {
typedef typename pointer_traits<typename
allocator_pointer<A>::type>::difference_type type;
};
template<class A>
struct allocator_difference_type<A,
typename detail::alloc_void<typename A::difference_type>::type> {
typedef typename A::difference_type type;
};
#endif
#if defined(BOOST_NO_CXX11_ALLOCATOR)
template<class A>
struct allocator_size_type {
typedef typename A::size_type type;
};
#else
template<class A, class = void>
struct allocator_size_type {
typedef typename std::make_unsigned<typename
allocator_difference_type<A>::type>::type type;
};
template<class A>
struct allocator_size_type<A,
typename detail::alloc_void<typename A::size_type>::type> {
typedef typename A::size_type type;
};
#endif
#if defined(BOOST_NO_CXX11_ALLOCATOR)
namespace detail {
struct alloc_false {
BOOST_STATIC_CONSTEXPR bool value = false;
template<class A, class = void>
struct alloc_const_ptr {
typedef typename boost::pointer_traits<typename
boost::allocator_pointer<A>::type>::template rebind_to<const typename
boost::allocator_value_type<A>::type>::type type;
};
template<class A>
struct alloc_const_ptr<A,
typename alloc_void<typename A::const_pointer>::type> {
typedef typename A::const_pointer type;
};
} /* detail */
template<class A>
struct allocator_propagate_on_container_copy_assignment {
typedef detail::alloc_false type;
};
#else
template<class A, class = void>
struct allocator_propagate_on_container_copy_assignment {
typedef std::false_type type;
struct allocator_const_pointer {
typedef typename detail::alloc_const_ptr<A>::type type;
};
template<class A>
struct allocator_propagate_on_container_copy_assignment<A,
typename detail::alloc_void<typename
A::propagate_on_container_copy_assignment>::type> {
typedef typename A::propagate_on_container_copy_assignment type;
};
#endif
#if defined(BOOST_NO_CXX11_ALLOCATOR)
template<class A>
struct allocator_propagate_on_container_move_assignment {
typedef detail::alloc_false type;
};
#else
template<class A, class = void>
struct allocator_propagate_on_container_move_assignment {
typedef std::false_type type;
};
template<class A>
struct allocator_propagate_on_container_move_assignment<A,
typename detail::alloc_void<typename
A::propagate_on_container_move_assignment>::type> {
typedef typename A::propagate_on_container_move_assignment type;
};
#endif
#if defined(BOOST_NO_CXX11_ALLOCATOR)
template<class A>
struct allocator_propagate_on_container_swap {
typedef detail::alloc_false type;
};
#else
template<class A, class = void>
struct allocator_propagate_on_container_swap {
typedef std::false_type type;
};
template<class A>
struct allocator_propagate_on_container_swap<A,
typename detail::alloc_void<typename
A::propagate_on_container_swap>::type> {
typedef typename A::propagate_on_container_swap type;
};
#endif
#if defined(BOOST_NO_CXX11_ALLOCATOR)
template<class A>
struct allocator_is_always_equal {
typedef detail::alloc_false type;
};
#else
template<class A, class = void>
struct allocator_is_always_equal {
typedef typename std::is_empty<A>::type type;
};
template<class A>
struct allocator_is_always_equal<A,
typename detail::alloc_void<typename A::is_always_equal>::type> {
typedef typename A::is_always_equal type;
};
#endif
#if defined(BOOST_NO_CXX11_ALLOCATOR)
template<class A, class T>
struct allocator_rebind {
typedef typename A::template rebind<T>::other type;
};
#else
namespace detail {
template<class, class>
struct alloc_to { };
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<template<class> class A, class T, class U>
struct alloc_to<A<U>, T> {
typedef A<T> type;
};
template<template<class, class> class A, class T, class U, class V>
struct alloc_to<A<U, V>, T> {
typedef A<T, V> type;
};
template<template<class, class, class> class A, class T, class U, class V1,
class V2>
struct alloc_to<A<U, V1, V2>, T> {
typedef A<T, V1, V2> type;
};
#else
template<template<class, class...> class A, class T, class U, class... V>
struct alloc_to<A<U, V...>, T> {
typedef A<T, V...> type;
};
} /* detail */
#endif
template<class A, class T, class = void>
struct allocator_rebind {
typedef typename detail::alloc_to<A, T>::type type;
struct alloc_rebind {
typedef typename alloc_to<A, T>::type type;
};
template<class A, class T>
struct allocator_rebind<A, T,
typename detail::alloc_void<typename A::template rebind<T>::other>::type> {
struct alloc_rebind<A, T,
typename alloc_void<typename A::template rebind<T>::other>::type> {
typedef typename A::template rebind<T>::other type;
};
} /* detail */
template<class A, class T>
struct allocator_rebind {
typedef typename detail::alloc_rebind<A, T>::type type;
};
namespace detail {
template<class A, class = void>
struct alloc_void_ptr {
typedef typename boost::pointer_traits<typename
boost::allocator_pointer<A>::type>::template
rebind_to<void>::type type;
};
template<class A>
struct alloc_void_ptr<A,
typename alloc_void<typename A::void_pointer>::type> {
typedef typename A::void_pointer type;
};
} /* detail */
template<class A>
struct allocator_void_pointer {
typedef typename detail::alloc_void_ptr<A>::type type;
};
namespace detail {
template<class A, class = void>
struct alloc_const_void_ptr {
typedef typename boost::pointer_traits<typename
boost::allocator_pointer<A>::type>::template
rebind_to<const void>::type type;
};
template<class A>
struct alloc_const_void_ptr<A,
typename alloc_void<typename A::const_void_pointer>::type> {
typedef typename A::const_void_pointer type;
};
} /* detail */
template<class A>
struct allocator_const_void_pointer {
typedef typename detail::alloc_const_void_ptr<A>::type type;
};
namespace detail {
template<class A, class = void>
struct alloc_diff_type {
typedef typename boost::pointer_traits<typename
boost::allocator_pointer<A>::type>::difference_type type;
};
template<class A>
struct alloc_diff_type<A,
typename alloc_void<typename A::difference_type>::type> {
typedef typename A::difference_type type;
};
} /* detail */
template<class A>
struct allocator_difference_type {
typedef typename detail::alloc_diff_type<A>::type type;
};
namespace detail {
#if defined(BOOST_NO_CXX11_ALLOCATOR)
template<class A, class = void>
struct alloc_size_type {
typedef std::size_t type;
};
#else
template<class A, class = void>
struct alloc_size_type {
typedef typename std::make_unsigned<typename
boost::allocator_difference_type<A>::type>::type type;
};
#endif
template<class A>
struct alloc_size_type<A,
typename alloc_void<typename A::size_type>::type> {
typedef typename A::size_type type;
};
} /* detail */
template<class A>
struct allocator_size_type {
typedef typename detail::alloc_size_type<A>::type type;
};
namespace detail {
#if defined(BOOST_NO_CXX11_ALLOCATOR)
template<bool V>
struct alloc_bool {
typedef bool value_type;
typedef alloc_bool type;
static const bool value = V;
operator bool() const BOOST_NOEXCEPT {
return V;
}
bool operator()() const BOOST_NOEXCEPT {
return V;
}
};
template<bool V>
const bool alloc_bool<V>::value;
typedef alloc_bool<false> alloc_false;
#else
typedef std::false_type alloc_false;
#endif
template<class A, class = void>
struct alloc_pocca {
typedef alloc_false type;
};
template<class A>
struct alloc_pocca<A,
typename alloc_void<typename
A::propagate_on_container_copy_assignment>::type> {
typedef typename A::propagate_on_container_copy_assignment type;
};
} /* detail */
template<class A, class = void>
struct allocator_propagate_on_container_copy_assignment {
typedef typename detail::alloc_pocca<A>::type type;
};
namespace detail {
template<class A, class = void>
struct alloc_pocma {
typedef alloc_false type;
};
template<class A>
struct alloc_pocma<A,
typename alloc_void<typename
A::propagate_on_container_move_assignment>::type> {
typedef typename A::propagate_on_container_move_assignment type;
};
} /* detail */
template<class A>
struct allocator_propagate_on_container_move_assignment {
typedef typename detail::alloc_pocma<A>::type type;
};
namespace detail {
template<class A, class = void>
struct alloc_pocs {
typedef alloc_false type;
};
template<class A>
struct alloc_pocs<A,
typename alloc_void<typename A::propagate_on_container_swap>::type> {
typedef typename A::propagate_on_container_swap type;
};
} /* detail */
template<class A>
struct allocator_propagate_on_container_swap {
typedef typename detail::alloc_pocs<A>::type type;
};
namespace detail {
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
template<class A, class = void>
struct alloc_equal {
typedef typename std::is_empty<A>::type type;
};
#elif defined(BOOST_DETAIL_ALLOC_EMPTY)
template<class A, class = void>
struct alloc_equal {
typedef alloc_bool<BOOST_DETAIL_ALLOC_EMPTY(A)> type;
};
#else
template<class A, class = void>
struct alloc_equal {
typedef alloc_false type;
};
#endif
template<class A>
struct alloc_equal<A,
typename alloc_void<typename A::is_always_equal>::type> {
typedef typename A::is_always_equal type;
};
} /* detail */
template<class A>
struct allocator_is_always_equal {
typedef typename detail::alloc_equal<A>::type type;
};
template<class A>
inline typename allocator_pointer<A>::type
allocator_allocate(A& a, typename allocator_size_type<A>::type n)
@@ -301,21 +386,24 @@ allocator_allocate(A& a, typename allocator_size_type<A>::type n,
#else
namespace detail {
struct alloc_none { };
template<class>
struct alloc_no {
char x, y;
};
template<class A>
class alloc_has_allocate {
template<class O>
static auto check(int) -> decltype(std::declval<O&>().allocate(
std::declval<typename allocator_size_type<A>::type>(),
std::declval<typename allocator_const_void_pointer<A>::type>()));
static auto check(int)
-> alloc_no<decltype(std::declval<O&>().allocate(std::declval<typename
boost::allocator_size_type<A>::type>(), std::declval<typename
boost::allocator_const_void_pointer<A>::type>()))>;
template<class>
static alloc_none check(long);
static char check(long);
public:
BOOST_STATIC_CONSTEXPR bool value =
!std::is_same<decltype(check<A>(0)), alloc_none>::value;
BOOST_STATIC_CONSTEXPR bool value = sizeof(check<A>(0)) > 1;
};
} /* detail */
@@ -339,9 +427,55 @@ allocator_allocate(A& a, typename allocator_size_type<A>::type n,
}
#endif
namespace detail {
#if defined(BOOST_NO_CXX11_ALLOCATOR)
template<class A, class = void>
struct alloc_has_construct {
BOOST_STATIC_CONSTEXPR bool value = false;
};
template<class A>
struct alloc_has_construct<A,
typename alloc_void<typename A::_default_construct_destroy>::type> {
BOOST_STATIC_CONSTEXPR bool value = true;
};
#else
template<class A, class T, class... Args>
class alloc_has_construct {
template<class O>
static auto check(int)
-> alloc_no<decltype(std::declval<O&>().construct(std::declval<T*>(),
std::declval<Args&&>()...))>;
template<class>
static char check(long);
public:
BOOST_STATIC_CONSTEXPR bool value = sizeof(check<A>(0)) > 1;
};
#endif
template<bool, class = void>
struct alloc_if { };
template<class T>
struct alloc_if<true, T> {
typedef T type;
};
} /* detail */
#if defined(BOOST_NO_CXX11_ALLOCATOR)
template<class A, class T>
inline void
inline typename detail::alloc_if<detail::alloc_has_construct<A>::value>::type
allocator_construct(A& a, T* p)
{
a.construct(p);
}
template<class A, class T>
inline typename detail::alloc_if<!detail::alloc_has_construct<A>::value>::type
allocator_construct(A&, T* p)
{
::new((void*)p) T();
@@ -379,25 +513,6 @@ allocator_construct(A&, T* p, V& v)
}
#endif
#else
namespace detail {
template<class A, class T, class... Args>
class alloc_has_construct {
template<class O>
static auto check(int)
-> decltype(std::declval<O&>().construct(std::declval<T*>(),
std::declval<Args&&>()...));
template<class>
static alloc_none check(long);
public:
BOOST_STATIC_CONSTEXPR bool value =
!std::is_same<decltype(check<A>(0)), alloc_none>::value;
};
} /* detail */
template<class A, class T, class... Args>
inline typename std::enable_if<detail::alloc_has_construct<A, T,
Args...>::value>::type
@@ -415,132 +530,236 @@ allocator_construct(A&, T* p, Args&&... args)
}
#endif
#if defined(BOOST_NO_CXX11_ALLOCATOR)
template<class A, class T>
inline void
allocator_destroy(A&, T* p)
{
p->~T();
(void)p;
}
#else
namespace detail {
#if defined(BOOST_NO_CXX11_ALLOCATOR)
template<class A, class, class = void>
struct alloc_has_destroy {
BOOST_STATIC_CONSTEXPR bool value = false;
};
template<class A, class T>
struct alloc_has_destroy<A, T,
typename alloc_void<typename A::_default_construct_destroy>::type> {
BOOST_STATIC_CONSTEXPR bool value = true;
};
#else
template<class A, class T>
class alloc_has_destroy {
template<class O>
static auto check(int)
-> decltype(std::declval<O&>().destroy(std::declval<T*>()));
-> alloc_no<decltype(std::declval<O&>().destroy(std::declval<T*>()))>;
template<class>
static alloc_none check(long);
static char check(long);
public:
BOOST_STATIC_CONSTEXPR bool value =
!std::is_same<decltype(check<A>(0)), alloc_none>::value;
BOOST_STATIC_CONSTEXPR bool value = sizeof(check<A>(0)) > 1;
};
#endif
} /* detail */
template<class A, class T>
inline typename std::enable_if<detail::alloc_has_destroy<A, T>::value>::type
inline typename detail::alloc_if<detail::alloc_has_destroy<A, T>::value>::type
allocator_destroy(A& a, T* p)
{
a.destroy(p);
}
template<class A, class T>
inline typename std::enable_if<!detail::alloc_has_destroy<A, T>::value>::type
inline typename detail::alloc_if<!detail::alloc_has_destroy<A, T>::value>::type
allocator_destroy(A&, T* p)
{
p->~T();
(void)p;
}
#endif
namespace detail {
#if defined(BOOST_NO_CXX11_ALLOCATOR)
template<class A>
inline typename allocator_size_type<A>::type
allocator_max_size(const A& a)
{
return a.max_size();
}
#else
namespace detail {
template<class T, T>
struct alloc_no {
char x, y;
};
template<class A>
class alloc_has_max_size {
template<class O>
static auto check(int) -> decltype(std::declval<O&>().max_size());
static alloc_no<typename boost::allocator_size_type<O>::type(O::*)(),
&O::max_size> check(int);
template<class O>
static alloc_no<typename boost::allocator_size_type<O>::type(O::*)() const,
&O::max_size> check(int);
template<class O>
static alloc_no<typename boost::allocator_size_type<O>::type(*)(),
&O::max_size> check(int);
template<class>
static alloc_none check(long);
static char check(long);
public:
BOOST_STATIC_CONSTEXPR bool value =
!std::is_same<decltype(check<A>(0)), alloc_none>::value;
BOOST_STATIC_CONSTEXPR bool value = sizeof(check<A>(0)) > 1;
};
#else
template<class A>
class alloc_has_max_size {
template<class O>
static auto check(int)
-> alloc_no<decltype(std::declval<const O&>().max_size())>;
template<class>
static char check(long);
public:
BOOST_STATIC_CONSTEXPR bool value = sizeof(check<A>(0)) > 1;
};
#endif
} /* detail */
template<class A>
inline typename std::enable_if<detail::alloc_has_max_size<A>::value,
inline typename detail::alloc_if<detail::alloc_has_max_size<A>::value,
typename allocator_size_type<A>::type>::type
allocator_max_size(const A& a)
allocator_max_size(const A& a) BOOST_NOEXCEPT
{
return a.max_size();
}
template<class A>
inline typename std::enable_if<!detail::alloc_has_max_size<A>::value,
inline typename detail::alloc_if<!detail::alloc_has_max_size<A>::value,
typename allocator_size_type<A>::type>::type
allocator_max_size(const A&)
allocator_max_size(const A&) BOOST_NOEXCEPT
{
return (std::numeric_limits<typename
allocator_size_type<A>::type>::max)() / sizeof(typename A::value_type);
allocator_size_type<A>::type>::max)() /
sizeof(typename allocator_value_type<A>::type);
}
#endif
namespace detail {
#if defined(BOOST_NO_CXX11_ALLOCATOR)
template<class A>
inline A
allocator_select_on_container_copy_construction(const A& a)
{
return a;
}
#else
namespace detail {
class alloc_has_soccc {
template<class O>
static alloc_no<O(O::*)(), &O::select_on_container_copy_construction>
check(int);
template<class O>
static alloc_no<O(O::*)() const, &O::select_on_container_copy_construction>
check(int);
template<class O>
static alloc_no<O(*)(), &O::select_on_container_copy_construction>
check(int);
template<class>
static char check(long);
public:
BOOST_STATIC_CONSTEXPR bool value = sizeof(check<A>(0)) > 1;
};
#else
template<class A>
class alloc_has_soccc {
template<class O>
static auto check(int)
-> decltype(std::declval<O&>().select_on_container_copy_construction());
static auto check(int) -> alloc_no<decltype(std::declval<const
O&>().select_on_container_copy_construction())>;
template<class>
static alloc_none check(long);
static char check(long);
public:
BOOST_STATIC_CONSTEXPR bool value =
!std::is_same<decltype(check<A>(0)), alloc_none>::value;
BOOST_STATIC_CONSTEXPR bool value = sizeof(check<A>(0)) > 1;
};
#endif
} /* detail */
template<class A>
inline typename std::enable_if<detail::alloc_has_soccc<A>::value, A>::type
inline typename detail::alloc_if<detail::alloc_has_soccc<A>::value, A>::type
allocator_select_on_container_copy_construction(const A& a)
{
return a.select_on_container_copy_construction();
}
template<class A>
inline typename std::enable_if<!detail::alloc_has_soccc<A>::value, A>::type
inline typename detail::alloc_if<!detail::alloc_has_soccc<A>::value, A>::type
allocator_select_on_container_copy_construction(const A& a)
{
return a;
}
#endif
template<class A, class T>
inline void
allocator_destroy_n(A& a, T* p, std::size_t n)
{
while (n > 0) {
boost::allocator_destroy(a, p + --n);
}
}
namespace detail {
template<class A, class T>
class alloc_destroyer {
public:
alloc_destroyer(A& a, T* p) BOOST_NOEXCEPT
: a_(a), p_(p), n_(0) { }
~alloc_destroyer() {
boost::allocator_destroy_n(a_, p_, n_);
}
std::size_t& size() BOOST_NOEXCEPT {
return n_;
}
private:
alloc_destroyer(const alloc_destroyer&);
alloc_destroyer& operator=(const alloc_destroyer&);
A& a_;
T* p_;
std::size_t n_;
};
} /* detail */
template<class A, class T>
inline void
allocator_construct_n(A& a, T* p, std::size_t n)
{
detail::alloc_destroyer<A, T> d(a, p);
for (std::size_t& i = d.size(); i < n; ++i) {
boost::allocator_construct(a, p + i);
}
d.size() = 0;
}
template<class A, class T>
inline void
allocator_construct_n(A& a, T* p, std::size_t n, const T* l, std::size_t m)
{
detail::alloc_destroyer<A, T> d(a, p);
for (std::size_t& i = d.size(); i < n; ++i) {
boost::allocator_construct(a, p + i, l[i % m]);
}
d.size() = 0;
}
template<class A, class T, class I>
inline void
allocator_construct_n(A& a, T* p, std::size_t n, I b)
{
detail::alloc_destroyer<A, T> d(a, p);
for (std::size_t& i = d.size(); i < n; void(++i), void(++b)) {
boost::allocator_construct(a, p + i, *b);
}
d.size() = 0;
}
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
template<class A>

View File

@@ -0,0 +1,112 @@
/*
Copyright 2021 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CORE_ALLOCATOR_TRAITS_HPP
#define BOOST_CORE_ALLOCATOR_TRAITS_HPP
#include <boost/core/allocator_access.hpp>
namespace boost {
template<class A>
struct allocator_traits {
typedef A allocator_type;
typedef typename allocator_value_type<A>::type value_type;
typedef typename allocator_pointer<A>::type pointer;
typedef typename allocator_const_pointer<A>::type const_pointer;
typedef typename allocator_void_pointer<A>::type void_pointer;
typedef typename allocator_const_void_pointer<A>::type const_void_pointer;
typedef typename allocator_difference_type<A>::type difference_type;
typedef typename allocator_size_type<A>::type size_type;
typedef typename allocator_propagate_on_container_copy_assignment<A>::type
propagate_on_container_copy_assignment;
typedef typename allocator_propagate_on_container_move_assignment<A>::type
propagate_on_container_move_assignment;
typedef typename allocator_propagate_on_container_swap<A>::type
propagate_on_container_swap;
typedef typename allocator_is_always_equal<A>::type is_always_equal;
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
template<class T>
using rebind_traits = allocator_traits<typename
allocator_rebind<A, T>::type>;
#else
template<class T>
struct rebind_traits
: allocator_traits<typename allocator_rebind<A, T>::type> { };
#endif
static pointer allocate(A& a, size_type n) {
return boost::allocator_allocate(a, n);
}
static pointer allocate(A& a, size_type n, const_void_pointer h) {
return boost::allocator_allocate(a, n, h);
}
static void deallocate(A& a, pointer p, size_type n) {
return boost::allocator_deallocate(a, p, n);
}
template<class T>
static void construct(A& a, T* p) {
boost::allocator_construct(a, p);
}
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<class T, class V, class... Args>
static void construct(A& a, T* p, V&& v, Args&&... args) {
boost::allocator_construct(a, p, std::forward<V>(v),
std::forward<Args>(args)...);
}
#else
template<class T, class V>
static void construct(A& a, T* p, V&& v) {
boost::allocator_construct(a, p, std::forward<V>(v));
}
#endif
#else
template<class T, class V>
static void construct(A& a, T* p, const V& v) {
boost::allocator_construct(a, p, v);
}
template<class T, class V>
static void construct(A& a, T* p, V& v) {
boost::allocator_construct(a, p, v);
}
#endif
template<class T>
static void destroy(A& a, T* p) {
boost::allocator_destroy(a, p);
}
static size_type max_size(const A& a) BOOST_NOEXCEPT {
return boost::allocator_max_size(a);
}
static A select_on_container_copy_construction(const A& a) {
return boost::allocator_select_on_container_copy_construction(a);
}
};
} /* boost */
#endif

View File

@@ -82,9 +82,9 @@ BOOST_CONSTEXPR inline int countl_impl( unsigned long x ) BOOST_NOEXCEPT
return x? __builtin_clzl( x ): std::numeric_limits<unsigned long>::digits;
}
BOOST_CONSTEXPR inline int countl_impl( unsigned long long x ) BOOST_NOEXCEPT
BOOST_CONSTEXPR inline int countl_impl( boost::ulong_long_type x ) BOOST_NOEXCEPT
{
return x? __builtin_clzll( x ): std::numeric_limits<unsigned long long>::digits;
return x? __builtin_clzll( x ): std::numeric_limits<boost::ulong_long_type>::digits;
}
} // namespace detail
@@ -92,6 +92,8 @@ BOOST_CONSTEXPR inline int countl_impl( unsigned long long x ) BOOST_NOEXCEPT
template<class T>
BOOST_CONSTEXPR int countl_zero( T x ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
return boost::core::detail::countl_impl( x );
}
@@ -169,17 +171,19 @@ inline int countl_impl( boost::uint16_t x ) BOOST_NOEXCEPT
template<class T>
int countl_zero( T x ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
BOOST_STATIC_ASSERT( sizeof(T) == sizeof(boost::uint8_t) || sizeof(T) == sizeof(boost::uint16_t) || sizeof(T) == sizeof(boost::uint32_t) || sizeof(T) == sizeof(boost::uint64_t) );
if( sizeof(T) == sizeof(boost::uint8_t) )
BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint8_t) )
{
return boost::core::detail::countl_impl( static_cast<boost::uint8_t>( x ) );
}
else if( sizeof(T) == sizeof(boost::uint16_t) )
else BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint16_t) )
{
return boost::core::detail::countl_impl( static_cast<boost::uint16_t>( x ) );
}
else if( sizeof(T) == sizeof(boost::uint32_t) )
else BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint32_t) )
{
return boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x ) );
}
@@ -194,6 +198,8 @@ int countl_zero( T x ) BOOST_NOEXCEPT
template<class T>
BOOST_CONSTEXPR int countl_one( T x ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
return boost::core::countl_zero( static_cast<T>( ~x ) );
}
@@ -224,9 +230,9 @@ BOOST_CONSTEXPR inline int countr_impl( unsigned long x ) BOOST_NOEXCEPT
return x? __builtin_ctzl( x ): std::numeric_limits<unsigned long>::digits;
}
BOOST_CONSTEXPR inline int countr_impl( unsigned long long x ) BOOST_NOEXCEPT
BOOST_CONSTEXPR inline int countr_impl( boost::ulong_long_type x ) BOOST_NOEXCEPT
{
return x? __builtin_ctzll( x ): std::numeric_limits<unsigned long long>::digits;
return x? __builtin_ctzll( x ): std::numeric_limits<boost::ulong_long_type>::digits;
}
} // namespace detail
@@ -234,6 +240,8 @@ BOOST_CONSTEXPR inline int countr_impl( unsigned long long x ) BOOST_NOEXCEPT
template<class T>
BOOST_CONSTEXPR int countr_zero( T x ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
return boost::core::detail::countr_impl( x );
}
@@ -304,17 +312,19 @@ inline int countr_impl( boost::uint16_t x ) BOOST_NOEXCEPT
template<class T>
int countr_zero( T x ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
BOOST_STATIC_ASSERT( sizeof(T) == sizeof(boost::uint8_t) || sizeof(T) == sizeof(boost::uint16_t) || sizeof(T) == sizeof(boost::uint32_t) || sizeof(T) == sizeof(boost::uint64_t) );
if( sizeof(T) == sizeof(boost::uint8_t) )
BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint8_t) )
{
return boost::core::detail::countr_impl( static_cast<boost::uint8_t>( x ) );
}
else if( sizeof(T) == sizeof(boost::uint16_t) )
else BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint16_t) )
{
return boost::core::detail::countr_impl( static_cast<boost::uint16_t>( x ) );
}
else if( sizeof(T) == sizeof(boost::uint32_t) )
else BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint32_t) )
{
return boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x ) );
}
@@ -329,6 +339,8 @@ int countr_zero( T x ) BOOST_NOEXCEPT
template<class T>
BOOST_CONSTEXPR int countr_one( T x ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
return boost::core::countr_zero( static_cast<T>( ~x ) );
}
@@ -365,7 +377,7 @@ BOOST_CORE_POPCOUNT_CONSTEXPR inline int popcount_impl( unsigned long x ) BOOST_
return __builtin_popcountl( x );
}
BOOST_CORE_POPCOUNT_CONSTEXPR inline int popcount_impl( unsigned long long x ) BOOST_NOEXCEPT
BOOST_CORE_POPCOUNT_CONSTEXPR inline int popcount_impl( boost::ulong_long_type x ) BOOST_NOEXCEPT
{
return __builtin_popcountll( x );
}
@@ -377,6 +389,8 @@ BOOST_CORE_POPCOUNT_CONSTEXPR inline int popcount_impl( unsigned long long x ) B
template<class T>
BOOST_CONSTEXPR int popcount( T x ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
return boost::core::detail::popcount_impl( x );
}
@@ -408,9 +422,11 @@ BOOST_CXX14_CONSTEXPR inline int popcount_impl( boost::uint64_t x ) BOOST_NOEXCE
template<class T>
BOOST_CXX14_CONSTEXPR int popcount( T x ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
BOOST_STATIC_ASSERT( sizeof(T) <= sizeof(boost::uint64_t) );
if( sizeof(T) <= sizeof(boost::uint32_t) )
BOOST_IF_CONSTEXPR ( sizeof(T) <= sizeof(boost::uint32_t) )
{
return boost::core::detail::popcount_impl( static_cast<boost::uint32_t>( x ) );
}
@@ -427,6 +443,8 @@ BOOST_CXX14_CONSTEXPR int popcount( T x ) BOOST_NOEXCEPT
template<class T>
BOOST_CXX14_CONSTEXPR T rotl( T x, int s ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
unsigned const mask = std::numeric_limits<T>::digits - 1;
return x << (s & mask) | x >> ((-s) & mask);
}
@@ -434,6 +452,8 @@ BOOST_CXX14_CONSTEXPR T rotl( T x, int s ) BOOST_NOEXCEPT
template<class T>
BOOST_CXX14_CONSTEXPR T rotr( T x, int s ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
unsigned const mask = std::numeric_limits<T>::digits - 1;
return x >> (s & mask) | x << ((-s) & mask);
}
@@ -443,18 +463,27 @@ BOOST_CXX14_CONSTEXPR T rotr( T x, int s ) BOOST_NOEXCEPT
template<class T>
BOOST_CONSTEXPR bool has_single_bit( T x ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
return x != 0 && ( x & ( x - 1 ) ) == 0;
}
// bit_width returns `int` now, https://cplusplus.github.io/LWG/issue3656
// has been applied to C++20 as a DR
template<class T>
BOOST_CONSTEXPR T bit_width( T x ) BOOST_NOEXCEPT
BOOST_CONSTEXPR int bit_width( T x ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
return std::numeric_limits<T>::digits - boost::core::countl_zero( x );
}
template<class T>
BOOST_CONSTEXPR T bit_floor( T x ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
return x == 0? 0: T(1) << ( boost::core::bit_width( x ) - 1 );
}
@@ -507,9 +536,11 @@ BOOST_CXX14_CONSTEXPR inline boost::uint64_t bit_ceil_impl( boost::uint64_t x )
template<class T>
BOOST_CXX14_CONSTEXPR T bit_ceil( T x ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
BOOST_STATIC_ASSERT( sizeof(T) <= sizeof(boost::uint64_t) );
if( sizeof(T) <= sizeof(boost::uint32_t) )
BOOST_IF_CONSTEXPR ( sizeof(T) <= sizeof(boost::uint32_t) )
{
return static_cast<T>( boost::core::detail::bit_ceil_impl( static_cast<boost::uint32_t>( x ) ) );
}

View File

@@ -19,21 +19,25 @@ BOOST_NORETURN void throw_exception(const std::exception&);
namespace default_ {
struct true_type {
template<bool V>
struct bool_constant {
typedef bool value_type;
typedef true_type type;
typedef bool_constant type;
BOOST_STATIC_CONSTANT(bool, value = true);
static const bool value = V;
BOOST_CONSTEXPR operator bool() const BOOST_NOEXCEPT {
return true;
operator bool() const BOOST_NOEXCEPT {
return V;
}
BOOST_CONSTEXPR bool operator()() const BOOST_NOEXCEPT {
return true;
bool operator()() const BOOST_NOEXCEPT {
return V;
}
};
template<bool V>
const bool bool_constant<V>::value;
template<class T>
struct add_reference {
typedef T& type;
@@ -58,8 +62,8 @@ struct default_allocator {
typedef typename add_reference<const T>::type const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef true_type propagate_on_container_move_assignment;
typedef true_type is_always_equal;
typedef bool_constant<true> propagate_on_container_move_assignment;
typedef bool_constant<true> is_always_equal;
template<class U>
struct rebind {
@@ -108,6 +112,12 @@ struct default_allocator {
}
#endif
#if defined(BOOST_NO_CXX11_ALLOCATOR)
T* allocate(std::size_t n, const void*) {
return allocate(n);
}
#endif
#if (defined(BOOST_LIBSTDCXX_VERSION) && BOOST_LIBSTDCXX_VERSION < 60000) || \
defined(BOOST_NO_CXX11_ALLOCATOR)
template<class U, class V>

View File

@@ -34,14 +34,14 @@ public:
boost::uint64_t operator()()
{
x_ += 0x9e3779b97f4a7c15;
x_ += ( boost::uint64_t(0x9e3779b9u) << 32 ) + 0x7f4a7c15u;
boost::uint64_t z = x_;
z ^= z >> 30;
z *= 0xbf58476d1ce4e5b9;
z *= ( boost::uint64_t(0xbf58476du) << 32 ) + 0x1ce4e5b9u;
z ^= z >> 27;
z *= 0x94d049bb133111eb;
z *= ( boost::uint64_t(0x94d049bbu) << 32 ) + 0x133111ebu;
z ^= z >> 31;
return z;

View File

@@ -31,9 +31,19 @@
#if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
# include <string_view>
#endif
#if !defined(BOOST_NO_CXX20_HDR_CONCEPTS) // std::common_reference_with
# include <type_traits>
#endif
namespace boost
{
// forward declaration of boost::basic_string_view from Utility
template<class Ch, class Tr> class basic_string_view;
// forward declaration of boost::hash_range from ContainerHash
template<class It> std::size_t hash_range( It, It );
namespace core
{
namespace detail
@@ -370,10 +380,10 @@ public:
{
}
template<class End> BOOST_CXX14_CONSTEXPR basic_string_view( Ch const* begin, End end,
typename boost::enable_if<is_same<End, Ch const*> >::type* = 0 ) BOOST_NOEXCEPT: p_( begin ), n_( end - begin )
template<class End> BOOST_CXX14_CONSTEXPR basic_string_view( Ch const* first, End last,
typename boost::enable_if<is_same<End, Ch const*> >::type* = 0 ) BOOST_NOEXCEPT: p_( first ), n_( last - first )
{
BOOST_ASSERT( end - begin >= 0 );
BOOST_ASSERT( last - first >= 0 );
}
template<class A> basic_string_view( std::basic_string<Ch, std::char_traits<Ch>, A> const& str ) BOOST_NOEXCEPT: p_( str.data() ), n_( str.size() )
@@ -386,6 +396,27 @@ public:
{
}
#endif
template<class Ch2> basic_string_view( boost::basic_string_view<Ch2, std::char_traits<Ch2> > const& str,
typename boost::enable_if<is_same<Ch, Ch2> >::type* = 0 ) BOOST_NOEXCEPT: p_( str.data() ), n_( str.size() )
{
}
#if !defined(BOOST_NO_CXX11_NULLPTR)
# if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
basic_string_view( std::nullptr_t ) = delete;
# else
private:
basic_string_view( std::nullptr_t );
public:
# endif
#endif
// BOOST_CONSTEXPR basic_string_view& operator=( basic_string_view const& ) BOOST_NOEXCEPT & = default;
@@ -407,6 +438,12 @@ public:
#endif
template<class Ch2> operator boost::basic_string_view<Ch2,
typename boost::enable_if<boost::core::is_same<Ch2, Ch>, std::char_traits<Ch> >::type> () const BOOST_NOEXCEPT
{
return boost::basic_string_view< Ch, std::char_traits<Ch> >( data(), size() );
}
// iterator support
BOOST_CONSTEXPR const_iterator begin() const BOOST_NOEXCEPT
@@ -538,7 +575,7 @@ public:
boost::throw_exception( std::out_of_range( "basic_string_view::copy" ), BOOST_CURRENT_LOCATION );
}
std::size_t rlen = std::min( n, size() - pos );
std::size_t rlen = (std::min)( n, size() - pos );
traits_type::copy( s, data() + pos, rlen );
@@ -552,7 +589,7 @@ public:
boost::throw_exception( std::out_of_range( "basic_string_view::substr" ), BOOST_CURRENT_LOCATION );
}
std::size_t rlen = std::min( n, size() - pos );
std::size_t rlen = (std::min)( n, size() - pos );
return basic_string_view( data() + pos, rlen );
}
@@ -561,7 +598,7 @@ public:
BOOST_CXX14_CONSTEXPR int compare( basic_string_view str ) const BOOST_NOEXCEPT
{
std::size_t rlen = std::min( size(), str.size() );
std::size_t rlen = (std::min)( size(), str.size() );
int cmp = traits_type::compare( data(), str.data(), rlen );
@@ -1144,6 +1181,11 @@ public:
}
#endif
inline friend std::size_t hash_value( basic_string_view const& sv )
{
return boost::hash_range( sv.begin(), sv.end() );
}
};
// stream inserter
@@ -1202,4 +1244,29 @@ typedef basic_string_view<char8_t> u8string_view;
} // namespace core
} // namespace boost
// std::common_reference support
// needed for iterators that have reference=string_view and value_type=std::string
#if !defined(BOOST_NO_CXX20_HDR_CONCEPTS)
template<class Ch, class A, template<class> class Q1, template<class> class Q2>
struct std::basic_common_reference<
boost::core::basic_string_view<Ch>,
std::basic_string<Ch, std::char_traits<Ch>, A>,
Q1, Q2>
{
using type = boost::core::basic_string_view<Ch>;
};
template<class Ch, class A, template<class> class Q1, template<class> class Q2>
struct std::basic_common_reference<
std::basic_string<Ch, std::char_traits<Ch>, A>,
boost::core::basic_string_view<Ch>,
Q1, Q2>
{
using type = boost::core::basic_string_view<Ch>;
};
#endif
#endif // #ifndef BOOST_CORE_STRING_VIEW_HPP_INCLUDED

View File

@@ -25,6 +25,11 @@ Distributed under the Boost Software License, Version 1.0.
#endif
#endif
#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable:4510)
#endif
namespace boost {
template<class T>
@@ -51,37 +56,37 @@ public:
#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
empty_value() = default;
#else
empty_value() { }
BOOST_CONSTEXPR empty_value() { }
#endif
empty_value(boost::empty_init_t)
BOOST_CONSTEXPR empty_value(boost::empty_init_t)
: value_() { }
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<class U, class... Args>
empty_value(boost::empty_init_t, U&& value, Args&&... args)
BOOST_CONSTEXPR empty_value(boost::empty_init_t, U&& value, Args&&... args)
: value_(std::forward<U>(value), std::forward<Args>(args)...) { }
#else
template<class U>
empty_value(boost::empty_init_t, U&& value)
BOOST_CONSTEXPR empty_value(boost::empty_init_t, U&& value)
: value_(std::forward<U>(value)) { }
#endif
#else
template<class U>
empty_value(boost::empty_init_t, const U& value)
BOOST_CONSTEXPR empty_value(boost::empty_init_t, const U& value)
: value_(value) { }
template<class U>
empty_value(boost::empty_init_t, U& value)
BOOST_CONSTEXPR empty_value(boost::empty_init_t, U& value)
: value_(value) { }
#endif
const T& get() const BOOST_NOEXCEPT {
BOOST_CONSTEXPR const T& get() const BOOST_NOEXCEPT {
return value_;
}
T& get() BOOST_NOEXCEPT {
BOOST_CXX14_CONSTEXPR T& get() BOOST_NOEXCEPT {
return value_;
}
@@ -99,37 +104,37 @@ public:
#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
empty_value() = default;
#else
empty_value() { }
BOOST_CONSTEXPR empty_value() { }
#endif
empty_value(boost::empty_init_t)
BOOST_CONSTEXPR empty_value(boost::empty_init_t)
: T() { }
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<class U, class... Args>
empty_value(boost::empty_init_t, U&& value, Args&&... args)
BOOST_CONSTEXPR empty_value(boost::empty_init_t, U&& value, Args&&... args)
: T(std::forward<U>(value), std::forward<Args>(args)...) { }
#else
template<class U>
empty_value(boost::empty_init_t, U&& value)
BOOST_CONSTEXPR empty_value(boost::empty_init_t, U&& value)
: T(std::forward<U>(value)) { }
#endif
#else
template<class U>
empty_value(boost::empty_init_t, const U& value)
BOOST_CONSTEXPR empty_value(boost::empty_init_t, const U& value)
: T(value) { }
template<class U>
empty_value(boost::empty_init_t, U& value)
BOOST_CONSTEXPR empty_value(boost::empty_init_t, U& value)
: T(value) { }
#endif
const T& get() const BOOST_NOEXCEPT {
BOOST_CONSTEXPR const T& get() const BOOST_NOEXCEPT {
return *this;
}
T& get() BOOST_NOEXCEPT {
BOOST_CXX14_CONSTEXPR T& get() BOOST_NOEXCEPT {
return *this;
}
};
@@ -143,4 +148,8 @@ BOOST_INLINE_CONSTEXPR empty_init_t empty_init = empty_init_t();
} /* boost */
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
#endif

View File

@@ -0,0 +1,46 @@
/*
* Copyright Andrey Semashev 2022.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*/
/*!
* \file fclose_deleter.hpp
* \author Andrey Semashev
* \date 21.09.2022
*
* This header contains an \c fclose_deleter implementation. This is a deleter
* function object that invokes <tt>std::fclose</tt> on the passed pointer to
* a <tt>std::FILE</tt> structure.
*/
#ifndef BOOST_CORE_FCLOSE_DELETER_HPP
#define BOOST_CORE_FCLOSE_DELETER_HPP
#include <cstdio>
#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
namespace boost {
//! A function object that closes a file
struct fclose_deleter
{
//! Function object result type
typedef void result_type;
/*!
* Closes the file handle
*/
void operator() (std::FILE* p) const BOOST_NOEXCEPT
{
if (BOOST_LIKELY(!!p))
std::fclose(p);
}
};
} // namespace boost
#endif // BOOST_CORE_FCLOSE_DELETER_HPP

View File

@@ -202,6 +202,13 @@ inline unsigned long test_output_impl( char32_t const& v ) { return v; }
#pragma warning(disable: 4996)
#endif
// Use snprintf if available as some compilers (clang 14.0) issue deprecation warnings for sprintf
#if ( defined(_MSC_VER) && _MSC_VER < 1900 ) || ( defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) )
# define BOOST_CORE_DETAIL_SNPRINTF(buffer, format, arg) std::sprintf(buffer, format, arg)
#else
# define BOOST_CORE_DETAIL_SNPRINTF(buffer, format, arg) std::snprintf(buffer, sizeof(buffer)/sizeof(buffer[0]), format, arg)
#endif
inline std::string test_output_impl( char const& v )
{
if( std::isprint( static_cast<unsigned char>( v ) ) )
@@ -211,12 +218,14 @@ inline std::string test_output_impl( char const& v )
else
{
char buffer[ 8 ];
std::sprintf( buffer, "\\x%02X", static_cast<unsigned char>( v ) );
BOOST_CORE_DETAIL_SNPRINTF( buffer, "\\x%02X", static_cast<unsigned char>( v ) );
return buffer;
}
}
#undef BOOST_CORE_DETAIL_SNPRINTF
#if defined(_MSC_VER)
#pragma warning(pop)
#endif

View File

@@ -15,6 +15,8 @@ namespace boost {
template<class A>
struct noinit_adaptor
: A {
typedef void _default_construct_destroy;
template<class U>
struct rebind {
typedef noinit_adaptor<typename allocator_rebind<A, U>::type> other;

View File

@@ -27,7 +27,7 @@ namespace noncopyable_ // protection from unintended ADL
// whether a type derives from noncopyable without needing the definition
// of noncopyable itself.
//
// The definition of base_token is macro-guarded so that Type Trais can
// The definition of base_token is macro-guarded so that Type Traits can
// define it locally without including this header, to avoid a dependency
// on Core.

View File

@@ -1,5 +1,5 @@
/*
Copyright 2017-2018 Glen Joseph Fernandes
Copyright 2017-2021 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
@@ -9,43 +9,23 @@ Distributed under the Boost Software License, Version 1.0.
#define BOOST_CORE_POINTER_TRAITS_HPP
#include <boost/config.hpp>
#if !defined(BOOST_NO_CXX11_POINTER_TRAITS)
#include <memory>
#else
#include <boost/core/addressof.hpp>
#include <cstddef>
#endif
namespace boost {
#if !defined(BOOST_NO_CXX11_POINTER_TRAITS)
template<class T>
struct pointer_traits
: std::pointer_traits<T> {
template<class U>
struct rebind_to {
typedef typename std::pointer_traits<T>::template rebind<U> type;
};
};
template<class T>
struct pointer_traits<T*>
: std::pointer_traits<T*> {
template<class U>
struct rebind_to {
typedef U* type;
};
};
#else
namespace detail {
struct ptr_none { };
template<class>
struct ptr_void {
struct ptr_valid {
typedef void type;
};
template<class T>
struct ptr_first;
template<class>
struct ptr_first {
typedef ptr_none type;
};
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<template<class, class...> class T, class U, class... Args>
@@ -75,7 +55,7 @@ struct ptr_element {
};
template<class T>
struct ptr_element<T, typename ptr_void<typename T::element_type>::type> {
struct ptr_element<T, typename ptr_valid<typename T::element_type>::type> {
typedef typename T::element_type type;
};
@@ -86,12 +66,12 @@ struct ptr_difference {
template<class T>
struct ptr_difference<T,
typename ptr_void<typename T::difference_type>::type> {
typename ptr_valid<typename T::difference_type>::type> {
typedef typename T::difference_type type;
};
template<class T, class V>
struct ptr_transform;
template<class, class>
struct ptr_transform { };
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<template<class, class...> class T, class U, class... Args, class V>
@@ -117,68 +97,139 @@ struct ptr_transform<T<U1, U2, U3>, V> {
#endif
template<class T, class U, class = void>
struct ptr_rebind {
typedef typename ptr_transform<T, U>::type type;
};
struct ptr_rebind
: ptr_transform<T, U> { };
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
template<class T, class U>
struct ptr_rebind<T, U,
typename ptr_void<typename T::template rebind<U> >::type> {
typename ptr_valid<typename T::template rebind<U> >::type> {
typedef typename T::template rebind<U> type;
};
#else
template<class T, class U>
struct ptr_rebind<T, U,
typename ptr_valid<typename T::template rebind<U>::other>::type> {
typedef typename T::template rebind<U>::other type;
};
#endif
#if !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
template<class T, class E>
class ptr_to_expr {
template<class>
struct result {
char x, y;
};
static E& source();
template<class O>
static auto check(int) -> result<decltype(O::pointer_to(source()))>;
template<class>
static char check(long);
public:
BOOST_STATIC_CONSTEXPR bool value = sizeof(check<T>(0)) > 1;
};
template<class T, class E>
struct ptr_to_expr<T*, E> {
BOOST_STATIC_CONSTEXPR bool value = true;
};
template<class T, class E>
struct ptr_has_to {
BOOST_STATIC_CONSTEXPR bool value = ptr_to_expr<T, E>::value;
};
#else
template<class, class>
struct ptr_has_to {
BOOST_STATIC_CONSTEXPR bool value = true;
};
#endif
template<class T>
struct ptr_value {
typedef T type;
struct ptr_has_to<T, void> {
BOOST_STATIC_CONSTEXPR bool value = false;
};
template<>
struct ptr_value<void> {
typedef struct { } type;
template<class T>
struct ptr_has_to<T, const void> {
BOOST_STATIC_CONSTEXPR bool value = false;
};
template<class T>
struct ptr_has_to<T, volatile void> {
BOOST_STATIC_CONSTEXPR bool value = false;
};
template<class T>
struct ptr_has_to<T, const volatile void> {
BOOST_STATIC_CONSTEXPR bool value = false;
};
template<class T, class E, bool = ptr_has_to<T, E>::value>
struct ptr_to { };
template<class T, class E>
struct ptr_to<T, E, true> {
static T pointer_to(E& v) {
return T::pointer_to(v);
}
};
template<class T>
struct ptr_to<T*, T, true> {
static T* pointer_to(T& v) BOOST_NOEXCEPT {
return boost::addressof(v);
}
};
template<class T, class E>
struct ptr_traits
: ptr_to<T, E> {
typedef T pointer;
typedef E element_type;
typedef typename ptr_difference<T>::type difference_type;
template<class U>
struct rebind_to
: ptr_rebind<T, U> { };
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
template<class U>
using rebind = typename rebind_to<U>::type;
#endif
};
template<class T>
struct ptr_traits<T, ptr_none> { };
} /* detail */
template<class T>
struct pointer_traits {
typedef T pointer;
typedef typename detail::ptr_element<T>::type element_type;
typedef typename detail::ptr_difference<T>::type difference_type;
template<class U>
struct rebind_to {
typedef typename detail::ptr_rebind<T, U>::type type;
};
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
template<class U>
using rebind = typename detail::ptr_rebind<T, U>::type;
#endif
static pointer
pointer_to(typename detail::ptr_value<element_type>::type& v) {
return pointer::pointer_to(v);
}
};
struct pointer_traits
: detail::ptr_traits<T, typename detail::ptr_element<T>::type> { };
template<class T>
struct pointer_traits<T*> {
struct pointer_traits<T*>
: detail::ptr_to<T*, T> {
typedef T* pointer;
typedef T element_type;
typedef std::ptrdiff_t difference_type;
template<class U>
struct rebind_to {
typedef U* type;
};
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
template<class U>
using rebind = U*;
using rebind = typename rebind_to<U>::type;
#endif
static T*
pointer_to(typename detail::ptr_value<T>::type& v) BOOST_NOEXCEPT {
return boost::addressof(v);
}
};
#endif
template<class T>
BOOST_CONSTEXPR inline T*

View File

@@ -33,7 +33,7 @@ extern "C" _Noreturn void quick_exit(int);
namespace boost
{
BOOST_NORETURN void quick_exit( int code ) BOOST_NOEXCEPT
BOOST_NORETURN inline void quick_exit( int code ) BOOST_NOEXCEPT
{
#if defined(_MSC_VER) && _MSC_VER < 1900

View File

@@ -347,14 +347,6 @@ public:
return const_reverse_iterator(s_.p);
}
friend constexpr iterator begin(span s) noexcept {
return s.begin();
}
friend constexpr iterator end(span s) noexcept {
return s.end();
}
private:
detail::span_store<T, E> s_;
};

View File

@@ -185,14 +185,23 @@ template<class T> std::string array_template_name()
# pragma warning( disable: 4996 )
#endif
// Use snprintf if available as some compilers (clang 14.0) issue deprecation warnings for sprintf
#if ( defined(_MSC_VER) && _MSC_VER < 1900 ) || ( defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) )
# define BOOST_CORE_DETAIL_SNPRINTF(buffer, format, arg) std::sprintf(buffer, format, arg)
#else
# define BOOST_CORE_DETAIL_SNPRINTF(buffer, format, arg) std::snprintf(buffer, sizeof(buffer)/sizeof(buffer[0]), format, arg)
#endif
inline std::string tn_to_string( std::size_t n )
{
char buffer[ 32 ];
std::sprintf( buffer, "%lu", static_cast< unsigned long >( n ) );
BOOST_CORE_DETAIL_SNPRINTF( buffer, "%lu", static_cast< unsigned long >( n ) );
return buffer;
}
#undef BOOST_CORE_DETAIL_SNPRINTF
#if defined(BOOST_MSVC)
# pragma warning( pop )
#endif
@@ -305,6 +314,26 @@ template<> struct tn_holder<boost::ulong_long_type>
}
};
#if defined(BOOST_HAS_INT128)
template<> struct tn_holder<boost::int128_type>
{
static std::string type_name( std::string const& suffix )
{
return "__int128" + suffix;
}
};
template<> struct tn_holder<boost::uint128_type>
{
static std::string type_name( std::string const& suffix )
{
return "unsigned __int128" + suffix;
}
};
#endif
template<> struct tn_holder<wchar_t>
{
static std::string type_name( std::string const& suffix )

View File

@@ -0,0 +1,88 @@
#ifndef BOOST_CORE_VERBOSE_TERMINATE_HANDLER_HPP_INCLUDED
#define BOOST_CORE_VERBOSE_TERMINATE_HANDLER_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
// Copyright 2022 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/core/demangle.hpp>
#include <boost/throw_exception.hpp>
#include <boost/config.hpp>
#include <exception>
#include <typeinfo>
#include <cstdlib>
#include <cstdio>
namespace boost
{
namespace core
{
BOOST_NORETURN inline void verbose_terminate_handler()
{
std::set_terminate( 0 );
#if defined(BOOST_NO_EXCEPTIONS)
std::fputs( "std::terminate called with exceptions disabled\n", stderr );
#else
try
{
throw;
}
catch( std::exception const& x )
{
#if defined(BOOST_NO_RTTI)
char const * typeid_name = "unknown (RTTI is disabled)";
#else
char const * typeid_name = typeid( x ).name();
boost::core::scoped_demangled_name typeid_demangled_name( typeid_name );
if( typeid_demangled_name.get() != 0 )
{
typeid_name = typeid_demangled_name.get();
}
#endif
boost::source_location loc = boost::get_throw_location( x );
std::fprintf( stderr,
"std::terminate called after throwing an exception:\n\n"
" type: %s\n"
" what(): %s\n"
" location: %s:%lu:%lu in function '%s'\n",
typeid_name,
x.what(),
loc.file_name(), static_cast<unsigned long>( loc.line() ),
static_cast<unsigned long>( loc.column() ), loc.function_name()
);
}
catch( ... )
{
std::fputs( "std::terminate called after throwing an unknown exception\n", stderr );
}
#endif
std::fflush( stdout );
std::abort();
}
} // namespace core
} // namespace boost
#endif // #ifndef BOOST_CORE_VERBOSE_TERMINATE_HANDLER_HPP_INCLUDED

View File

@@ -5,7 +5,9 @@
#ifndef BOOST_ITERATOR_HPP
#define BOOST_ITERATOR_HPP
// This header is obsolete and will be deprecated.
#include <boost/config/header_deprecated.hpp>
BOOST_HEADER_DEPRECATED("<iterator>")
#include <iterator>
#include <cstddef> // std::ptrdiff_t

View File

@@ -1,4 +1,4 @@
# Copyright 2018, 2019, 2021 Peter Dimov
# Copyright 2018-2021 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
@@ -23,6 +23,14 @@ set(BOOST_TEST_LINK_LIBRARIES Boost::core Boost::throw_exception)
boost_test(TYPE run SOURCES no_exceptions_support_test.cpp)
set(BOOST_TEST_LINK_LIBRARIES Boost::core Boost::utility)
boost_test(TYPE run SOURCES sv_conversion_test2.cpp)
set(BOOST_TEST_LINK_LIBRARIES Boost::core Boost::config Boost::move Boost::smart_ptr)
boost_test(TYPE run SOURCES fclose_deleter_test.cpp)
endif()
add_subdirectory(swap)

View File

@@ -14,6 +14,8 @@ project : requirements
<warnings>extra
<toolset>msvc:<warnings-as-errors>on
<toolset>clang:<warnings-as-errors>on
# https://github.com/boostorg/type_traits/issues/173
<toolset>clang-15:<cxxflags>-Wno-deprecated-builtins
<toolset>gcc:<warnings-as-errors>on
<toolset>gcc-4.4:<cxxflags>-Wno-sign-compare ;
@@ -174,7 +176,7 @@ run demangle_test.cpp
run demangled_name_test.cpp
: : : <test-info>always_show_run_output ;
run demangled_name_test.cpp : : : <rtti>off <test-info>always_show_run_output : demangled_name_test_no_rtti ;
run demangled_name_test.cpp : : : <rtti>off <test-info>always_show_run_output : demangled_name_test_no_rtti ;
run scoped_enum.cpp ;
compile-fail scoped_enum_compile_fail_conv_from_int.cpp
@@ -184,11 +186,16 @@ compile-fail scoped_enum_compile_fail_conv_to_int.cpp
run underlying_type.cpp ;
run fclose_deleter_test.cpp : : : <target-os>windows:<define>_CRT_SECURE_NO_WARNINGS <target-os>windows:<define>_CRT_SECURE_NO_DEPRECATE ;
run pointer_traits_pointer_test.cpp ;
run pointer_traits_element_type_test.cpp ;
run pointer_traits_difference_type_test.cpp ;
run pointer_traits_rebind_test.cpp ;
run pointer_traits_pointer_to_test.cpp ;
run pointer_traits_sfinae_test.cpp ;
run pointer_traits_rebind_sfinae_test.cpp ;
run pointer_traits_pointer_to_sfinae_test.cpp ;
run to_address_test.cpp ;
run exchange_test.cpp ;
@@ -200,6 +207,7 @@ compile first_scalar_constexpr_test.cpp ;
run empty_value_test.cpp ;
run empty_value_size_test.cpp ;
run empty_value_final_test.cpp ;
run empty_value_constexpr_test.cpp ;
run quick_exit_test.cpp ;
run-fail quick_exit_fail.cpp ;
@@ -211,6 +219,7 @@ run default_allocator_test.cpp
<toolset>msvc:<warnings-as-errors>on
<toolset>gcc:<warnings-as-errors>on
<toolset>clang:<warnings-as-errors>on ;
run default_allocator_allocate_hint_test.cpp ;
run noinit_adaptor_test.cpp ;
run alloc_construct_test.cpp ;
@@ -236,6 +245,11 @@ run allocator_allocate_hint_test.cpp ;
run allocator_deallocate_test.cpp ;
run allocator_max_size_test.cpp ;
run allocator_soccc_test.cpp ;
run allocator_construct_test.cpp ;
run allocator_destroy_test.cpp ;
run allocator_construct_n_test.cpp ;
run allocator_destroy_n_test.cpp ;
run allocator_traits_test.cpp ;
lib lib_typeid : lib_typeid.cpp : <link>shared:<define>LIB_TYPEID_DYN_LINK=1 ;
@@ -259,19 +273,33 @@ run uncaught_exceptions_np.cpp
run no_exceptions_support_test.cpp : ;
run no_exceptions_support_test.cpp : : : <exception-handling>off : no_exceptions_support_test_nx ;
run cmath_test.cpp ;
run cmath_test.cpp
: : : $(pedantic-errors) ;
run cmath_test.cpp : : : <define>BOOST_CORE_USE_GENERIC_CMATH <toolset>msvc-8.0:<build>no : cmath_test_generic ;
run bit_cast_test.cpp ;
run bit_rotate_test.cpp ;
run bit_countr_test.cpp ;
run bit_countl_test.cpp ;
run bit_width_test.cpp ;
run has_single_bit_test.cpp ;
run bit_floor_test.cpp ;
run bit_ceil_test.cpp ;
run bit_popcount_test.cpp ;
run bit_endian_test.cpp ;
run bit_cast_test.cpp
: : : $(pedantic-errors) ;
run bit_rotate_test.cpp
: : : $(pedantic-errors) ;
run bit_countr_test.cpp
: : : $(pedantic-errors) ;
run bit_countl_test.cpp
: : : $(pedantic-errors) ;
run bit_width_test.cpp
: : : $(pedantic-errors) ;
run has_single_bit_test.cpp
: : : $(pedantic-errors) ;
run bit_floor_test.cpp
: : : $(pedantic-errors) ;
run bit_ceil_test.cpp
: : : $(pedantic-errors) ;
run bit_popcount_test.cpp
: : : $(pedantic-errors) ;
run bit_endian_test.cpp
: : : $(pedantic-errors) ;
compile-fail bit_width_fail.cpp
: <warnings>off ;
run type_name_test.cpp ;
@@ -300,6 +328,12 @@ run sv_eq_test.cpp ;
run sv_lt_test.cpp ;
run sv_stream_insert_test.cpp ;
run sv_conversion_test.cpp ;
run sv_conversion_test2.cpp : ;
run sv_common_reference_test.cpp ;
compile sv_common_reference_test2.cpp ;
compile sv_windows_h_test.cpp ;
compile-fail sv_nullptr_fail.cpp
: $(warning-as-errors-off) ;
run span_test.cpp ;
run span_types_test.cpp ;
@@ -307,6 +341,15 @@ run span_constructible_test.cpp ;
run span_deduction_guide_test.cpp ;
run as_bytes_test.cpp ;
run as_writable_bytes_test.cpp ;
compile span_boost_begin_test.cpp ;
run splitmix64_test.cpp
: : : $(pedantic-errors) ;
run-fail verbose_terminate_handler_fail.cpp : ;
run-fail verbose_terminate_handler_fail.cpp : : : <exception-handling>off : verbose_terminate_handler_fail_nx ;
run-fail verbose_terminate_handler_fail.cpp : : : <rtti>off : verbose_terminate_handler_fail_nr ;
run-fail verbose_terminate_handler_fail.cpp : : : <exception-handling>off <rtti>off : verbose_terminate_handler_fail_nxr ;
use-project /boost/core/swap : ./swap ;
build-project ./swap ;

View File

@@ -15,20 +15,16 @@ struct A1 {
typedef int* const_pointer;
};
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
template<class T>
struct A2 {
typedef T value_type;
};
#endif
int main()
{
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<int*,
boost::allocator_const_pointer<A1<char> >::type>));
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<const int*,
boost::allocator_const_pointer<A2<int> >::type>));
#endif
return boost::report_errors();
}

View File

@@ -20,20 +20,16 @@ struct A1 {
};
};
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
template<class T>
struct A2 {
typedef T value_type;
};
#endif
int main()
{
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<int*,
boost::allocator_const_void_pointer<A1<char> >::type>));
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<const void*,
boost::allocator_const_void_pointer<A2<int> >::type>));
#endif
return boost::report_errors();
}

View File

@@ -0,0 +1,47 @@
/*
Copyright 2022 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/core/allocator_access.hpp>
#include <boost/core/lightweight_test.hpp>
template<class T>
struct A {
typedef T value_type;
A() { }
};
int main()
{
{
A<int> a;
int i[3] = { 5, 5, 5 };
boost::allocator_construct_n(a, &i[0], 3);
BOOST_TEST_EQ(i[0], 0);
BOOST_TEST_EQ(i[1], 0);
BOOST_TEST_EQ(i[2], 0);
}
{
A<int> a;
int i[4] = { 5, 5, 5, 5 };
int j[2] = { 1, 2 };
boost::allocator_construct_n(a, &i[0], 4, &j[0], 2);
BOOST_TEST_EQ(i[0], 1);
BOOST_TEST_EQ(i[1], 2);
BOOST_TEST_EQ(i[2], 1);
BOOST_TEST_EQ(i[3], 2);
}
{
A<int> a;
int i[3] = { 5, 5, 5 };
int j[3] = { 1, 2, 3 };
boost::allocator_construct_n(a, &i[0], 3, &j[0]);
BOOST_TEST_EQ(i[0], 1);
BOOST_TEST_EQ(i[1], 2);
BOOST_TEST_EQ(i[2], 3);
}
return boost::report_errors();
}

View File

@@ -36,7 +36,7 @@ int main()
}
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
{
A1<int> a;
A2<int> a;
int i = 0;
boost::allocator_construct(a, &i, 5);
BOOST_TEST_EQ(i, 6);

View File

@@ -0,0 +1,66 @@
/*
Copyright 2022 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/core/allocator_access.hpp>
#include <boost/core/lightweight_test.hpp>
struct S {
static int count;
S() {
++count;
}
S(const S&) {
++count;
}
~S() {
--count;
}
};
int S::count = 0;
template<class T>
struct A1 {
typedef T value_type;
A1() { }
};
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
template<class T>
struct A2 {
typedef T value_type;
A2() { }
template<class U>
void destroy(U* p) {
*p = U();
}
};
#endif
int main()
{
{
A1<int> a;
S s[3];
boost::allocator_destroy_n(a, &s[0], 3);
BOOST_TEST_EQ(S::count, 0);
::new((void*)&s[0]) S();
::new((void*)&s[1]) S();
::new((void*)&s[2]) S();
}
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
{
A2<int> a;
int i[3] = { 5, 5, 5 };
boost::allocator_destroy_n(a, &i[0], 3);
BOOST_TEST_EQ(i[0], 0);
BOOST_TEST_EQ(i[1], 0);
BOOST_TEST_EQ(i[2], 0);
}
#endif
return boost::report_errors();
}

View File

@@ -52,7 +52,7 @@ int main()
}
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
{
A1<int> a;
A2<int> a;
int i = 5;
boost::allocator_destroy(a, &i);
BOOST_TEST_EQ(i, 0);

View File

@@ -15,20 +15,16 @@ struct A1 {
typedef short difference_type;
};
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
template<class T>
struct A2 {
typedef T value_type;
};
#endif
int main()
{
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<short,
boost::allocator_difference_type<A1<char> >::type>));
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<std::ptrdiff_t,
boost::allocator_difference_type<A2<int> >::type>));
#endif
return boost::report_errors();
}

View File

@@ -15,7 +15,6 @@ struct A1 {
int value;
};
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
template<class T>
struct A2 {
typedef T value_type;
@@ -24,24 +23,25 @@ struct A2 {
template<class T>
struct A3 {
typedef T value_type;
typedef std::false_type is_always_equal;
struct is_always_equal {
static const bool value = false;
};
};
template<class T>
struct A4 {
typedef T value_type;
typedef std::true_type is_always_equal;
struct is_always_equal {
static const bool value = true;
};
int value;
};
#endif
int main()
{
BOOST_TEST_TRAIT_FALSE((boost::allocator_is_always_equal<A1<int> >::type));
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
BOOST_TEST_TRAIT_TRUE((boost::allocator_is_always_equal<A2<int> >::type));
BOOST_TEST_TRAIT_FALSE((boost::allocator_is_always_equal<A3<int> >::type));
BOOST_TEST_TRAIT_TRUE((boost::allocator_is_always_equal<A4<int> >::type));
#endif
return boost::report_errors();
}

View File

@@ -19,21 +19,17 @@ struct A1 {
}
};
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
template<class T>
struct A2 {
typedef T value_type;
typedef short size_type;
A2() { }
};
#endif
int main()
{
BOOST_TEST_EQ(boost::allocator_max_size(A1<int>()), 1);
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
BOOST_TEST_LE(boost::allocator_max_size(A2<int>()),
(std::numeric_limits<short>::max)());
#endif
return boost::report_errors();
}

View File

@@ -14,21 +14,19 @@ struct A1 {
typedef T value_type;
};
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
template<class T>
struct A2 {
typedef T value_type;
typedef std::true_type propagate_on_container_copy_assignment;
struct propagate_on_container_copy_assignment {
static const bool value = true;
};
};
#endif
int main()
{
BOOST_TEST_TRAIT_FALSE((boost::
allocator_propagate_on_container_copy_assignment<A1<int> >::type));
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
BOOST_TEST_TRAIT_TRUE((boost::
allocator_propagate_on_container_copy_assignment<A2<int> >::type));
#endif
return boost::report_errors();
}

View File

@@ -14,21 +14,19 @@ struct A1 {
typedef T value_type;
};
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
template<class T>
struct A2 {
typedef T value_type;
typedef std::true_type propagate_on_container_move_assignment;
struct propagate_on_container_move_assignment {
static const bool value = true;
};
};
#endif
int main()
{
BOOST_TEST_TRAIT_FALSE((boost::
allocator_propagate_on_container_move_assignment<A1<int> >::type));
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
BOOST_TEST_TRAIT_TRUE((boost::
allocator_propagate_on_container_move_assignment<A2<int> >::type));
#endif
return boost::report_errors();
}

View File

@@ -14,21 +14,19 @@ struct A1 {
typedef T value_type;
};
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
template<class T>
struct A2 {
typedef T value_type;
typedef std::true_type propagate_on_container_swap;
struct propagate_on_container_swap {
static const bool value = true;
};
};
#endif
int main()
{
BOOST_TEST_TRAIT_FALSE((boost::
allocator_propagate_on_container_swap<A1<int> >::type));
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
BOOST_TEST_TRAIT_TRUE((boost::
allocator_propagate_on_container_swap<A2<int> >::type));
#endif
return boost::report_errors();
}

View File

@@ -15,20 +15,16 @@ struct A1 {
typedef int* pointer;
};
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
template<class T>
struct A2 {
typedef T value_type;
};
#endif
int main()
{
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<int*,
boost::allocator_pointer<A1<char> >::type>));
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<int*,
boost::allocator_pointer<A2<int> >::type>));
#endif
return boost::report_errors();
}

View File

@@ -18,20 +18,16 @@ struct A1 {
};
};
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
template<class T>
struct A2 {
typedef T value_type;
};
#endif
int main()
{
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<A1<int>,
boost::allocator_rebind<A1<char>, bool>::type>));
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<A2<int>,
boost::allocator_rebind<A2<char>, int>::type>));
#endif
return boost::report_errors();
}

View File

@@ -16,7 +16,6 @@ struct A1 {
int value;
};
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
template<class T>
struct A2 {
typedef T value_type;
@@ -27,15 +26,12 @@ struct A2 {
}
int value;
};
#endif
int main()
{
BOOST_TEST_EQ(1, boost::
allocator_select_on_container_copy_construction(A1<int>(1)).value);
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
BOOST_TEST_EQ(2, boost::
allocator_select_on_container_copy_construction(A2<int>(1)).value);
#endif
return boost::report_errors();
}

View File

@@ -0,0 +1,114 @@
/*
Copyright 2021 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/core/allocator_traits.hpp>
#include <boost/core/lightweight_test_trait.hpp>
template<class T>
class creator {
public:
typedef T value_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef void* void_pointer;
typedef const void* const_void_pointer;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
template<class U>
struct rebind {
typedef creator<U> other;
};
explicit creator(int value) BOOST_NOEXCEPT
: state_(value) { }
template<class U>
creator(const creator<U>& other) BOOST_NOEXCEPT
: state_(other.state) { }
std::size_t max_size() const BOOST_NOEXCEPT {
return static_cast<std::size_t>(-1) / sizeof(T);
}
T* allocate(std::size_t n, const void* = 0) {
return static_cast<T*>(::operator new(sizeof(T) * n));
}
void deallocate(T* p, std::size_t) {
::operator delete(p);
}
int state() const {
return state_;
}
private:
int state_;
};
template<class T, class U>
inline bool operator==(const creator<T>& lhs,
const creator<U>& rhs) BOOST_NOEXCEPT
{
return lhs.state() == rhs.state();
}
template<class T, class U>
inline bool operator!=(const creator<T>& lhs,
const creator<U>& rhs) BOOST_NOEXCEPT
{
return !(lhs == rhs);
}
int main()
{
BOOST_TEST_TRAIT_SAME(creator<int>,
boost::allocator_traits<creator<int> >::allocator_type);
BOOST_TEST_TRAIT_SAME(int,
boost::allocator_traits<creator<int> >::value_type);
BOOST_TEST_TRAIT_SAME(int*,
boost::allocator_traits<creator<int> >::pointer);
BOOST_TEST_TRAIT_SAME(const int*,
boost::allocator_traits<creator<int> >::const_pointer);
BOOST_TEST_TRAIT_SAME(void*,
boost::allocator_traits<creator<int> >::void_pointer);
BOOST_TEST_TRAIT_SAME(const void*,
boost::allocator_traits<creator<int> >::const_void_pointer);
BOOST_TEST_TRAIT_SAME(std::ptrdiff_t,
boost::allocator_traits<creator<int> >::difference_type);
BOOST_TEST_TRAIT_SAME(std::size_t,
boost::allocator_traits<creator<int> >::size_type);
BOOST_TEST_TRAIT_FALSE((boost::allocator_traits<creator<int> >::
propagate_on_container_copy_assignment));
BOOST_TEST_TRAIT_FALSE((boost::allocator_traits<creator<int> >::
propagate_on_container_move_assignment));
BOOST_TEST_TRAIT_FALSE((boost::allocator_traits<creator<int> >::
propagate_on_container_swap));
BOOST_TEST_TRAIT_FALSE((boost::allocator_traits<creator<int> >::
is_always_equal));
BOOST_TEST_TRAIT_SAME(creator<char>,
boost::allocator_traits<creator<int> >::
rebind_traits<char>::allocator_type);
creator<int> a(1);
int* p1 = boost::allocator_traits<creator<int> >::allocate(a, 1);
if (BOOST_TEST(p1)) {
boost::allocator_traits<creator<int> >::construct(a, p1, 5);
BOOST_TEST_EQ(*p1, 5);
boost::allocator_traits<creator<int> >::destroy(a, p1);
boost::allocator_traits<creator<int> >::deallocate(a, p1, 1);
}
int* p2 = boost::allocator_traits<creator<int> >::allocate(a, 1, 0);
if (BOOST_TEST(p2)) {
boost::allocator_traits<creator<int> >::deallocate(a, p2, 1);
}
BOOST_TEST_EQ(boost::allocator_traits<creator<int> >::max_size(a),
static_cast<std::size_t>(-1) / sizeof(int));
BOOST_TEST(boost::allocator_traits<creator<int> >::
select_on_container_copy_construction(a) == a);
return boost::report_errors();
}

View File

@@ -20,20 +20,16 @@ struct A1 {
};
};
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
template<class T>
struct A2 {
typedef T value_type;
};
#endif
int main()
{
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<int*,
boost::allocator_void_pointer<A1<char> >::type>));
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<void*,
boost::allocator_void_pointer<A2<int> >::type>));
#endif
return boost::report_errors();
}

View File

@@ -38,14 +38,14 @@ int main()
test_bit_ceil( static_cast<unsigned short>( 0 ) );
test_bit_ceil( static_cast<unsigned int>( 0 ) );
test_bit_ceil( static_cast<unsigned long>( 0 ) );
test_bit_ceil( static_cast<unsigned long long>( 0 ) );
test_bit_ceil( static_cast<boost::ulong_long_type>( 0 ) );
}
{
test_bit_ceil( static_cast<boost::uint8_t>( 0x80 ) );
test_bit_ceil( static_cast<boost::uint16_t>( 0x8000 ) );
test_bit_ceil( static_cast<boost::uint32_t>( 0x80000000 ) );
test_bit_ceil( static_cast<boost::uint64_t>( 0x8000000000000000 ) );
test_bit_ceil( boost::uint64_t( 1 ) << 63 );
}
boost::detail::splitmix64 rng;
@@ -58,7 +58,7 @@ int main()
test_bit_ceil( static_cast<unsigned short>( x ) );
test_bit_ceil( static_cast<unsigned int>( x ) );
test_bit_ceil( static_cast<unsigned long>( x ) );
test_bit_ceil( static_cast<unsigned long long>( x ) );
test_bit_ceil( static_cast<boost::ulong_long_type>( x ) );
}
return boost::report_errors();

View File

@@ -27,7 +27,7 @@ int main()
test_countl( static_cast<unsigned short>( 0 ) );
test_countl( static_cast<unsigned int>( 0 ) );
test_countl( static_cast<unsigned long>( 0 ) );
test_countl( static_cast<unsigned long long>( 0 ) );
test_countl( static_cast<boost::ulong_long_type>( 0 ) );
boost::detail::splitmix64 rng;
@@ -39,7 +39,7 @@ int main()
test_countl( static_cast<unsigned short>( x ) );
test_countl( static_cast<unsigned int>( x ) );
test_countl( static_cast<unsigned long>( x ) );
test_countl( static_cast<unsigned long long>( x ) );
test_countl( static_cast<boost::ulong_long_type>( x ) );
}
return boost::report_errors();

View File

@@ -27,7 +27,7 @@ int main()
test_countr( static_cast<unsigned short>( 0 ) );
test_countr( static_cast<unsigned int>( 0 ) );
test_countr( static_cast<unsigned long>( 0 ) );
test_countr( static_cast<unsigned long long>( 0 ) );
test_countr( static_cast<boost::ulong_long_type>( 0 ) );
boost::detail::splitmix64 rng;
@@ -39,7 +39,7 @@ int main()
test_countr( static_cast<unsigned short>( x ) );
test_countr( static_cast<unsigned int>( x ) );
test_countr( static_cast<unsigned long>( x ) );
test_countr( static_cast<unsigned long long>( x ) );
test_countr( static_cast<boost::ulong_long_type>( x ) );
}
return boost::report_errors();

View File

@@ -15,7 +15,7 @@
int main()
{
boost::uint64_t v = static_cast<boost::uint64_t>( 0x0102030405060708ull );
boost::uint64_t v = ( static_cast<boost::uint64_t>( 0x01020304u ) << 32 ) + 0x05060708u;
if( boost::core::endian::native == boost::core::endian::little )
{

View File

@@ -33,7 +33,7 @@ int main()
test_bit_floor( static_cast<unsigned short>( 0 ) );
test_bit_floor( static_cast<unsigned int>( 0 ) );
test_bit_floor( static_cast<unsigned long>( 0 ) );
test_bit_floor( static_cast<unsigned long long>( 0 ) );
test_bit_floor( static_cast<boost::ulong_long_type>( 0 ) );
}
boost::detail::splitmix64 rng;
@@ -46,7 +46,7 @@ int main()
test_bit_floor( static_cast<unsigned short>( x ) );
test_bit_floor( static_cast<unsigned int>( x ) );
test_bit_floor( static_cast<unsigned long>( x ) );
test_bit_floor( static_cast<unsigned long long>( x ) );
test_bit_floor( static_cast<boost::ulong_long_type>( x ) );
}
return boost::report_errors();

View File

@@ -26,7 +26,7 @@ int main()
test_popcount( static_cast<unsigned short>( 0 ) );
test_popcount( static_cast<unsigned int>( 0 ) );
test_popcount( static_cast<unsigned long>( 0 ) );
test_popcount( static_cast<unsigned long long>( 0 ) );
test_popcount( static_cast<boost::ulong_long_type>( 0 ) );
}
boost::detail::splitmix64 rng;
@@ -39,7 +39,7 @@ int main()
test_popcount( static_cast<unsigned short>( x ) );
test_popcount( static_cast<unsigned int>( x ) );
test_popcount( static_cast<unsigned long>( x ) );
test_popcount( static_cast<unsigned long long>( x ) );
test_popcount( static_cast<boost::ulong_long_type>( x ) );
}
return boost::report_errors();

View File

@@ -103,26 +103,28 @@ int main()
BOOST_TEST_EQ( +boost::core::rotr( x, 1 ), 0x44444444 );
}
#define CONST64(x) ((boost::uint64_t(x) << 32) + (x))
{
boost::uint64_t x = 0x1111111111111111;
boost::uint64_t x = CONST64(0x11111111);
BOOST_TEST_EQ( +boost::core::rotl( x, 1 ), 0x2222222222222222 );
BOOST_TEST_EQ( +boost::core::rotr( x, 1 ), 0x8888888888888888 );
BOOST_TEST_EQ( +boost::core::rotl( x, 1 ), CONST64(0x22222222) );
BOOST_TEST_EQ( +boost::core::rotr( x, 1 ), CONST64(0x88888888) );
x = 0x2222222222222222;
x = CONST64(0x22222222);
BOOST_TEST_EQ( +boost::core::rotl( x, 1 ), 0x4444444444444444 );
BOOST_TEST_EQ( +boost::core::rotr( x, 1 ), 0x1111111111111111 );
BOOST_TEST_EQ( +boost::core::rotl( x, 1 ), CONST64(0x44444444) );
BOOST_TEST_EQ( +boost::core::rotr( x, 1 ), CONST64(0x11111111) );
x = 0x4444444444444444;
x = CONST64(0x44444444);
BOOST_TEST_EQ( +boost::core::rotl( x, 1 ), 0x8888888888888888 );
BOOST_TEST_EQ( +boost::core::rotr( x, 1 ), 0x2222222222222222 );
BOOST_TEST_EQ( +boost::core::rotl( x, 1 ), CONST64(0x88888888) );
BOOST_TEST_EQ( +boost::core::rotr( x, 1 ), CONST64(0x22222222) );
x = 0x8888888888888888;
x = CONST64(0x88888888);
BOOST_TEST_EQ( +boost::core::rotl( x, 1 ), 0x1111111111111111 );
BOOST_TEST_EQ( +boost::core::rotr( x, 1 ), 0x4444444444444444 );
BOOST_TEST_EQ( +boost::core::rotl( x, 1 ), CONST64(0x11111111) );
BOOST_TEST_EQ( +boost::core::rotr( x, 1 ), CONST64(0x44444444) );
}
for( int i = -M; i <= M; ++i )
@@ -152,7 +154,7 @@ int main()
}
{
unsigned long long x = 0;
boost::ulong_long_type x = 0;
BOOST_TEST_EQ( boost::core::rotl( x, i ), x );
BOOST_TEST_EQ( boost::core::rotr( x, i ), x );
}
@@ -168,7 +170,7 @@ int main()
test_rotate( static_cast<unsigned short>( x ) );
test_rotate( static_cast<unsigned int>( x ) );
test_rotate( static_cast<unsigned long>( x ) );
test_rotate( static_cast<unsigned long long>( x ) );
test_rotate( static_cast<boost::ulong_long_type>( x ) );
}
return boost::report_errors();

13
test/bit_width_fail.cpp Normal file
View File

@@ -0,0 +1,13 @@
// Negative test for boost/core/bit.hpp (bit_width)
//
// Copyright 2022 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/core/bit.hpp>
int main()
{
// should fail, because 0 is a signed integral type
return boost::core::bit_width( 0 );
}

View File

@@ -87,7 +87,7 @@ int main()
test_width( static_cast<unsigned short>( x ) );
test_width( static_cast<unsigned int>( x ) );
test_width( static_cast<unsigned long>( x ) );
test_width( static_cast<unsigned long long>( x ) );
test_width( static_cast<boost::ulong_long_type>( x ) );
}
return boost::report_errors();

View File

@@ -0,0 +1,19 @@
/*
Copyright 2021 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/core/default_allocator.hpp>
#include <boost/core/allocator_access.hpp>
#include <boost/core/lightweight_test.hpp>
int main()
{
boost::default_allocator<int> a;
int* p = boost::allocator_allocate(a, 1, 0);
BOOST_TEST(p != 0);
a.deallocate(p, 1);
return boost::report_errors();
}

View File

@@ -0,0 +1,65 @@
/*
Copyright 2022 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_CONSTEXPR)
#include <boost/core/empty_value.hpp>
#include <boost/core/lightweight_test.hpp>
struct empty {
constexpr int value() const {
return 1;
}
};
class type {
public:
explicit constexpr type(int count)
: value_(count) { }
constexpr int value() const {
return value_;
}
private:
int value_;
};
void test_int()
{
constexpr boost::empty_value<int> v(boost::empty_init_t(), 4);
constexpr int c = v.get();
BOOST_TEST_EQ(c, 4);
}
void test_empty()
{
constexpr boost::empty_value<empty> v = boost::empty_init_t();
constexpr int c = v.get().value();
BOOST_TEST_EQ(c, 1);
}
void test_type()
{
constexpr boost::empty_value<type> v(boost::empty_init_t(), 2);
constexpr int c = v.get().value();
BOOST_TEST_EQ(c, 2);
}
int main()
{
test_int();
test_empty();
test_type();
return boost::report_errors();
}
#else
int main()
{
return 0;
}
#endif

View File

@@ -0,0 +1,73 @@
/*
* Copyright Andrey Semashev 2022.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*/
/*!
* \file fclose_deleter_test.cpp
* \author Andrey Semashev
* \date 21.09.2022
*
* This file contains tests for \c boost::fclose_deleter.
*/
#include <boost/core/fclose_deleter.hpp>
#include <cstdio>
#include <cstddef>
#include <boost/config.hpp>
#include <boost/move/unique_ptr.hpp>
#include <boost/smart_ptr/shared_ptr.hpp>
#if !defined(BOOST_NO_CXX11_SMART_PTR)
#include <memory>
#endif
boost::movelib::unique_ptr< std::FILE, boost::fclose_deleter > make_boost_unique_file(const char* filename)
{
return boost::movelib::unique_ptr< std::FILE, boost::fclose_deleter >(std::fopen(filename, "w"));
}
boost::shared_ptr< std::FILE > make_boost_shared_file(const char* filename)
{
return boost::shared_ptr< std::FILE >(std::fopen(filename, "w"), boost::fclose_deleter());
}
#if !defined(BOOST_NO_CXX11_SMART_PTR)
std::unique_ptr< std::FILE, boost::fclose_deleter > make_std_unique_file(const char* filename)
{
return std::unique_ptr< std::FILE, boost::fclose_deleter >(std::fopen(filename, "w"));
}
std::shared_ptr< std::FILE > make_std_shared_file(const char* filename)
{
return std::shared_ptr< std::FILE >(std::fopen(filename, "w"), boost::fclose_deleter());
}
#endif
int main()
{
const char* const filename = "fcd_test.txt";
std::FILE* file = std::fopen(filename, "w");
if (file)
{
boost::fclose_deleter()(file);
file = NULL;
}
make_boost_unique_file(filename);
make_boost_shared_file(filename);
#if !defined(BOOST_NO_CXX11_SMART_PTR)
make_std_unique_file(filename);
make_std_shared_file(filename);
#endif
// Test if the deleter can be called on a NULL pointer
boost::shared_ptr< std::FILE >(static_cast< std::FILE* >(NULL), boost::fclose_deleter());
#if !defined(BOOST_NO_CXX11_SMART_PTR)
std::shared_ptr< std::FILE >(static_cast< std::FILE* >(NULL), boost::fclose_deleter());
#endif
std::remove(filename);
}

View File

@@ -103,7 +103,7 @@ int main()
test_single_bit( static_cast<unsigned short>( x ) );
test_single_bit( static_cast<unsigned int>( x ) );
test_single_bit( static_cast<unsigned long>( x ) );
test_single_bit( static_cast<unsigned long long>( x ) );
test_single_bit( static_cast<boost::ulong_long_type>( x ) );
}
return boost::report_errors();

View File

@@ -8,8 +8,15 @@
// http://www.boost.org/LICENSE_1_0.txt
//
#define BOOST_ALLOW_DEPRECATED_HEADERS
#define _SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING
#include <boost/config.hpp>
// std::iterator template is deprecated in C++17. Some standard libraries emit warnings
// that cannot be easily suppressed, so disable the tests in C++17 onwards.
#if BOOST_CXX_VERSION < 201703
#include <boost/iterator.hpp>
#include <boost/core/is_same.hpp>
#include <boost/core/lightweight_test_trait.hpp>
@@ -69,3 +76,11 @@ int main()
return boost::report_errors();
}
#else // BOOST_CXX_VERSION < 201703
int main()
{
}
#endif // BOOST_CXX_VERSION < 201703

View File

@@ -0,0 +1,72 @@
/*
Copyright 2021 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_DECLTYPE_N3276)
#include <boost/core/pointer_traits.hpp>
#include <boost/core/lightweight_test.hpp>
template<class T>
class has_pointer_to {
template<class>
struct result {
char x, y;
};
template<class O>
static auto check(int) -> result<decltype(O::pointer_to)>;
template<class O>
static char check(long);
public:
static const bool value = sizeof(check<T>(0)) > 1;
};
struct P1 { };
struct P2 {
typedef int element_type;
static int* pointer_to(int& value) {
return &value;
}
};
struct P3 {
typedef void element_type;
};
struct P4 {
typedef int element_type;
};
struct P5 {
typedef int element_type;
static int* pointer_to() {
return 0;
}
};
int main()
{
BOOST_TEST((!has_pointer_to<boost::pointer_traits<P1> >::value));
BOOST_TEST(has_pointer_to<boost::pointer_traits<P2> >::value);
BOOST_TEST(!has_pointer_to<boost::pointer_traits<P3> >::value);
BOOST_TEST(!has_pointer_to<boost::pointer_traits<P4> >::value);
BOOST_TEST(!has_pointer_to<boost::pointer_traits<P5> >::value);
BOOST_TEST(has_pointer_to<boost::pointer_traits<int*> >::value);
BOOST_TEST(!has_pointer_to<boost::pointer_traits<void*> >::value);
return boost::report_errors();
}
#else
int main()
{
return 0;
}
#endif

View File

@@ -0,0 +1,83 @@
/*
Copyright 2021 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_TEMPLATE_ALIASES) && \
(!defined(BOOST_GCC) || (BOOST_GCC >= 40800)) && \
(!defined(BOOST_MSVC) || (BOOST_MSVC >= 1900))
#include <boost/core/pointer_traits.hpp>
#include <boost/core/lightweight_test.hpp>
template<class>
struct valid {
typedef void type;
};
#if !defined(BOOST_GCC) || (BOOST_GCC >= 50000)
template<class, class, class = void>
struct has_rebind {
static const bool value = false;
};
template<class T, class U>
struct has_rebind<T, U,
typename valid<typename T::template rebind<U> >::type> {
static const bool value = true;
};
#else
template<template<class> class T, class U>
using defer = T<U>;
template<class T, class U>
using rebind = defer<T::template rebind, U>;
template<class, class, template<class, class> class = rebind, class = void>
struct has_rebind {
static const bool value = false;
};
template<class T, class U, template<class, class> class R>
struct has_rebind<T, U, R, typename valid<R<T, U> >::type> {
static const bool value = true;
};
#endif
struct P1 { };
struct P2 {
typedef int element_type;
};
struct P3 {
typedef int element_type;
template<class>
using rebind = P3;
};
template<class T>
struct S {
typedef T element_type;
};
typedef S<int> P4;
int main()
{
BOOST_TEST((!has_rebind<boost::pointer_traits<P1>, char>::value));
BOOST_TEST((!has_rebind<boost::pointer_traits<P2>, char>::value));
BOOST_TEST((has_rebind<boost::pointer_traits<P3>, char>::value));
BOOST_TEST((has_rebind<boost::pointer_traits<P4>, char>::value));
BOOST_TEST((has_rebind<boost::pointer_traits<int*>, char>::value));
return boost::report_errors();
}
#else
int main()
{
return 0;
}
#endif

View File

@@ -1,5 +1,5 @@
/*
Copyright 2017 Glen Joseph Fernandes
Copyright 2017-2022 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
@@ -84,15 +84,49 @@ int main()
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<P1<int>,
boost::pointer_traits<P1<const R> >::rebind_to<int>::type>));
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<char*,
boost::pointer_traits<R*>::rebind<char> >));
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<P1<char>,
boost::pointer_traits<P1<R> >::rebind<char> >));
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<P2<char, R>,
boost::pointer_traits<P2<R, R> >::rebind<char> >));
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<P3<char, R, R>,
boost::pointer_traits<P3<R, R, R> >::rebind<char> >));
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<void*,
boost::pointer_traits<R*>::rebind<void> >));
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<P1<void>,
boost::pointer_traits<P1<R> >::rebind<void> >));
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<R*,
boost::pointer_traits<void*>::rebind<R> >));
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<P1<R>,
boost::pointer_traits<P1<void> >::rebind<R> >));
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<const int*,
boost::pointer_traits<R*>::rebind<const int> >));
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<P1<const int>,
boost::pointer_traits<P1<R> >::rebind<const int> >));
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<int*,
boost::pointer_traits<const R*>::rebind<int> >));
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<P1<int>,
boost::pointer_traits<P1<const R> >::rebind<int> >));
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<E1<bool>,
boost::pointer_traits<E1<R> >::rebind_to<char>::type>));
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<E2<bool, R>,
boost::pointer_traits<E2<R, R> >::rebind_to<char>::type>));
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<E3<bool, R, R>,
boost::pointer_traits<E3<R, R, R> >::rebind_to<char>::type>));
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<E1<bool>,
boost::pointer_traits<E1<R> >::rebind<char> >));
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<E2<bool, R>,
boost::pointer_traits<E2<R, R> >::rebind<char> >));
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<E3<bool, R, R>,
boost::pointer_traits<E3<R, R, R> >::rebind<char> >));
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<P<char, R, R, R>,
boost::pointer_traits<P<R, R, R, R> >::rebind<char> >));
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<E<bool, R, R, R>,
boost::pointer_traits<E<R, R, R, R> >::rebind_to<char>::type>));
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<E<bool, R, R, R>,
boost::pointer_traits<E<R, R, R, R> >::rebind<char> >));
#endif
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<E1<bool>,
boost::pointer_traits<E1<R> >::rebind_to<void>::type>));
@@ -102,6 +136,14 @@ int main()
boost::pointer_traits<E1<R> >::rebind_to<const int>::type>));
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<E1<bool>,
boost::pointer_traits<E1<const R> >::rebind_to<int>::type>));
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<E1<bool>,
boost::pointer_traits<E1<R> >::rebind<void> >));
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<E1<bool>,
boost::pointer_traits<E1<void> >::rebind<R> >));
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<E1<bool>,
boost::pointer_traits<E1<R> >::rebind<const int> >));
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<E1<bool>,
boost::pointer_traits<E1<const R> >::rebind<int> >));
#endif
return boost::report_errors();
}

View File

@@ -0,0 +1,108 @@
/*
Copyright 2021 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/core/pointer_traits.hpp>
#include <boost/core/lightweight_test.hpp>
template<class>
struct valid {
typedef void type;
};
template<class, class = void>
struct has_pointer {
static const bool value = false;
};
template<class T>
struct has_pointer<T, typename valid<typename T::pointer>::type> {
static const bool value = true;
};
template<class, class = void>
struct has_element_type {
static const bool value = false;
};
template<class T>
struct has_element_type<T, typename valid<typename T::element_type>::type> {
static const bool value = true;
};
template<class, class = void>
struct has_difference_type {
static const bool value = false;
};
template<class T>
struct has_difference_type<T,
typename valid<typename T::difference_type>::type> {
static const bool value = true;
};
template<class, class, class = void>
struct has_rebind_to_type {
static const bool value = false;
};
template<class T, class U>
struct has_rebind_to_type<T, U,
typename valid<typename T::template rebind_to<U>::type>::type> {
static const bool value = true;
};
struct P1 { };
struct P2 {
typedef int element_type;
};
struct P3 {
typedef int element_type;
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
template<class>
using rebind = P3;
#else
template<class>
struct rebind {
typedef P3 other;
};
#endif
};
template<class T>
struct S {
typedef T element_type;
};
typedef S<int> P4;
int main()
{
BOOST_TEST(!has_pointer<boost::pointer_traits<P1> >::value);
BOOST_TEST(!has_element_type<boost::pointer_traits<P1> >::value);
BOOST_TEST(!has_difference_type<boost::pointer_traits<P1> >::value);
BOOST_TEST((!has_rebind_to_type<boost::pointer_traits<P1>, char>::value));
BOOST_TEST(has_pointer<boost::pointer_traits<P2> >::value);
BOOST_TEST(has_element_type<boost::pointer_traits<P2> >::value);
BOOST_TEST(has_difference_type<boost::pointer_traits<P2> >::value);
BOOST_TEST((!has_rebind_to_type<boost::pointer_traits<P2>, char>::value));
BOOST_TEST(has_pointer<boost::pointer_traits<P3> >::value);
BOOST_TEST(has_element_type<boost::pointer_traits<P3> >::value);
BOOST_TEST(has_difference_type<boost::pointer_traits<P3> >::value);
BOOST_TEST((has_rebind_to_type<boost::pointer_traits<P3>, char>::value));
BOOST_TEST(has_pointer<boost::pointer_traits<P4> >::value);
BOOST_TEST(has_element_type<boost::pointer_traits<P4> >::value);
BOOST_TEST(has_difference_type<boost::pointer_traits<P4> >::value);
BOOST_TEST((has_rebind_to_type<boost::pointer_traits<P4>, char>::value));
BOOST_TEST(has_pointer<boost::pointer_traits<int*> >::value);
BOOST_TEST(has_element_type<boost::pointer_traits<int*> >::value);
BOOST_TEST(has_difference_type<boost::pointer_traits<int*> >::value);
BOOST_TEST((has_rebind_to_type<boost::pointer_traits<int*>, char>::value));
return boost::report_errors();
}

View File

@@ -20,6 +20,7 @@
#include <boost/core/lightweight_test.hpp>
#include <boost/noncopyable.hpp>
#include <boost/core/null_deleter.hpp>
#include <boost/core/fclose_deleter.hpp>
#include <boost/core/pointer_traits.hpp>
#include <boost/ref.hpp>
#include <boost/core/scoped_enum.hpp>

View File

@@ -0,0 +1,32 @@
/*
Copyright 2022 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_CONSTEXPR) && !defined(BOOST_NO_CXX11_DECLTYPE)
#include <boost/core/span.hpp>
#include <vector>
namespace boost {
namespace begin_ {
template<class T>
void begin(T&) { }
} // begin_
using namespace begin_;
} // boost
template class boost::span<float>;
void function()
{
std::vector<int> y;
boost::begin(y);
}
#endif

View File

@@ -362,18 +362,6 @@ void test_crend()
BOOST_TEST_EQ((boost::span<int>(&a[0], 4).crend().base()), &a[0]);
}
void test_begin_span()
{
int a[4];
BOOST_TEST_EQ((begin(boost::span<int>(&a[0], 4))), &a[0]);
}
void test_end_span()
{
int a[4];
BOOST_TEST_EQ((end(boost::span<int>(&a[0], 4))), &a[4]);
}
int main()
{
test_extent();
@@ -421,8 +409,6 @@ int main()
test_cend();
test_crbegin();
test_crend();
test_begin_span();
test_end_span();
return boost::report_errors();
}
#else

38
test/splitmix64_test.cpp Normal file
View File

@@ -0,0 +1,38 @@
// Test for boost/core/detail/splitmix64.hpp
//
// Copyright 2022 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/core/detail/splitmix64.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/cstdint.hpp>
int main()
{
{
boost::detail::splitmix64 rng;
boost::uint64_t r1 = rng(), x1 = ( boost::uint64_t(0xe220a839u) << 32 ) + 0x7b1dcdafu;
BOOST_TEST_EQ( r1, x1 );
for( int i = 0; i < 1000; ++i ) rng();
boost::uint64_t r2 = rng(), x2 = ( boost::uint64_t(0xdcad513cu) << 32 ) + 0x211f942du;
BOOST_TEST_EQ( r2, x2 );
}
{
boost::detail::splitmix64 rng( 12345 );
boost::uint64_t r1 = rng(), x1 = ( boost::uint64_t(0x22118258u) << 32 ) + 0xa9d111a0u;
BOOST_TEST_EQ( r1, x1 );
for( int i = 0; i < 1000; ++i ) rng();
boost::uint64_t r2 = rng(), x2 = ( boost::uint64_t(0xaaefb4b6u) << 32 ) + 0x5c15e958u;
BOOST_TEST_EQ( r2, x2 );
}
return boost::report_errors();
}

View File

@@ -0,0 +1,34 @@
// Copyright 2021 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/core/detail/string_view.hpp>
#include <boost/core/lightweight_test_trait.hpp>
#include <boost/config/pragma_message.hpp>
#include <boost/config.hpp>
#include <string>
#if defined(BOOST_NO_CXX20_HDR_CONCEPTS)
BOOST_PRAGMA_MESSAGE( "Skipping test because BOOST_NO_CXX20_HDR_CONCEPTS is defined" )
int main() {}
#else
#include <concepts>
#include <type_traits>
using T = std::common_reference_t< boost::core::string_view&&, std::string& >;
static_assert( std::common_reference_with< boost::core::string_view&&, std::string& > );
static_assert( std::common_reference_with< boost::core::wstring_view&&, std::wstring const& > );
int main()
{
BOOST_TEST_TRAIT_SAME( std::common_reference_t< boost::core::string_view&&, std::string& >, boost::core::string_view );
BOOST_TEST_TRAIT_SAME( std::common_reference_t< boost::core::wstring_view&&, std::wstring const& >, boost::core::wstring_view );
return boost::report_errors();
}
#endif

View File

@@ -0,0 +1,24 @@
// Copyright 2021 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/core/detail/string_view.hpp>
#include <boost/config/pragma_message.hpp>
#include <string>
#include <iterator>
#if !defined(__cpp_lib_ranges)
BOOST_PRAGMA_MESSAGE( "Skipping test because __cpp_lib_ranges is not defined" )
#else
struct Iterator
{
using value_type = std::string;
boost::core::string_view operator*() const noexcept;
};
static_assert( std::indirectly_readable<Iterator> );
#endif

View File

@@ -0,0 +1,32 @@
// Copyright 2021 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/core/detail/string_view.hpp>
#include <boost/utility/string_view.hpp>
#include <boost/core/lightweight_test.hpp>
#include <string>
boost::core::string_view f( boost::core::string_view const& str )
{
return str;
}
int main()
{
{
std::string s1( "123" );
std::string s2 = f( s1 );
BOOST_TEST_EQ( s1, s2 );
}
{
boost::string_view s1( "123" );
boost::string_view s2 = f( s1 );
BOOST_TEST_EQ( s1, s2 );
}
return boost::report_errors();
}

19
test/sv_nullptr_fail.cpp Normal file
View File

@@ -0,0 +1,19 @@
// Copyright 2022 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/core/detail/string_view.hpp>
#include <boost/config.hpp>
#if defined(BOOST_NO_CXX11_NULLPTR)
#error BOOST_NO_CXX11_NULLPTR is defined, test will be skipped.
#else
int main()
{
return boost::core::string_view( nullptr ).size() == 0;
}
#endif

View File

@@ -0,0 +1,15 @@
// Copyright 2021 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#if !defined(_WIN32) && !defined(__CYGWIN__)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE( "Skipping test because _WIN32 and __CYGWIN__ are not defined" )
#else
#include <windows.h>
#include <boost/core/detail/string_view.hpp>
#endif

View File

@@ -13,9 +13,11 @@ class P1 {
public:
explicit P1(T* p)
: p_(p) { }
T* operator->() const BOOST_NOEXCEPT {
return p_;
}
private:
T* p_;
};
@@ -25,9 +27,11 @@ class P2 {
public:
explicit P2(T* p)
: p_(p) { }
P1<T> operator->() const BOOST_NOEXCEPT {
return p_;
}
private:
P1<T> p_;
};
@@ -38,20 +42,24 @@ class P3 {
public:
explicit P3(T* p)
: p_(p) { }
T* get() const BOOST_NOEXCEPT {
return p_;
}
private:
T* p_;
};
namespace boost {
template<class T>
struct pointer_traits<P3<T> > {
static T* to_address(const P3<T>& p) BOOST_NOEXCEPT {
return p.get();
}
};
} /* boost */
template<class T>
@@ -59,77 +67,29 @@ class P4 {
public:
explicit P4(T* p)
: p_(p) { }
T* operator->() const BOOST_NOEXCEPT {
return 0;
}
T* get() const BOOST_NOEXCEPT {
return p_;
}
private:
int* p_;
};
namespace boost {
template<class T>
struct pointer_traits<P4<T> > {
static T* to_address(const P4<T>& p) BOOST_NOEXCEPT {
return p.get();
}
};
} /* boost */
#if !defined(BOOST_NO_CXX11_POINTER_TRAITS)
template<class T>
class P5 {
public:
explicit P5(T* p)
: p_(p) { }
T* get() const BOOST_NOEXCEPT {
return p_;
}
private:
T* p_;
};
namespace std {
template<class T>
struct pointer_traits<P5<T> > {
static T* to_address(const P5<T>& p) BOOST_NOEXCEPT {
return p.get();
}
};
} /* std */
template<class T>
class P6 {
public:
explicit P6(T* p)
: p_(p) { }
T* get() const BOOST_NOEXCEPT {
return p_;
}
private:
T* p_;
};
namespace boost {
template<class T>
struct pointer_traits<P6<T> > {
static T* to_address(const P6<T>& p) BOOST_NOEXCEPT {
return p.get();
}
};
} /* boost */
namespace std {
template<class T>
struct pointer_traits<P6<T> > {
static T* to_address(const P6<T>& /*p*/) BOOST_NOEXCEPT {
return 0;
}
};
} /* std */
#endif
#endif
int main()
@@ -147,12 +107,6 @@ int main()
BOOST_TEST(boost::to_address(p3) == &i);
P4<int> p4(&i);
BOOST_TEST(boost::to_address(p4) == &i);
#if !defined(BOOST_NO_CXX11_POINTER_TRAITS)
P5<int> p5(&i);
BOOST_TEST(boost::to_address(p5) == &i);
P6<int> p6(&i);
BOOST_TEST(boost::to_address(p6) == &i);
#endif
#endif
return boost::report_errors();
}

View File

@@ -82,6 +82,11 @@ int main()
TEST(long long);
TEST(unsigned long long);
#if defined(BOOST_HAS_INT128)
TEST(__int128);
TEST(unsigned __int128);
#endif
TEST(char);
TEST(wchar_t);
#if !defined(BOOST_NO_CXX11_CHAR16_T)

View File

@@ -0,0 +1,50 @@
// Copyright 2022 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#if defined(_MSC_VER)
# pragma warning(disable: 4702) // unreachable code
# pragma warning(disable: 4530) // C++ exception handler used
# pragma warning(disable: 4577) // 'noexcept' used
#endif
#include <boost/core/verbose_terminate_handler.hpp>
#include <boost/throw_exception.hpp>
#include <exception>
#include <stdlib.h>
#if defined(_MSC_VER) && defined(_CPPLIB_VER) && defined(_DEBUG)
# include <crtdbg.h>
#endif
int main()
{
#if defined(_MSC_VER) && (_MSC_VER > 1310)
// disable message boxes on assert(), abort()
::_set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
#endif
#if defined(_MSC_VER) && defined(_CPPLIB_VER) && defined(_DEBUG)
// disable message boxes on iterator debugging violations
_CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE );
_CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDERR );
#endif
std::set_terminate( boost::core::verbose_terminate_handler );
boost::throw_with_location( std::exception() );
}
#if defined(BOOST_NO_EXCEPTIONS)
void boost::throw_exception( std::exception const& x )
{
std::fprintf( stderr, "throw_exception: %s\n\n", x.what() );
std::terminate();
}
void boost::throw_exception( std::exception const& x, boost::source_location const& )
{
std::fprintf( stderr, "throw_exception: %s\n\n", x.what() );
std::terminate();
}
#endif