1
0
forked from boostorg/core

Compare commits

..

114 Commits

Author SHA1 Message Date
Peter Dimov
3ec157eb6f Disable cmath_test_generic on msvc-8.0 2021-10-05 19:16:24 +03:00
Peter Dimov
75fc48ad32 Add a revision history section to documentation 2021-10-05 18:46:47 +03:00
Peter Dimov
6985b1ae25 Remove extra semicolons 2021-10-05 15:53:16 +03:00
Peter Dimov
8ab119135c Add overload for char8_t because Mac has no typeinfo for char8_t 2021-10-05 15:46:22 +03:00
Peter Dimov
1fd2cadddd g++ 4.4 has no string::front 2021-10-05 15:38:33 +03:00
Peter Dimov
bb0c6381f6 Add msvc workarounds 2021-10-05 08:04:01 +03:00
Peter Dimov
4f6f7c3799 Add tests for all fundamental types 2021-10-05 07:50:52 +03:00
Peter Dimov
cd1a8fd238 Support pointers to members 2021-10-05 07:25:35 +03:00
Peter Dimov
b0b48c5783 Support qualified function types 2021-10-05 07:05:34 +03:00
Peter Dimov
ccdf5ce031 Track the type suffix independently for better decomposition of functions and arrays 2021-10-05 06:45:41 +03:00
Peter Dimov
f833040d48 Disable msvc warnings around tn_is_function 2021-10-05 05:42:41 +03:00
Peter Dimov
b93317815c Apply msvc-12.0 (and below) workarounds 2021-10-05 05:30:37 +03:00
Peter Dimov
01bd23df5d Add tests for function types 2021-10-05 05:04:56 +03:00
Peter Dimov
36cec9a5cc Handle references to functions 2021-10-05 05:01:05 +03:00
Peter Dimov
5e382efa84 Fix std::ostream failure on libstdc++ 2021-10-01 15:51:13 +03:00
Peter Dimov
e260bb865d Add support for string_view 2021-10-01 15:07:19 +03:00
Peter Dimov
f884833b42 Add workaround for msvc-10.0 2021-09-30 03:21:31 +03:00
Peter Dimov
8265fe6405 Minor documentation fix 2021-09-29 21:55:40 +03:00
Peter Dimov
f7b04afe4d Add documentation for type_name 2021-09-29 21:34:23 +03:00
Peter Dimov
2c1eb07a68 Add test for scoped enums 2021-09-29 21:12:54 +03:00
Peter Dimov
a5cbddc466 Add test for enums 2021-09-29 21:09:19 +03:00
Peter Dimov
91a64b3bcf Add support for std::array 2021-09-29 21:02:39 +03:00
Peter Dimov
a039f8c318 Support -fno-rtti 2021-09-29 20:53:38 +03:00
Peter Dimov
bebb7349ba Add workarounds for msvc-12.0 and earlier 2021-09-29 20:05:23 +03:00
Peter Dimov
dc6e3261ec Use typedef instead of using 2021-09-29 19:51:16 +03:00
Peter Dimov
15a7d84858 Use basic_string<char8_t> instead of u8string 2021-09-29 19:50:14 +03:00
Peter Dimov
06023d4ffe Strip libstdc++ and libc++ inline namespaces 2021-09-29 19:34:37 +03:00
Peter Dimov
3e0bc52c32 Add <boost/core/type_name.hpp> 2021-09-29 19:13:12 +03:00
Andrey Semashev
b83f27a9e0 Another fix in git version check. 2021-09-26 20:35:37 +03:00
Andrey Semashev
578e3105b8 Fixed git version check on Mac OS. 2021-09-26 20:31:43 +03:00
Andrey Semashev
f34c4986c1 Added a timeout for GHA CI. 2021-09-15 20:45:23 +03:00
Andrey Semashev
cfd469d858 Removed unused reference to extra_tests variable in GHA config. 2021-09-15 18:27:17 +03:00
Peter Dimov
b1e01b53f3 Merge branch 'develop' into feature/cmath 2021-09-14 19:15:41 +03:00
Peter Dimov
177c093151 Automatically use generic cmath if FP_SUBNORMAL isn't defined 2021-09-14 18:57:33 +03:00
Peter Dimov
cffaabead8 Update and fix CMake test jobs 2021-09-14 18:49:03 +03:00
Peter Dimov
2715f9b5d8 Add a workaround for g++ 4.4, 4.6 2021-09-14 18:35:31 +03:00
Peter Dimov
8043bafb6b Add a generic cmath.hpp implementation, enabled when BOOST_CORE_USE_GENERIC_CMATH is defined 2021-09-14 16:50:34 +03:00
Andrey Semashev
f6bdb17fd9 Updated GitHub Actions config for better configurability.
Reworked extra package installation and added explicit specification
of external package sources. Moved some common constants to environment
variables. Removed installation of unneeded packages in the containers.
2021-09-12 18:28:02 +03:00
Andrey Semashev
cd6847aee8 Update GitHub Actions config to switch Ubuntu 16.04 jobs to Docker containers.
The Ubuntu 16.04 environment is scheduled to be removed from GitHub Actions
in September 2021. Migrate those jobs to Docker containers or Ubuntu 18.04.

Also, added some older compilers. Ported CMake tests from Travis CI.

Based on https://github.com/boostorg/core/pull/95.
Closes https://github.com/boostorg/core/pull/95.
2021-09-06 02:00:12 +03:00
Andrey Semashev
9ff312e2fb Updated README.md to refer to GitHub Actions instead of Travis. 2021-09-06 01:24:19 +03:00
Andrey Semashev
494927312d Removed Travis CI config file.
Travis CI no longer provides (adequate) service to open source projects,
so we have switched to GitHub Actions as a replacement.
2021-09-06 01:24:19 +03:00
Peter Dimov
df91243a1d Whether wchar_t is signed is implementation-defined 2021-08-21 20:28:47 +03:00
Andrey Semashev
f4b3d5dba6 Merge pull request #93 from sdarwin/feature/gha_fix
Small GHA fix, create destination dir
2021-07-27 23:53:44 +03:00
sdarwin
9f0b97c80b Small GHA fix, create destination dir 2021-07-27 13:35:51 -05:00
Andrey Semashev
ce53cc1f8f Changed quotes in format() expression. 2021-07-02 20:38:22 +03:00
Andrey Semashev
8fad14b804 Use gcc-7 toolchain for clang-8 CI job. 2021-07-02 20:35:45 +03:00
Andrey Semashev
24b6d89e7f Changed CI concurrency group format.
This should fix CI and also make concurrncy work for PRs.
2021-07-02 20:34:19 +03:00
Andrey Semashev
ffd79a28e1 Added concurrency settings to auto-cancel redundant CI jobs. 2021-07-02 20:03:50 +03:00
Andrey Semashev
aa97e418f2 Increased git fetch jobs on Windows and use CPU count for build jobs. 2021-07-02 19:33:06 +03:00
Andrey Semashev
f563d50d42 Use more git fetch jobs to speed up clones. 2021-07-02 19:19:48 +03:00
Andrey Semashev
c55a20dff2 Reverted gcc package removal and instead setup a dummy gcc toolset tree.
Removing gcc and libstdc++ packages did not fix the clang-8 test failures.

Instead, setup a dummy gcc toolset tree and point clang to it to force
the compiler detect and use an older libstdc++.
2021-07-02 19:14:04 +03:00
Andrey Semashev
bc508f8b4c Remove gcc-10 for clang-8 testing.
This is another attempt to make clang-8 tests not fail in C++20 mode. Remove
gcc-10 and libstdc++-10 to prevent clang using it.

Also, use apt-get instead of apt since the former is recommended to use in
scripts. This should silence apt warnings.
2021-07-02 16:15:59 +03:00
Andrey Semashev
03c5481dd4 Moved clang-8 to Bionic and gcc-10,11 to Focal.
clang-8 jobs fail in C++20 mode since it doesn't support
std::is_constant_evaluated, which is called from libstdc++-10 that is installed
in Focal image. Moving it back to Bionic should work around the issue
as it should use an older libstdc++ version.

gcc-10 and 11 were moved to Focal just to make this configuration tested.

Also, changed 2a to 20 for compilers that support this.
2021-07-02 11:52:44 +03:00
Andrey Semashev
8e7ee90080 Merge pull request #92 from evanmiller/develop
Restore support for ancient Mac OS
2021-07-02 01:59:50 +03:00
Evan Miller
128d9314d6 Restore support for ancient Mac OS
Mac OS 10.4 and earlier lack Availability.h, causing compilation to
fail. Rearrange the macro logic to include Availability.h only if we
already think there may be support for uncaught exceptions.
2021-07-01 16:32:40 -04:00
Peter Dimov
012d96a72b Use non-const references in non-variadic branch as well 2021-06-10 10:09:46 +03:00
Peter Dimov
27d700ec01 Use non-const references in ignore_unused to avoid g++-11 warning 2021-06-10 09:54:51 +03:00
Peter Dimov
507c182f4c Revert "Initialize variables in ignore_unused_test to avoid a g++-11 warning"
This reverts commit 1a011cde56.
2021-06-10 09:40:08 +03:00
Peter Dimov
1a011cde56 Initialize variables in ignore_unused_test to avoid a g++-11 warning 2021-06-10 08:25:28 +03:00
Peter Dimov
71c3d320d5 Update ci.yml 2021-06-10 07:20:24 +03:00
Peter Dimov
b3fa7ca565 Take care of gcc-4.4 in addition to gcc-4.4.7 2021-06-10 04:58:17 +03:00
Peter Dimov
d3aa4a2f12 Update .travis.yml 2021-06-10 04:56:26 +03:00
Peter Dimov
67107dbaf9 Update ci.yml 2021-06-10 04:22:36 +03:00
Peter Dimov
0b74f0d394 Update CMakeLists.txt 2021-06-10 02:03:10 +03:00
Peter Dimov
e53393357f Update .github/workflows 2021-04-19 18:11:37 +03:00
Peter Dimov
7daee1d41b Add -DBUILD_TESTING=ON to .yml files; it's not default anymore 2021-03-19 03:53:31 +02:00
Glen Fernandes
ddbaa242a9 Update copyright comments 2021-02-16 02:14:14 -05:00
Glen Fernandes
86bff4c2d3 Revise allocator access utilities
Now supports MSVC 2013, and no workarounds use allocator_traits.
2021-02-15 22:11:41 -05:00
Peter Dimov
2e5ecbe6f6 Add test for typeid(struct X) across libraries 2021-02-11 04:43:05 +02:00
Peter Dimov
1c43651533 Test (signed char)-1 instead of 1 2021-01-20 02:40:37 +02:00
Peter Dimov
afba04cf7f Output non-printable chars as \xXY 2021-01-20 02:38:57 +02:00
Peter Dimov
0ae16756eb Add run-fail test for BOOST_TEST_NE and character types 2021-01-20 02:04:30 +02:00
Peter Dimov
2729beab83 Print char types as numeric values (C++20 deletes these ostream overloads) 2021-01-20 01:54:37 +02:00
Peter Dimov
71d60a3fb7 Fix typos in macro names 2021-01-20 01:39:09 +02:00
Peter Dimov
2642ad4562 Add test for BOOST_TEST_EQ and character types 2021-01-20 01:10:57 +02:00
Peter Dimov
f7c1f6c6ab Merge pull request #85 from eldiener/develop
[skip ci] Add "cxxstd" json field
2021-01-20 00:28:10 +02:00
Edward Diener
10eb5cdf7c [skip ci] Add "cxxstd" json field. The "cxxstd" json field is being added to each Boost library's meta json information for libraries in order to specify the minumum C++ standard compilation level. The value of this field matches one of the values for 'cxxstd' in Boost.Build. The purpose of doing this is to provide information for the Boost website documentation for each library which will specify the minimum C++ standard compilation that an end-user must employ in order to use the particular library. This will aid end-users who want to know if they can successfully use a Boost library based on their C++ compiler's compilation level, without having to search the library's documentation to find this out. 2021-01-19 13:08:18 -05:00
Glen Fernandes
82a51aea40 Merge branch 'develop' into feature/update-travis 2020-12-31 13:54:01 -05:00
Glen Fernandes
5726534f6d Correct unit test for allocator_size_type 2020-12-31 11:41:04 -05:00
Peter Dimov
a13a82f8c1 Fix Travis configurations 2020-12-31 17:48:48 +02:00
Peter Dimov
cb94f76a5e Remove redundant configurations from Travis; add non-redundant ones 2020-12-30 20:58:04 +02:00
Peter Dimov
a6cab03127 Add documentation for bit.hpp 2020-12-30 20:34:34 +02:00
Peter Dimov
fa82b680cf Work around clang++ 3.3 failure 2020-12-30 19:40:52 +02:00
Peter Dimov
16e9536146 Implement boost::core::endian 2020-12-29 02:41:15 +02:00
Peter Dimov
919b98d425 Use __builtin_popcount 2020-12-29 02:06:56 +02:00
Peter Dimov
e8aa0c75b4 Use _BitScanForward 2020-12-29 02:02:33 +02:00
Peter Dimov
8bd2239b0b Use __builtin_ctz 2020-12-29 01:56:34 +02:00
Peter Dimov
c838ebc003 Use _BitScanReverse 2020-12-29 01:53:30 +02:00
Peter Dimov
aca46fae91 Use __builtin_clz 2020-12-29 01:28:59 +02:00
Peter Dimov
409c809cd8 Add popcount 2020-12-29 01:06:22 +02:00
Peter Dimov
dc8aa5eb39 Update test_bit_floor 2020-12-29 00:30:54 +02:00
Peter Dimov
26728848b4 Add bit_ceil 2020-12-29 00:29:44 +02:00
Peter Dimov
3e41929dfb Update bit_floor_test 2020-12-29 00:22:45 +02:00
Peter Dimov
579cb8f7f3 Add bit_floor_test 2020-12-29 00:06:25 +02:00
Peter Dimov
3b14a3677d Add has_single_bit_test 2020-12-28 23:59:58 +02:00
Peter Dimov
26991f0c75 Add bit_width_test 2020-12-28 23:52:39 +02:00
Peter Dimov
cc877e6b5b Add countl_zero, countl_one 2020-12-28 23:40:59 +02:00
Peter Dimov
123b567051 Add missing unsigned short tests to bit_rotate_test 2020-12-28 21:54:42 +02:00
Peter Dimov
a47eebf41a Add countr_zero, countr_one 2020-12-28 21:52:02 +02:00
Peter Dimov
045487ba96 Add boost/core/bit.hpp (bit_cast, rotl, rotr) 2020-12-28 21:12:22 +02:00
Peter Dimov
804c5b250d Add documentation for cmath.hpp 2020-12-24 01:20:32 +02:00
Peter Dimov
bee040b8cc Add fpclassify. 2020-12-24 00:58:56 +02:00
Peter Dimov
c307f86520 Add core/cmath.hpp 2020-12-24 00:19:20 +02:00
Peter Dimov
0364b64927 Compute LIBRARY from GITHUB_REPOSITORY 2020-12-23 06:47:00 +02:00
Peter Dimov
a04803b6cb Fix BOOST_BRANCH 2020-12-23 05:15:04 +02:00
Peter Dimov
88896d0805 Update ci.yml 2020-12-19 17:54:04 +02:00
Peter Dimov
bff4172486 Move windows.yml into ci.yml 2020-12-19 17:45:30 +02:00
Peter Dimov
ea0b1dc8a9 Rename posix.yml to ci.yml 2020-12-19 17:44:32 +02:00
Peter Dimov
3d6683edb5 Update maintainer e-mail 2020-12-12 01:01:07 +02:00
Peter Dimov
72089753f7 Add Doxygen annotation 2020-11-21 18:18:31 +02:00
Peter Dimov
156a016865 Add matrix.addrmd, toolset=gcc to windows.yml 2020-11-20 05:22:06 +02:00
Peter Dimov
0dcd164a12 Add .github/workflows 2020-11-20 04:23:22 +02:00
Peter Dimov
54671134ae Add implicit conversion between compatible reference wrappers (refs #83) 2020-11-19 18:57:56 +02:00
Peter Dimov
7bc2873e38 Update appveyor.yml 2020-11-14 22:02:03 +02:00
41 changed files with 4621 additions and 575 deletions

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

@@ -0,0 +1,509 @@
# Copyright 2020-2021 Peter Dimov
# Copyright 2021 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)
name: CI
on:
pull_request:
push:
branches:
- master
- develop
- feature/**
concurrency:
group: ${{format('{0}:{1}', github.repository, github.ref)}}
cancel-in-progress: true
env:
GIT_FETCH_JOBS: 8
NET_RETRY_COUNT: 5
DEFAULT_BUILD_VARIANT: debug,release
jobs:
posix:
defaults:
run:
shell: bash
strategy:
fail-fast: false
matrix:
include:
# Linux, gcc
- toolset: gcc-4.4
cxxstd: "98,0x"
os: ubuntu-20.04
container: ubuntu:16.04
install:
- g++-4.4
sources:
- "ppa:ubuntu-toolchain-r/test"
- toolset: gcc-4.6
cxxstd: "03,0x"
os: ubuntu-20.04
container: ubuntu:16.04
install:
- g++-4.6
sources:
- "ppa:ubuntu-toolchain-r/test"
- toolset: gcc-4.7
cxxstd: "03,11"
os: ubuntu-20.04
container: ubuntu:16.04
install:
- g++-4.7
- toolset: gcc-4.8
cxxstd: "03,11"
os: ubuntu-18.04
install:
- g++-4.8
- toolset: gcc-4.9
cxxstd: "03,11"
os: ubuntu-20.04
container: ubuntu:16.04
install:
- g++-4.9
- toolset: gcc-5
cxxstd: "03,11,14,1z"
os: ubuntu-20.04
container: ubuntu:16.04
install:
- g++-5
- toolset: gcc-6
cxxstd: "03,11,14,1z"
os: ubuntu-18.04
install:
- g++-6
- toolset: gcc-7
cxxstd: "03,11,14,17"
os: ubuntu-18.04
install:
- g++-7
- toolset: gcc-8
cxxstd: "03,11,14,17,2a"
os: ubuntu-18.04
install:
- g++-8
- toolset: gcc-9
cxxstd: "03,11,14,17,2a"
os: ubuntu-18.04
install:
- g++-9
- toolset: gcc-10
cxxstd: "03,11,14,17,20"
os: ubuntu-20.04
install:
- g++-10
- toolset: gcc-11
cxxstd: "03,11,14,17,20"
os: ubuntu-20.04
install:
- g++-11
sources:
- "ppa:ubuntu-toolchain-r/test"
- name: UBSAN
toolset: gcc-11
cxxstd: "03,11,14,17,20"
ubsan: 1
os: ubuntu-20.04
install:
- g++-11
sources:
- "ppa:ubuntu-toolchain-r/test"
# Linux, clang
- toolset: clang
compiler: clang++-3.5
cxxstd: "03,11"
os: ubuntu-20.04
container: ubuntu:16.04
install:
- clang-3.5
- toolset: clang
compiler: clang++-3.6
cxxstd: "03,11,14"
os: ubuntu-20.04
container: ubuntu:16.04
install:
- clang-3.6
- toolset: clang
compiler: clang++-3.7
cxxstd: "03,11,14"
os: ubuntu-20.04
container: ubuntu:16.04
install:
- clang-3.7
- toolset: clang
compiler: clang++-3.8
cxxstd: "03,11,14"
os: ubuntu-20.04
container: ubuntu:16.04
install:
- clang-3.8
- toolset: clang
compiler: clang++-3.9
cxxstd: "03,11,14"
os: ubuntu-18.04
install:
- clang-3.9
- toolset: clang
compiler: clang++-4.0
cxxstd: "03,11,14"
os: ubuntu-18.04
install:
- clang-4.0
- toolset: clang
compiler: clang++-5.0
cxxstd: "03,11,14,1z"
os: ubuntu-18.04
install:
- clang-5.0
- toolset: clang
compiler: clang++-6.0
cxxstd: "03,11,14,17"
os: ubuntu-18.04
install:
- clang-6.0
- toolset: clang
compiler: clang++-7
cxxstd: "03,11,14,17"
os: 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
install:
- clang-8
- g++-7
gcc_toolchain: 7
- toolset: clang
compiler: clang++-9
cxxstd: "03,11,14,17,2a"
os: ubuntu-20.04
install:
- clang-9
- toolset: clang
compiler: clang++-10
cxxstd: "03,11,14,17,20"
os: ubuntu-20.04
install:
- clang-10
- toolset: clang
compiler: clang++-11
cxxstd: "03,11,14,17,20"
os: ubuntu-20.04
install:
- clang-11
- toolset: clang
compiler: clang++-12
cxxstd: "03,11,14,17,20"
os: ubuntu-20.04
install:
- clang-12
- toolset: clang
compiler: clang++-12
cxxstd: "03,11,14,17,20"
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"
cxxflags: -stdlib=libc++
linkflags: -stdlib=libc++
ubsan: 1
os: ubuntu-20.04
install:
- clang-12
- libc++-12-dev
- libc++abi-12-dev
- toolset: clang
cxxstd: "03,11,14,17,2a"
os: macos-10.15
- name: CMake tests
cmake_tests: 1
os: ubuntu-20.04
timeout-minutes: 120
runs-on: ${{matrix.os}}
container: ${{matrix.container}}
steps:
- name: Setup environment
run: |
if [ -f "/etc/debian_version" ]
then
echo "DEBIAN_FRONTEND=noninteractive" >> $GITHUB_ENV
export DEBIAN_FRONTEND=noninteractive
fi
if [ -n "${{matrix.container}}" ]
then
echo "GHA_CONTAINER=${{matrix.container}}" >> $GITHUB_ENV
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
fi
fi
git config --global pack.threads 0
- uses: actions/checkout@v2
- name: Install packages
if: matrix.install
run: |
SOURCE_KEYS=(${{join(matrix.source_keys, ' ')}})
SOURCES=(${{join(matrix.sources, ' ')}})
for key in "${SOURCE_KEYS[@]}"
do
for i in {1..$NET_RETRY_COUNT}
do
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"
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
for source in "${SOURCES[@]}"
do
for i in {1..$NET_RETRY_COUNT}
do
APT_ADD_REPO_ARGS=("${APT_ADD_REPO_COMMON_ARGS[@]}")
if [ $APT_ADD_REPO_HAS_SOURCE_ARGS -ne 0 ]
then
case "$source" in
"ppa:"*)
APT_ADD_REPO_ARGS+=("-P")
;;
"deb "*)
APT_ADD_REPO_ARGS+=("-S")
;;
*)
APT_ADD_REPO_ARGS+=("-U")
;;
esac
fi
APT_ADD_REPO_ARGS+=("$source")
sudo -E apt-add-repository "${APT_ADD_REPO_ARGS[@]}" && break || sleep 2
done
done
fi
sudo apt-get -o Acquire::Retries=$NET_RETRY_COUNT update
sudo apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y ${{join(matrix.install, ' ')}}
- name: Setup GCC Toolchain
if: matrix.gcc_toolchain
run: |
GCC_TOOLCHAIN_ROOT="$HOME/gcc-toolchain"
echo "GCC_TOOLCHAIN_ROOT=\"$GCC_TOOLCHAIN_ROOT\"" >> $GITHUB_ENV
MULTIARCH_TRIPLET="$(dpkg-architecture -qDEB_HOST_MULTIARCH)"
mkdir -p "$GCC_TOOLCHAIN_ROOT"
ln -s /usr/include "$GCC_TOOLCHAIN_ROOT/include"
ln -s /usr/bin "$GCC_TOOLCHAIN_ROOT/bin"
mkdir -p "$GCC_TOOLCHAIN_ROOT/lib/gcc/$MULTIARCH_TRIPLET"
ln -s "/usr/lib/gcc/$MULTIARCH_TRIPLET/${{matrix.gcc_toolchain}}" "$GCC_TOOLCHAIN_ROOT/lib/gcc/$MULTIARCH_TRIPLET/${{matrix.gcc_toolchain}}"
- 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
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" ]
then
if $(dpkg --compare-versions "$GIT_VERSION" lt 2.8.0)
then
GIT_HAS_JOBS=0
fi
else
declare -a GIT_VER=(${GIT_VERSION//./ })
declare -a GIT_MIN_VER=(2 8 0)
for ((i=0; i<${#GIT_VER[@]}; i++))
do
if [ -z "${GIT_MIN_VER[i]}" ]
then
GIT_MIN_VER[i]=0
fi
if [ "${GIT_VER[i]}" -lt "${GIT_MIN_VER[i]}" ]
then
GIT_HAS_JOBS=0
break
fi
done
fi
if [ "$GIT_HAS_JOBS" -ne 0 ]
then
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 update --init tools/boostdep
DEPINST_ARGS+=("$LIBRARY")
python tools/boostdep/depinst/depinst.py "${DEPINST_ARGS[@]}"
if [ -z "${{matrix.cmake_tests}}" ]
then
./bootstrap.sh
./b2 headers
if [ -n "${{matrix.compiler}}" -o -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
fi
fi
- name: Run tests
if: matrix.cmake_tests == ''
run: |
cd ../boost-root
B2_ARGS=("-j" "$BUILD_JOBS" "toolset=${{matrix.toolset}}" "cxxstd=${{matrix.cxxstd}}")
if [ -n "${{matrix.build_variant}}" ]
then
B2_ARGS+=("variant=${{matrix.build_variant}}")
else
B2_ARGS+=("variant=$DEFAULT_BUILD_VARIANT")
fi
if [ -n "${{matrix.threading}}" ]
then
B2_ARGS+=("threading=${{matrix.threading}}")
fi
if [ -n "${{matrix.ubsan}}" ]
then
export UBSAN_OPTIONS="print_stacktrace=1"
B2_ARGS+=("cxxflags=-fsanitize=undefined -fno-sanitize-recover=undefined" "linkflags=-fsanitize=undefined -fuse-ld=gold" "define=UBSAN=1" "debug-symbols=on" "visibility=global")
fi
if [ -n "${{matrix.cxxflags}}" ]
then
B2_ARGS+=("cxxflags=${{matrix.cxxflags}}")
fi
if [ -n "${{matrix.linkflags}}" ]
then
B2_ARGS+=("linkflags=${{matrix.linkflags}}")
fi
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"
addrmd: 32,64
os: windows-2016
- toolset: msvc-14.2
cxxstd: "14,17,latest"
addrmd: 32,64
os: windows-2019
- toolset: gcc
cxxstd: "03,11,14,17,2a"
addrmd: 64
os: windows-2019
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v2
- name: Setup Boost
shell: cmd
run: |
echo GITHUB_REPOSITORY: %GITHUB_REPOSITORY%
for /f %%i in ("%GITHUB_REPOSITORY%") do set LIBRARY=%%~nxi
echo LIBRARY: %LIBRARY%
echo LIBRARY=%LIBRARY%>>%GITHUB_ENV%
echo GITHUB_BASE_REF: %GITHUB_BASE_REF%
echo GITHUB_REF: %GITHUB_REF%
if "%GITHUB_BASE_REF%" == "" set GITHUB_BASE_REF=%GITHUB_REF%
set BOOST_BRANCH=develop
for /f %%i in ("%GITHUB_BASE_REF%") do if "%%~nxi" == "master" set BOOST_BRANCH=master
echo BOOST_BRANCH: %BOOST_BRANCH%
cd ..
git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
xcopy /s /e /q %GITHUB_WORKSPACE% libs\%LIBRARY%\
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py --git_args "--jobs %GIT_FETCH_JOBS%" %LIBRARY%
cmd /c bootstrap
b2 -d0 headers
- name: Run tests
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

View File

@@ -1,412 +0,0 @@
# Copyright 2016-2019 Peter Dimov
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
language: cpp
dist: xenial
branches:
only:
- master
- develop
- /feature\/.*/
env:
matrix:
- BOGUS_JOB=true
matrix:
exclude:
- env: BOGUS_JOB=true
include:
- os: linux
compiler: g++
env: TOOLSET=gcc COMPILER=g++ CXXSTD=03,11
- os: linux
compiler: g++-4.4
env: TOOLSET=gcc COMPILER=g++-4.4 CXXSTD=98,0x
addons:
apt:
packages:
- g++-4.4
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-4.6
env: TOOLSET=gcc COMPILER=g++-4.6 CXXSTD=03,0x
addons:
apt:
packages:
- g++-4.6
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-4.7
env: TOOLSET=gcc COMPILER=g++-4.7 CXXSTD=03,11
addons:
apt:
packages:
- g++-4.7
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-4.8
env: TOOLSET=gcc COMPILER=g++-4.8 CXXSTD=03,11
addons:
apt:
packages:
- g++-4.8
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-4.9
env: TOOLSET=gcc COMPILER=g++-4.9 CXXSTD=03,11
addons:
apt:
packages:
- g++-4.9
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-5
env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- g++-5
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-6
env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- g++-6
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-7
env: TOOLSET=gcc COMPILER=g++-7 CXXSTD=03,11,14,17
addons:
apt:
packages:
- g++-7
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-8
env: TOOLSET=gcc COMPILER=g++-8 CXXSTD=03,11,14,17
addons:
apt:
packages:
- g++-8
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-9
env: TOOLSET=gcc COMPILER=g++-9 CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
- g++-9
sources:
- ubuntu-toolchain-r-test
- os: linux
dist: bionic
compiler: g++-10
env: TOOLSET=gcc COMPILER=g++-10 CXXSTD=03,11,14,17,20
addons:
apt:
packages:
- g++-10
sources:
- sourceline: "ppa:ubuntu-toolchain-r/test"
- os: linux
dist: bionic
compiler: g++-10
env: UBSAN=1 TOOLSET=gcc COMPILER=g++-10 CXXSTD=03,11,14,17,20 UBSAN_OPTIONS=print_stacktrace=1 LINKFLAGS=-fuse-ld=gold
addons:
apt:
packages:
- g++-10
sources:
- sourceline: "ppa:ubuntu-toolchain-r/test"
- os: linux
compiler: clang++
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11
- os: linux
dist: trusty
compiler: /usr/bin/clang++
env: TOOLSET=clang COMPILER=/usr/bin/clang++ CXXSTD=03,11
addons:
apt:
packages:
- clang-3.3
- os: linux
dist: trusty
compiler: /usr/bin/clang++
env: TOOLSET=clang COMPILER=/usr/bin/clang++ CXXSTD=03,11
addons:
apt:
packages:
- clang-3.4
- os: linux
dist: trusty
compiler: clang++-3.5
env: TOOLSET=clang COMPILER=clang++-3.5 CXXSTD=03,11
addons:
apt:
packages:
- clang-3.5
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++-3.6
env: TOOLSET=clang COMPILER=clang++-3.6 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-3.6
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++-3.7
env: TOOLSET=clang COMPILER=clang++-3.7 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-3.7
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++-3.8
env: TOOLSET=clang COMPILER=clang++-3.8 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-3.8
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++-3.9
env: TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-3.9
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++-4.0
env: TOOLSET=clang COMPILER=clang++-4.0 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-4.0
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++-5.0
env: TOOLSET=clang COMPILER=clang++-5.0 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-5.0
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++-6.0
env: TOOLSET=clang COMPILER=clang++-6.0 CXXSTD=03,11,14,17
addons:
apt:
packages:
- clang-6.0
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++-7
env: TOOLSET=clang COMPILER=clang++-7 CXXSTD=03,11,14,17
addons:
apt:
packages:
- clang-7
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-xenial-7
- os: linux
compiler: clang++-8
env: TOOLSET=clang COMPILER=clang++-8 CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
- clang-8
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-xenial-8
- os: linux
compiler: clang++-9
env: TOOLSET=clang COMPILER=clang++-9 CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
- clang-9
sources:
- ubuntu-toolchain-r-test
- sourceline: 'deb https://apt.llvm.org/xenial/ llvm-toolchain-xenial-9 main'
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
- os: linux
compiler: clang++-10
env: TOOLSET=clang COMPILER=clang++-10 CXXSTD=03,11,14,17,20
addons:
apt:
packages:
- clang-10
sources:
- ubuntu-toolchain-r-test
- sourceline: 'deb https://apt.llvm.org/xenial/ llvm-toolchain-xenial-10 main'
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
- os: linux
compiler: clang++-10
env: UBSAN=1 TOOLSET=clang COMPILER=clang++-10 CXXSTD=03,11,14,17,20 UBSAN_OPTIONS=print_stacktrace=1
addons:
apt:
packages:
- clang-10
sources:
- ubuntu-toolchain-r-test
- sourceline: 'deb https://apt.llvm.org/xenial/ llvm-toolchain-xenial-10 main'
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
- os: linux
dist: trusty
compiler: clang++-libc++
env: TOOLSET=clang COMPILER=clang++-libc++ CXXSTD=03,11,14,1z
addons:
apt:
packages:
- libc++-dev
- libc++abi-dev
- os: linux
dist: trusty
compiler: clang++-libc++
env: UBSAN=1 TOOLSET=clang COMPILER=clang++-libc++ CXXSTD=03,11,14,1z UBSAN_OPTIONS=print_stacktrace=1
addons:
apt:
packages:
- libc++-dev
- libc++abi-dev
- os: osx
compiler: clang++
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z
osx_image: xcode7.3
- os: osx
compiler: clang++
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z
osx_image: xcode8.3
- os: osx
compiler: clang++
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z
osx_image: xcode9.4
- os: osx
compiler: clang++
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z
osx_image: xcode10.1
- os: linux
env: CMAKE_TEST=1
script:
- mkdir __build__ && cd __build__
- cmake -DBOOST_ENABLE_CMAKE=1 -DBoost_VERBOSE=1 -DBOOST_INCLUDE_LIBRARIES=core ..
- ctest --output-on-failure -R boost_core
- os: linux
env: CMAKE_SUBDIR_TEST=1
install:
- BOOST_BRANCH=develop
- if [ "$TRAVIS_BRANCH" = "master" ]; then BOOST_BRANCH=master; fi
- git clone -b $BOOST_BRANCH https://github.com/boostorg/config.git ../config
- git clone -b $BOOST_BRANCH https://github.com/boostorg/assert.git ../assert
script:
- cd test/cmake_subdir_test && mkdir __build__ && cd __build__
- cmake ..
- cmake --build .
- cmake --build . --target check
- os: linux
env: CMAKE_INSTALL_TEST=1
script:
- mkdir __build__ && cd __build__
- cmake -DBOOST_ENABLE_CMAKE=1 -DBoost_VERBOSE=1 -DBOOST_INCLUDE_LIBRARIES="assert;config;core" -DCMAKE_INSTALL_PREFIX=~/.local ..
- cmake --build . --target install
- cd ../libs/core/test/cmake_install_test && mkdir __build__ && cd __build__
- cmake -DCMAKE_INSTALL_PREFIX=~/.local ..
- cmake --build .
- cmake --build . --target check
install:
- BOOST_BRANCH=develop
- if [ "$TRAVIS_BRANCH" = "master" ]; then BOOST_BRANCH=master; fi
- 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 init tools/cmake
- git submodule update --jobs 4
- cp -r $TRAVIS_BUILD_DIR/* libs/core
- ./bootstrap.sh
- ./b2 headers
script:
- |-
echo "using $TOOLSET : : $COMPILER ;" > ~/user-config.jam
- BUILD_JOBS=`(nproc || sysctl -n hw.ncpu) 2> /dev/null`
- ./b2 -j $BUILD_JOBS libs/core/test toolset=$TOOLSET cxxstd=$CXXSTD variant=debug,release ${UBSAN:+cxxflags=-fsanitize=undefined cxxflags=-fno-sanitize-recover=undefined linkflags=-fsanitize=undefined define=UBSAN=1 debug-symbols=on} ${LINKFLAGS:+linkflags=$LINKFLAGS}
notifications:
email:
on_success: always

View File

@@ -17,13 +17,6 @@ target_link_libraries(boost_core
Boost::config
)
if(BOOST_SUPERPROJECT_VERSION)
include(BoostInstall)
boost_install(TARGETS boost_core HEADER_DIRECTORY include/)
endif()
if(BUILD_TESTING)
add_subdirectory(test)

View File

@@ -8,12 +8,12 @@ The criteria for inclusion is that the utility component be:
* used by other Boost libraries, and
* not dependent on any other Boost modules except Core itself, Config, Assert, Static Assert, or Predef.
### CI Status
### Build Status
Branch | Travis | Appveyor
---------|--------|---------
Develop | [![Build Status](https://travis-ci.org/boostorg/core.svg?branch=develop)](https://travis-ci.org/boostorg/core) | [![Build Status](https://ci.appveyor.com/api/projects/status/github/boostorg/core?branch=develop&svg=true)](https://ci.appveyor.com/project/pdimov/core)
Master | [![Build Status](https://travis-ci.org/boostorg/core.svg?branch=master)](https://travis-ci.org/boostorg/core) | [![Build Status](https://ci.appveyor.com/api/projects/status/github/boostorg/core?branch=master&svg=true)](https://ci.appveyor.com/project/pdimov/core)
Branch | GitHub Actions | AppVeyor | Test Matrix | Dependencies |
---------|----------------|--------- | ----------- | ------------ |
Develop | [![GitHub Actions](https://github.com/boostorg/core/actions/workflows/ci.yml/badge.svg?branch=develop)](https://github.com/boostorg/filesystem/actions?query=branch%3Adevelop) | [![AppVeyor](https://ci.appveyor.com/api/projects/status/github/boostorg/core?branch=develop&svg=true)](https://ci.appveyor.com/project/pdimov/core) | [![Tests](https://img.shields.io/badge/matrix-develop-brightgreen.svg)](http://www.boost.org/development/tests/develop/developer/core.html) | [![Dependencies](https://img.shields.io/badge/deps-develop-brightgreen.svg)](https://pdimov.github.io/boostdep-report/develop/core.html)
Master | [![GitHub Actions](https://github.com/boostorg/core/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/boostorg/filesystem/actions?query=branch%3Amaster) | [![AppVeyor](https://ci.appveyor.com/api/projects/status/github/boostorg/core?branch=master&svg=true)](https://ci.appveyor.com/project/pdimov/core) | [![Tests](https://img.shields.io/badge/matrix-master-brightgreen.svg)](http://www.boost.org/development/tests/master/developer/core.html) | [![Dependencies](https://img.shields.io/badge/deps-master-brightgreen.svg)](https://pdimov.github.io/boostdep-report/master/core.html)
### Directories

View File

@@ -16,6 +16,7 @@ environment:
matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
TOOLSET: msvc-9.0,msvc-10.0,msvc-11.0
ADDRMD: 32
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
TOOLSET: msvc-12.0,msvc-14.0
@@ -36,7 +37,7 @@ environment:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
TOOLSET: msvc-14.2
ADDRMD: 32,64
CXXSTD: 14,17
CXXSTD: 14,17,latest
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
ADDPATH: C:\cygwin\bin;

203
doc/bit.qbk Normal file
View File

@@ -0,0 +1,203 @@
[/
Copyright 2020 Peter Dimov
Distributed under the Boost Software License, Version 1.0.
See accompanying file LICENSE_1_0.txt
or copy at http://boost.org/LICENSE_1_0.txt
]
[section:bit bit]
[simplesect Authors]
* Peter Dimov
[endsimplesect]
[section Header <boost/core/bit.hpp>]
The header `<boost/core/bit.hpp>` implements, in a portable way,
the C++20 `<bit>` header.
[section Synopsis]
``
namespace boost
{
namespace core
{
// bit_cast
template<class To, class From>
To bit_cast(From const& from) noexcept;
// Integral powers of 2
template<class T>
constexpr bool has_single_bit(T x) noexcept;
template<class T>
constexpr T bit_ceil(T x) noexcept;
template<class T>
constexpr T bit_floor(T x) noexcept;
template<class T>
constexpr T bit_width(T x) noexcept;
// Rotating
template<class T>
constexpr T rotl(T x, int s) noexcept;
template<class T>
constexpr T rotr(T x, int s) noexcept;
// Counting
template<class T>
constexpr int countl_zero(T x) noexcept;
template<class T>
constexpr int countl_one(T x) noexcept;
template<class T>
constexpr int countr_zero(T x) noexcept;
template<class T>
constexpr int countr_one(T x) noexcept;
template<class T>
constexpr int popcount(T x) noexcept;
// Endian
enum class endian
{
little = see below,
big = see below,
native = see below
};
using endian_type = endian; // portable alias for C++03 code
} // namespace core
} // namespace boost
``
Note: even though the functions are shown as `constexpr` in the synopsis, since they are implemented
via compiler-specific intrinsics, portable code cannot generally rely on their being usable in a
constant expression context.
[endsect]
[section bit_cast]
`template<class To, class From> To bit_cast(From const& from) noexcept;`
* *Requires:* `To` and `From` must be trivially copyable and `sizeof(To)` must be the same as `sizeof(From)`.
* *Returns:* A value of type `To` with the storage bytes copied from `from`.
[endsect]
[section Integral powers of 2]
`template<class T> constexpr bool has_single_bit(T x) noexcept;`
* *Requires:* `T` must be an unsigned integer type (i.e. one of `unsigned char`, `unsigned short`, `unsigned int`, `unsigned long`, `unsigned long long`).
* *Returns:* `true` if `x` is an integral power of two, `false` otherwise. (`has_single_bit(0u)` is false.)
`template<class T> constexpr T bit_ceil(T x) noexcept;`
* *Requires:* `T` must be an unsigned integer type.
* *Returns:* The smallest integral power of 2 greater than or equal to `x`. If this value is not representable in `T`, behavior is undefined.
`template<class T> constexpr T bit_floor(T x) noexcept;`
* *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;`
* *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.
[endsect]
[section Rotating]
In the following descriptions, `N` denotes `numeric_limits<T>::digits` and `r` denotes `s % N`.
`template<class T> constexpr T rotl(T x, int s) noexcept;`
* *Requires:* `T` must be an unsigned integer type.
* *Returns:* If `s` is negative, `rotr(x, -s)`; if `r` is 0, `x`; if `r` is positive, `(x << r) | (x >> (N - r))`.
`template<class T> constexpr T rotr(T x, int s) noexcept;`
* *Requires:* `T` must be an unsigned integer type.
* *Returns:* If `s` is negative, `rotl(x, -s)`; if `r` is 0, `x`; if `r` is positive, `(x >> r) | (x << (N - r))`.
[endsect]
[section Counting]
`template<class T> constexpr int countl_zero(T x) noexcept;`
* *Requires:* `T` must be an unsigned integer type.
* *Returns:* The number of consecutive 0 bits in the value of `x`, starting from the most significant ("left") bit.
`template<class T> constexpr int countl_one(T x) noexcept;`
* *Requires:* `T` must be an unsigned integer type.
* *Returns:* The number of consecutive 1 bits in the value of `x`, starting from the most significant bit.
`template<class T> constexpr int countr_zero(T x) noexcept;`
* *Requires:* `T` must be an unsigned integer type.
* *Returns:* The number of consecutive 0 bits in the value of `x`, starting from the least significant ("right") bit.
`template<class T> constexpr int countr_one(T x) noexcept;`
* *Requires:* `T` must be an unsigned integer type.
* *Returns:* The number of consecutive 1 bits in the value of `x`, starting from the least significant bit.
`template<class T> constexpr int popcount(T x) noexcept;`
* *Requires:* `T` must be an unsigned integer type.
* *Returns:* The number of 1 bits in the value of `x`.
[endsect]
[section Endian]
Under C++11, `endian` is defined as `enum class endian` as shown in the synopsis. Under C++03, its definition is
``
namespace endian
{
enum type
{
little = see below,
big = see below,
native = see below
};
}
typedef endian::type endian_type;
``
The values of `endian::big` and `endian::little` are distinct. `endian::native` is equal to `endian::big` on
big endian platforms, equal to `endian::little` on little endian platforms, and a distinct value on platforms
that are neither.
Note that you should not rely on `little` and `big` having any specific values, because the C++20 standard
leaves these unspecified.
[endsect]
[endsect]
[endsect]

88
doc/changes.qbk Normal file
View File

@@ -0,0 +1,88 @@
[/
Copyright 2021 Peter Dimov
Distributed under the Boost Software License, Version 1.0.
https://boost.org/LICENSE_1_0.txt)
]
[section Revision History]
[section Changes in 1.78.0]
* Added a generic implementation to `boost/core/cmath.hpp`, enabled when `BOOST_CORE_USE_GENERIC_CMATH`
is defined or when the platform does not provide the necessary facilities in `<cmath>`.
* Added `boost::core::type_name`.
[endsect]
[section Changes in 1.77.0]
* `boost/core/uncaught_exceptions.hpp` has been modified for compatibility with Mac OS 10.4 and older.
[endsect]
[section Changes in 1.76.0]
* Add implicit conversion between compatible reference wrappers.
* Add `boost/core/cmath.hpp`, a portable implementation of the floating point classification functions from `<cmath>`.
* Add `boost/core/bit.hpp`, a portable implementation of the C++20 standard header `<bit>`.
* Fix `BOOST_TEST_EQ`, `BOOST_TEST_NE` for character types under C++20.
* Revise allocator access utilities (now support VS2013, and no workarounds use `allocator_traits`.)
[endsect]
[section Changes in 1.74.0]
* Implemented the allocator access utilities which provide a replacement for `allocator_traits`
with individual traits and functions for each facility. They support the C++11 allocator model
when possible and provide a fallback for C++98 compatibility.
[endsect]
[section Changes in 1.71.0]
* Added functions `alloc_construct`, `alloc_construct_n`, `alloc_destroy`, and `alloc_destroy_n`
in `<boost/core/alloc_construct.hpp>` for allocator aware and exception safe construction and
destruction of objects and arrays.
* Added constexpr functions `first_scalar` in `<boost/core/first_scalar.hpp>` for obtaining a pointer
to the first scalar element of an array. Given a pointer of type `T*` they return a pointer of type
`remove_all_extents_t<T>*`.
* Added class template `noinit_adaptor` in `<boost/core/noinit_adaptor.hpp>` which is an allocator adaptor
that converts any allocator into one whose `construct(ptr)` performs default initialization via placement
`new`, and whose `destroy(ptr)` invokes the `value_type` destructor directly.
* Added class template `default_allocator` in `<boost/core/default_allocator.hpp>`, which can serve as a minimal
default allocator that has interface similar to C++20 `std::allocator`, supports configurations with disabled
exceptions and does not have `std` as an associated namespace. The allocator uses `operator new` and
`operator delete` for allocation.
* In `<boost/core/uncaught_exceptions.hpp>` header, added workarounds for better compatibility with QNX SDP 7.0
when libc++/libc++abi libraries are used.
* The `<boost/detail/sp_typeinfo.hpp>` header is now marked as deprecated and will be removed in a future release.
`<boost/core/typeinfo.hpp>` should be used instead.
[endsect]
[section Changes in 1.69.0]
* Implemented `boost::empty_value`, for library authors to conveniently leverage the Empty Base Optimization to
store objects of potentially empty types.
* Implemented `boost::quick_exit` to provide the C++11 standard library facility `std::quick_exit` functionality.
* Reduced the number of statics in Lightweight Test, and employ lighter abort behavior for MSVC compilers upon
failure to call `boost::report_errors`.
[endsect]
[section Changes in 1.67.0]
* Updated `to_address` and `pointer_traits` to reflect the design adopted for C++20 in
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0653r2.html P0653R2].
[endsect]
[section Changes in 1.65.0]
* Implemented `pointer_traits` for C++03 and higher, that implements
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0653r0.html P0653r0].
* Added `BOOST_TEST_GT` and `BOOST_TEST_GE` to Lightweight Test.
[endsect]
[endsect]

122
doc/cmath.qbk Normal file
View File

@@ -0,0 +1,122 @@
[/
Copyright 2018 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
]
[section:cmath cmath]
[simplesect Authors]
* Peter Dimov
[endsimplesect]
[section Header <boost/core/cmath.hpp>]
The header `<boost/core/cmath.hpp>` defines, in a portable way, the floating
point classification and sign manipulation functions from C++11.
[section Synopsis]
``
namespace boost
{
namespace core
{
// fpclassify return values
int const fp_zero = /*unspecified*/;
int const fp_subnormal = /*unspecified*/;
int const fp_normal = /*unspecified*/;
int const fp_infinite = /*unspecified*/;
int const fp_nan = /*unspecified*/;
// Classification functions
template<class T> bool isfinite( T x );
template<class T> bool isnan( T x );
template<class T> bool isinf( T x );
template<class T> bool isnormal( T x );
template<class T> int fpclassify( T x );
// Sign manipulation functions
template<class T> bool signbit( T x );
template<class T> T copysign( T x, T y );
} // namespace core
} // namespace boost
``
[endsect]
[section Classification Functions]
[section template<class T> bool isfinite( T x );]
* *Requires:* `T` must be `float`, `double`, or `long double`.
* *Returns:* `true` when `x` is finite (not infinity or NaN), `false` otherwise.
[endsect]
[section template<class T> bool isnan( T x );]
* *Requires:* `T` must be `float`, `double`, or `long double`.
* *Returns:* `true` when `x` is NaN, `false` otherwise.
[endsect]
[section template<class T> bool isinf( T x );]
* *Requires:* `T` must be `float`, `double`, or `long double`.
* *Returns:* `true` when `x` is infinity, `false` otherwise.
[endsect]
[section template<class T> bool isnormal( T x );]
* *Requires:* `T` must be `float`, `double`, or `long double`.
* *Returns:* `true` when `x` is a normal number (not zero, subnormal, infinity, or NaN), `false` otherwise.
[endsect]
[section template<class T> int fpclassify( T x );]
* *Requires:* `T` must be `float`, `double`, or `long double`.
* *Returns:*
* `fp_zero` when `x` is zero;
* `fp_subnormal` when `x` is subnormal;
* `fp_infinite` when `x` is infinity;
* `fp_nan` when `x` is NaN;
* `fp_normal` otherwise.
[endsect]
[endsect]
[section Sign Manipulation Functions]
[section template<class T> bool signbit( T x );]
* *Requires:* `T` must be `float`, `double`, or `long double`.
* *Returns:* `true` when `x` is negative, `false` otherwise.
[endsect]
[section template<class T> bool copysign( T x, T y );]
* *Requires:* `T` must be `float`, `double`, or `long double`.
* *Returns:* `x` with the sign copied from `y`.
[endsect]
[endsect]
[endsect]
[endsect]

View File

@@ -38,10 +38,14 @@ criteria for inclusion is that the utility component be:
[endsect]
[include changes.qbk]
[include addressof.qbk]
[include allocator_access.qbk]
[include alloc_construct.qbk]
[include bit.qbk]
[include checked_delete.qbk]
[include cmath.qbk]
[include default_allocator.qbk]
[include demangle.qbk]
[include empty_value.qbk]
@@ -63,5 +67,6 @@ criteria for inclusion is that the utility component be:
[include scoped_enum.qbk]
[include swap.qbk]
[include typeinfo.qbk]
[include type_name.qbk]
[include uncaught_exceptions.qbk]
[include use_default.qbk]

77
doc/type_name.qbk Normal file
View File

@@ -0,0 +1,77 @@
[/
Copyright 2021 Peter Dimov
Distributed under the Boost Software License, Version 1.0.
https://boost.org/LICENSE_1_0.txt
]
[section:type_name type_name]
[simplesect Authors]
* Peter Dimov
[endsimplesect]
[section Header <boost/core/type_name.hpp>]
The header `<boost/core/type_name.hpp>` defines the function
template `boost::core::type_name<T>()` that returns a string
representation of the name of `T`, suitable for logging or
diagnostic display purposes.
The result is similar to `boost::core::demangle( typeid(T).name() )`,
but it's made more regular by eliminating some of the platform-specific
differences and extra template parameters of the standard library
container types.
For example, `type_name< std::map<std::string, int> >()` returns
`"std::map<std::string, int>"` and not
```
std::map<std::__cxx11::basic_string<char, std::char_traits<char>,
std::allocator<char> >, int, std::less<std::__cxx11::basic_string<char,
std::char_traits<char>, std::allocator<char> > >, std::allocator<
std::pair<std::__cxx11::basic_string<char, std::char_traits<char>,
std::allocator<char> > const, int> > >
```
or
```
class std::map<class std::basic_string<char,struct std::char_traits<char>,
class std::allocator<char> >,int,struct std::less<class std::basic_string<
char,struct std::char_traits<char>,class std::allocator<char> > >,class
std::allocator<struct std::pair<class std::basic_string<char,struct
std::char_traits<char>,class std::allocator<char> > const ,int> > >
```
The return values aren't guaranteed to be stable across Boost releases.
Compilation with `-fno-rtti` is supported, but the returned type names aren't
guaranteed to be particularly useful or unique.
[section Synopsis]
``
namespace boost
{
namespace core
{
template<class T> std::string type_name();
} // namespace core
} // namespace boost
``
[endsect]
[section template<class T> std::string type_name();]
* *Returns:* A string representation of the name of `T`.
[endsect]
[endsect]
[endsect]

View File

@@ -1,5 +1,5 @@
/*
Copyright 2020 Glen Joseph Fernandes
Copyright 2020-2021 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
@@ -11,11 +11,7 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/config.hpp>
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
#include <boost/core/pointer_traits.hpp>
#if !defined(BOOST_MSVC)
#include <limits>
#else
#include <memory>
#endif
#include <type_traits>
#endif
#include <new>
@@ -23,21 +19,18 @@ Distributed under the Boost Software License, Version 1.0.
#include <utility>
#endif
namespace boost {
namespace detail {
#if defined(BOOST_NO_CXX11_ALLOCATOR)
struct alloc_false {
BOOST_STATIC_CONSTEXPR bool value = false;
};
#else
template<class>
struct alloc_void {
typedef void type;
};
#if defined(_LIBCPP_SUPPRESS_DEPRECATED_PUSH)
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
#endif
#if defined(_STL_DISABLE_DEPRECATED_WARNING)
_STL_DISABLE_DEPRECATED_WARNING
#endif
#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable:4996)
#endif
} /* detail */
namespace boost {
template<class A>
struct allocator_value_type {
@@ -49,17 +42,21 @@ template<class A>
struct allocator_pointer {
typedef typename A::pointer type;
};
#elif defined(BOOST_MSVC)
template<class A>
struct allocator_pointer {
typedef typename std::allocator_traits<A>::pointer type;
};
#else
template<class A, class = void>
struct allocator_pointer {
typedef typename A::value_type* type;
};
namespace detail {
template<class>
struct alloc_void {
typedef void type;
};
} /* detail */
template<class A>
struct allocator_pointer<A,
typename detail::alloc_void<typename A::pointer>::type> {
@@ -72,11 +69,6 @@ template<class A>
struct allocator_const_pointer {
typedef typename A::const_pointer type;
};
#elif defined(BOOST_MSVC)
template<class A>
struct allocator_const_pointer {
typedef typename std::allocator_traits<A>::const_pointer type;
};
#else
template<class A, class = void>
struct allocator_const_pointer {
@@ -137,11 +129,6 @@ template<class A>
struct allocator_difference_type {
typedef typename A::difference_type type;
};
#elif defined(BOOST_MSVC)
template<class A>
struct allocator_difference_type {
typedef typename std::allocator_traits<A>::difference_type type;
};
#else
template<class A, class = void>
struct allocator_difference_type {
@@ -161,11 +148,6 @@ template<class A>
struct allocator_size_type {
typedef typename A::size_type type;
};
#elif defined(BOOST_MSVC)
template<class A>
struct allocator_size_type {
typedef typename std::allocator_traits<A>::size_type type;
};
#else
template<class A, class = void>
struct allocator_size_type {
@@ -181,6 +163,14 @@ struct allocator_size_type<A,
#endif
#if defined(BOOST_NO_CXX11_ALLOCATOR)
namespace detail {
struct alloc_false {
BOOST_STATIC_CONSTEXPR bool value = false;
};
} /* detail */
template<class A>
struct allocator_propagate_on_container_copy_assignment {
typedef detail::alloc_false type;
@@ -260,11 +250,6 @@ template<class A, class T>
struct allocator_rebind {
typedef typename A::template rebind<T>::other type;
};
#elif defined(BOOST_MSVC)
template<class A, class T>
struct allocator_rebind {
typedef typename std::allocator_traits<A>::template rebind_alloc<T> type;
};
#else
namespace detail {
@@ -313,36 +298,31 @@ allocator_allocate(A& a, typename allocator_size_type<A>::type n,
{
return a.allocate(n, h);
}
#elif defined(BOOST_MSVC)
template<class A>
inline typename allocator_pointer<A>::type
allocator_allocate(A& a, typename allocator_size_type<A>::type n,
typename allocator_const_void_pointer<A>::type h)
{
return std::allocator_traits<A>::allocate(a, n, h);
}
#else
namespace detail {
template<class, class, class, class = void>
struct alloc_has_allocate {
BOOST_STATIC_CONSTEXPR bool value = false;
};
struct alloc_none { };
template<class A, class N, class H>
struct alloc_has_allocate<A, N, H,
typename alloc_void<decltype(std::declval<A&>().allocate(std::declval<N>(),
std::declval<H>()))>::type> {
BOOST_STATIC_CONSTEXPR bool value = true;
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>()));
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>
inline typename std::enable_if<detail::alloc_has_allocate<A,
typename allocator_size_type<A>::type,
typename allocator_const_void_pointer<A>::type>::value,
typename allocator_pointer<A>::type>::type
inline typename std::enable_if<detail::alloc_has_allocate<A>::value,
typename allocator_pointer<A>::type>::type
allocator_allocate(A& a, typename allocator_size_type<A>::type n,
typename allocator_const_void_pointer<A>::type h)
{
@@ -350,10 +330,8 @@ allocator_allocate(A& a, typename allocator_size_type<A>::type n,
}
template<class A>
inline typename std::enable_if<!detail::alloc_has_allocate<A,
typename allocator_size_type<A>::type,
typename allocator_const_void_pointer<A>::type>::value,
typename allocator_pointer<A>::type>::type
inline typename std::enable_if<!detail::alloc_has_allocate<A>::value,
typename allocator_pointer<A>::type>::type
allocator_allocate(A& a, typename allocator_size_type<A>::type n,
typename allocator_const_void_pointer<A>::type)
{
@@ -400,32 +378,28 @@ allocator_construct(A&, T* p, V& v)
::new((void*)p) T(v);
}
#endif
#elif defined(BOOST_MSVC)
template<class A, class T, class... Args>
inline void
allocator_construct(A& a, T* p, Args&&... args)
{
std::allocator_traits<A>::construct(a, p, std::forward<Args>(args)...);
}
#else
namespace detail {
template<class, class, class, class...>
struct alloc_has_construct {
BOOST_STATIC_CONSTEXPR bool value = false;
};
template<class A, class T, class... Args>
struct alloc_has_construct<typename alloc_void<decltype(std::declval<A
&>().construct(std::declval<T*>(), std::declval<Args&&>()...))>::type,
A, T, Args...> {
BOOST_STATIC_CONSTEXPR bool value = true;
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<void, A, T,
inline typename std::enable_if<detail::alloc_has_construct<A, T,
Args...>::value>::type
allocator_construct(A& a, T* p, Args&&... args)
{
@@ -433,7 +407,7 @@ allocator_construct(A& a, T* p, Args&&... args)
}
template<class A, class T, class... Args>
inline typename std::enable_if<!detail::alloc_has_construct<void, A, T,
inline typename std::enable_if<!detail::alloc_has_construct<A, T,
Args...>::value>::type
allocator_construct(A&, T* p, Args&&... args)
{
@@ -449,26 +423,21 @@ allocator_destroy(A&, T* p)
p->~T();
(void)p;
}
#elif defined(BOOST_MSVC)
template<class A, class T>
inline void
allocator_destroy(A& a, T* p)
{
std::allocator_traits<A>::destroy(a, p);
}
#else
namespace detail {
template<class, 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<decltype(std::declval<A
&>().destroy(std::declval<T*>()))>::type> {
BOOST_STATIC_CONSTEXPR bool value = true;
class alloc_has_destroy {
template<class O>
static auto check(int)
-> decltype(std::declval<O&>().destroy(std::declval<T*>()));
template<class>
static alloc_none check(long);
public:
BOOST_STATIC_CONSTEXPR bool value =
!std::is_same<decltype(check<A>(0)), alloc_none>::value;
};
} /* detail */
@@ -496,26 +465,20 @@ allocator_max_size(const A& a)
{
return a.max_size();
}
#elif defined(BOOST_MSVC)
template<class A>
inline typename allocator_size_type<A>::type
allocator_max_size(const A& a)
{
return std::allocator_traits<A>::max_size(a);
}
#else
namespace detail {
template<class, class = void>
struct alloc_has_max_size {
BOOST_STATIC_CONSTEXPR bool value = false;
};
template<class A>
struct alloc_has_max_size<A,
typename alloc_void<decltype(std::declval<const
A&>().max_size())>::type> {
BOOST_STATIC_CONSTEXPR bool value = true;
class alloc_has_max_size {
template<class O>
static auto check(int) -> decltype(std::declval<O&>().max_size());
template<class>
static alloc_none check(long);
public:
BOOST_STATIC_CONSTEXPR bool value =
!std::is_same<decltype(check<A>(0)), alloc_none>::value;
};
} /* detail */
@@ -545,26 +508,21 @@ allocator_select_on_container_copy_construction(const A& a)
{
return a;
}
#elif defined(BOOST_MSVC)
template<class A>
inline A
allocator_select_on_container_copy_construction(const A& a)
{
return std::allocator_traits<A>::select_on_container_copy_construction(a);
}
#else
namespace detail {
template<class, class = void>
struct alloc_has_soccc {
BOOST_STATIC_CONSTEXPR bool value = false;
};
template<class A>
struct alloc_has_soccc<A,
typename alloc_void<decltype(std::declval<const
A&>().select_on_container_copy_construction())>::type> {
BOOST_STATIC_CONSTEXPR bool value = true;
class alloc_has_soccc {
template<class O>
static auto check(int)
-> decltype(std::declval<O&>().select_on_container_copy_construction());
template<class>
static alloc_none check(long);
public:
BOOST_STATIC_CONSTEXPR bool value =
!std::is_same<decltype(check<A>(0)), alloc_none>::value;
};
} /* detail */
@@ -630,4 +588,14 @@ using allocator_rebind_t = typename allocator_rebind<A, T>::type;
} /* boost */
#if defined(_LIBCPP_SUPPRESS_DEPRECATED_POP)
_LIBCPP_SUPPRESS_DEPRECATED_POP
#endif
#if defined(_STL_RESTORE_DEPRECATED_WARNING)
_STL_RESTORE_DEPRECATED_WARNING
#endif
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
#endif

581
include/boost/core/bit.hpp Normal file
View File

@@ -0,0 +1,581 @@
#ifndef BOOST_CORE_BIT_HPP_INCLUDED
#define BOOST_CORE_BIT_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
// boost/core/bit.hpp
//
// A portable version of the C++20 standard header <bit>
//
// Copyright 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/config.hpp>
#include <boost/static_assert.hpp>
#include <boost/cstdint.hpp>
#include <limits>
#include <cstring>
#if defined(_MSC_VER)
# include <intrin.h>
# pragma intrinsic(_BitScanForward)
# pragma intrinsic(_BitScanReverse)
# if defined(_M_X64)
# pragma intrinsic(_BitScanForward64)
# pragma intrinsic(_BitScanReverse64)
# endif
#endif // defined(_MSC_VER)
namespace boost
{
namespace core
{
// bit_cast
template<class To, class From>
To bit_cast( From const & from ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( sizeof(To) == sizeof(From) );
To to;
std::memcpy( &to, &from, sizeof(To) );
return to;
}
// countl
#if defined(__GNUC__) || defined(__clang__)
namespace detail
{
BOOST_CONSTEXPR inline int countl_impl( unsigned char x ) BOOST_NOEXCEPT
{
return x? __builtin_clz( x ) - ( std::numeric_limits<unsigned int>::digits - std::numeric_limits<unsigned char>::digits ): std::numeric_limits<unsigned char>::digits;
}
BOOST_CONSTEXPR inline int countl_impl( unsigned short x ) BOOST_NOEXCEPT
{
return x? __builtin_clz( x ) - ( std::numeric_limits<unsigned int>::digits - std::numeric_limits<unsigned short>::digits ): std::numeric_limits<unsigned short>::digits;
}
BOOST_CONSTEXPR inline int countl_impl( unsigned int x ) BOOST_NOEXCEPT
{
return x? __builtin_clz( x ): std::numeric_limits<unsigned int>::digits;
}
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
{
return x? __builtin_clzll( x ): std::numeric_limits<unsigned long long>::digits;
}
} // namespace detail
template<class T>
BOOST_CONSTEXPR int countl_zero( T x ) BOOST_NOEXCEPT
{
return boost::core::detail::countl_impl( x );
}
#else // defined(__GNUC__) || defined(__clang__)
namespace detail
{
inline int countl_impl( boost::uint32_t x ) BOOST_NOEXCEPT
{
#if defined(_MSC_VER)
unsigned long r;
if( _BitScanReverse( &r, x ) )
{
return 31 - static_cast<int>( r );
}
else
{
return 32;
}
#else
static unsigned char const mod37[ 37 ] = { 32, 31, 6, 30, 9, 5, 0, 29, 16, 8, 2, 4, 21, 0, 19, 28, 25, 15, 0, 7, 10, 1, 17, 3, 22, 20, 26, 0, 11, 18, 23, 27, 12, 24, 13, 14, 0 };
x |= x >> 1;
x |= x >> 2;
x |= x >> 4;
x |= x >> 8;
x |= x >> 16;
return mod37[ x % 37 ];
#endif
}
inline int countl_impl( boost::uint64_t x ) BOOST_NOEXCEPT
{
#if defined(_MSC_VER) && defined(_M_X64)
unsigned long r;
if( _BitScanReverse64( &r, x ) )
{
return 63 - static_cast<int>( r );
}
else
{
return 64;
}
#else
return static_cast<boost::uint32_t>( x >> 32 ) != 0?
boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x >> 32 ) ):
boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x ) ) + 32;
#endif
}
inline int countl_impl( boost::uint8_t x ) BOOST_NOEXCEPT
{
return boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x ) ) - 24;
}
inline int countl_impl( boost::uint16_t x ) BOOST_NOEXCEPT
{
return boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x ) ) - 16;
}
} // namespace detail
template<class T>
int countl_zero( T x ) BOOST_NOEXCEPT
{
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) )
{
return boost::core::detail::countl_impl( static_cast<boost::uint8_t>( x ) );
}
else if( 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) )
{
return boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x ) );
}
else
{
return boost::core::detail::countl_impl( static_cast<boost::uint64_t>( x ) );
}
}
#endif // defined(__GNUC__) || defined(__clang__)
template<class T>
BOOST_CONSTEXPR int countl_one( T x ) BOOST_NOEXCEPT
{
return boost::core::countl_zero( static_cast<T>( ~x ) );
}
// countr
#if defined(__GNUC__) || defined(__clang__)
namespace detail
{
BOOST_CONSTEXPR inline int countr_impl( unsigned char x ) BOOST_NOEXCEPT
{
return x? __builtin_ctz( x ): std::numeric_limits<unsigned char>::digits;
}
BOOST_CONSTEXPR inline int countr_impl( unsigned short x ) BOOST_NOEXCEPT
{
return x? __builtin_ctz( x ): std::numeric_limits<unsigned short>::digits;
}
BOOST_CONSTEXPR inline int countr_impl( unsigned int x ) BOOST_NOEXCEPT
{
return x? __builtin_ctz( x ): std::numeric_limits<unsigned int>::digits;
}
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
{
return x? __builtin_ctzll( x ): std::numeric_limits<unsigned long long>::digits;
}
} // namespace detail
template<class T>
BOOST_CONSTEXPR int countr_zero( T x ) BOOST_NOEXCEPT
{
return boost::core::detail::countr_impl( x );
}
#else // defined(__GNUC__) || defined(__clang__)
namespace detail
{
inline int countr_impl( boost::uint32_t x ) BOOST_NOEXCEPT
{
#if defined(_MSC_VER)
unsigned long r;
if( _BitScanForward( &r, x ) )
{
return static_cast<int>( r );
}
else
{
return 32;
}
#else
static unsigned char const mod37[ 37 ] = { 32, 0, 1, 26, 2, 23, 27, 0, 3, 16, 24, 30, 28, 11, 0, 13, 4, 7, 17, 0, 25, 22, 31, 15, 29, 10, 12, 6, 0, 21, 14, 9, 5, 20, 8, 19, 18 };
return mod37[ ( -(boost::int32_t)x & x ) % 37 ];
#endif
}
inline int countr_impl( boost::uint64_t x ) BOOST_NOEXCEPT
{
#if defined(_MSC_VER) && defined(_M_X64)
unsigned long r;
if( _BitScanForward64( &r, x ) )
{
return static_cast<int>( r );
}
else
{
return 64;
}
#else
return static_cast<boost::uint32_t>( x ) != 0?
boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x ) ):
boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x >> 32 ) ) + 32;
#endif
}
inline int countr_impl( boost::uint8_t x ) BOOST_NOEXCEPT
{
return boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x ) | 0x100 );
}
inline int countr_impl( boost::uint16_t x ) BOOST_NOEXCEPT
{
return boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x ) | 0x10000 );
}
} // namespace detail
template<class T>
int countr_zero( T x ) BOOST_NOEXCEPT
{
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) )
{
return boost::core::detail::countr_impl( static_cast<boost::uint8_t>( x ) );
}
else if( 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) )
{
return boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x ) );
}
else
{
return boost::core::detail::countr_impl( static_cast<boost::uint64_t>( x ) );
}
}
#endif // defined(__GNUC__) || defined(__clang__)
template<class T>
BOOST_CONSTEXPR int countr_one( T x ) BOOST_NOEXCEPT
{
return boost::core::countr_zero( static_cast<T>( ~x ) );
}
// popcount
#if defined(__GNUC__) || defined(__clang__)
#if defined(__clang__) && __clang_major__ * 100 + __clang_minor__ < 304
# define BOOST_CORE_POPCOUNT_CONSTEXPR
#else
# define BOOST_CORE_POPCOUNT_CONSTEXPR BOOST_CONSTEXPR
#endif
namespace detail
{
BOOST_CORE_POPCOUNT_CONSTEXPR inline int popcount_impl( unsigned char x ) BOOST_NOEXCEPT
{
return __builtin_popcount( x );
}
BOOST_CORE_POPCOUNT_CONSTEXPR inline int popcount_impl( unsigned short x ) BOOST_NOEXCEPT
{
return __builtin_popcount( x );
}
BOOST_CORE_POPCOUNT_CONSTEXPR inline int popcount_impl( unsigned int x ) BOOST_NOEXCEPT
{
return __builtin_popcount( x );
}
BOOST_CORE_POPCOUNT_CONSTEXPR inline int popcount_impl( unsigned long x ) BOOST_NOEXCEPT
{
return __builtin_popcountl( x );
}
BOOST_CORE_POPCOUNT_CONSTEXPR inline int popcount_impl( unsigned long long x ) BOOST_NOEXCEPT
{
return __builtin_popcountll( x );
}
} // namespace detail
#undef BOOST_CORE_POPCOUNT_CONSTEXPR
template<class T>
BOOST_CONSTEXPR int popcount( T x ) BOOST_NOEXCEPT
{
return boost::core::detail::popcount_impl( x );
}
#else // defined(__GNUC__) || defined(__clang__)
namespace detail
{
BOOST_CXX14_CONSTEXPR inline int popcount_impl( boost::uint32_t x ) BOOST_NOEXCEPT
{
x = x - ( ( x >> 1 ) & 0x55555555 );
x = ( x & 0x33333333 ) + ( ( x >> 2 ) & 0x33333333 );
x = ( x + ( x >> 4 ) ) & 0x0F0F0F0F;
return static_cast<unsigned>( ( x * 0x01010101 ) >> 24 );
}
BOOST_CXX14_CONSTEXPR inline int popcount_impl( boost::uint64_t x ) BOOST_NOEXCEPT
{
x = x - ( ( x >> 1 ) & 0x5555555555555555 );
x = ( x & 0x3333333333333333 ) + ( ( x >> 2 ) & 0x3333333333333333 );
x = ( x + ( x >> 4 ) ) & 0x0F0F0F0F0F0F0F0F;
return static_cast<unsigned>( ( x * 0x0101010101010101 ) >> 56 );
}
} // namespace detail
template<class T>
BOOST_CXX14_CONSTEXPR int popcount( T x ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( sizeof(T) <= sizeof(boost::uint64_t) );
if( sizeof(T) <= sizeof(boost::uint32_t) )
{
return boost::core::detail::popcount_impl( static_cast<boost::uint32_t>( x ) );
}
else
{
return boost::core::detail::popcount_impl( static_cast<boost::uint64_t>( x ) );
}
}
#endif // defined(__GNUC__) || defined(__clang__)
// rotating
template<class T>
BOOST_CXX14_CONSTEXPR T rotl( T x, int s ) BOOST_NOEXCEPT
{
unsigned const mask = std::numeric_limits<T>::digits - 1;
return x << (s & mask) | x >> ((-s) & mask);
}
template<class T>
BOOST_CXX14_CONSTEXPR T rotr( T x, int s ) BOOST_NOEXCEPT
{
unsigned const mask = std::numeric_limits<T>::digits - 1;
return x >> (s & mask) | x << ((-s) & mask);
}
// integral powers of 2
template<class T>
BOOST_CONSTEXPR bool has_single_bit( T x ) BOOST_NOEXCEPT
{
return x != 0 && ( x & ( x - 1 ) ) == 0;
}
template<class T>
BOOST_CONSTEXPR T bit_width( T x ) BOOST_NOEXCEPT
{
return std::numeric_limits<T>::digits - boost::core::countl_zero( x );
}
template<class T>
BOOST_CONSTEXPR T bit_floor( T x ) BOOST_NOEXCEPT
{
return x == 0? 0: T(1) << ( boost::core::bit_width( x ) - 1 );
}
namespace detail
{
BOOST_CXX14_CONSTEXPR inline boost::uint32_t bit_ceil_impl( boost::uint32_t x ) BOOST_NOEXCEPT
{
if( x == 0 )
{
return 0;
}
--x;
x |= x >> 1;
x |= x >> 2;
x |= x >> 4;
x |= x >> 8;
x |= x >> 16;
++x;
return x;
}
BOOST_CXX14_CONSTEXPR inline boost::uint64_t bit_ceil_impl( boost::uint64_t x ) BOOST_NOEXCEPT
{
if( x == 0 )
{
return 0;
}
--x;
x |= x >> 1;
x |= x >> 2;
x |= x >> 4;
x |= x >> 8;
x |= x >> 16;
x |= x >> 32;
++x;
return x;
}
} // namespace detail
template<class T>
BOOST_CXX14_CONSTEXPR T bit_ceil( T x ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( sizeof(T) <= sizeof(boost::uint64_t) );
if( sizeof(T) <= sizeof(boost::uint32_t) )
{
return static_cast<T>( boost::core::detail::bit_ceil_impl( static_cast<boost::uint32_t>( x ) ) );
}
else
{
return static_cast<T>( boost::core::detail::bit_ceil_impl( static_cast<boost::uint64_t>( x ) ) );
}
}
// endian
#if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
# define BOOST_CORE_BIT_NATIVE_INITIALIZER =little
#elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
# define BOOST_CORE_BIT_NATIVE_INITIALIZER =big
#elif defined(__BYTE_ORDER__) && defined(__ORDER_PDP_ENDIAN__) && __BYTE_ORDER__ == __ORDER_PDP_ENDIAN__
# define BOOST_CORE_BIT_NATIVE_INITIALIZER
#elif defined(__LITTLE_ENDIAN__)
# define BOOST_CORE_BIT_NATIVE_INITIALIZER =little
#elif defined(__BIG_ENDIAN__)
# define BOOST_CORE_BIT_NATIVE_INITIALIZER =big
#elif defined(_MSC_VER) || defined(__i386__) || defined(__x86_64__)
# define BOOST_CORE_BIT_NATIVE_INITIALIZER =little
#else
# define BOOST_CORE_BIT_NATIVE_INITIALIZER
#endif
#if !defined(BOOST_NO_CXX11_SCOPED_ENUMS)
enum class endian
{
big,
little,
native BOOST_CORE_BIT_NATIVE_INITIALIZER
};
typedef endian endian_type;
#else
namespace endian
{
enum type
{
big,
little,
native BOOST_CORE_BIT_NATIVE_INITIALIZER
};
} // namespace endian
typedef endian::type endian_type;
#endif
#undef BOOST_CORE_BIT_NATIVE_INITIALIZER
} // namespace core
} // namespace boost
#endif // #ifndef BOOST_CORE_BIT_HPP_INCLUDED

View File

@@ -0,0 +1,298 @@
#ifndef BOOST_CORE_CMATH_HPP_INCLUDED
#define BOOST_CORE_CMATH_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
// boost/core/cmath.hpp
//
// Floating point classification and sign manipulation functions
// Extracted from https://github.com/boostorg/lexical_cast/pull/37
//
// Copyright 2020, 2021 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <cmath>
#if defined(BOOST_CORE_USE_GENERIC_CMATH) || (!defined(_MSC_VER) && !defined(FP_SUBNORMAL))
#include <boost/cstdint.hpp>
#include <boost/static_assert.hpp>
#include <limits>
#include <cstring>
namespace boost
{
namespace core
{
// fpclassify return values
int const fp_zero = 0;
int const fp_subnormal = 1;
int const fp_normal = 2;
int const fp_infinite = 3;
int const fp_nan = 4;
// Classification functions
template<class T> bool isfinite( T x )
{
return x <= (std::numeric_limits<T>::max)() && x >= -(std::numeric_limits<T>::max)();
}
template<class T> bool isinf( T x )
{
return x > (std::numeric_limits<T>::max)() || x < -(std::numeric_limits<T>::max)();
}
template<class T> bool isnan( T x )
{
return !isfinite( x ) && !isinf( x );
}
template<class T> bool isnormal( T x )
{
return isfinite( x ) && ( x >= (std::numeric_limits<T>::min)() || x <= -(std::numeric_limits<T>::min)() );
}
template<class T> int fpclassify( T x )
{
if( x == 0 ) return fp_zero;
if( x < 0 ) x = -x;
if( x > (std::numeric_limits<T>::max)() ) return fp_infinite;
if( x >= (std::numeric_limits<T>::min)() ) return fp_normal;
if( x < (std::numeric_limits<T>::min)() ) return fp_subnormal;
return fp_nan;
}
// Sign manipulation functions
inline bool signbit( float x )
{
boost::int32_t y;
BOOST_STATIC_ASSERT( sizeof( x ) == sizeof( y ) );
std::memcpy( &y, &x, sizeof( y ) );
return y < 0;
}
inline bool signbit( double x )
{
boost::int64_t y;
BOOST_STATIC_ASSERT( sizeof( x ) == sizeof( y ) );
std::memcpy( &y, &x, sizeof( y ) );
return y < 0;
}
inline bool signbit( long double x )
{
return signbit( static_cast<double>( x ) );
}
template<class T> T copysign( T x, T y )
{
return signbit( x ) == signbit( y )? x: -x;
}
} // namespace core
} // namespace boost
#else // defined(BOOST_CORE_USE_GENERIC_CMATH)
#if defined(_MSC_VER) && _MSC_VER < 1800
# include <float.h>
#endif
namespace boost
{
namespace core
{
#if defined(_MSC_VER) && _MSC_VER < 1800
template<class T> T copysign( T x, T y )
{
return static_cast<T>( _copysign( static_cast<double>( x ), static_cast<double>( y ) ) );
}
template<class T> bool isnan( T x )
{
return _isnan( static_cast<double>( x ) ) != 0;
}
template<class T> bool isfinite( T x )
{
return _finite( static_cast<double>( x ) ) != 0;
}
template<class T> bool isinf( T x )
{
return ( _fpclass( static_cast<double>( x ) ) & ( _FPCLASS_PINF | _FPCLASS_NINF ) ) != 0;
}
inline bool isnormal( float x )
{
// no _fpclassf in 32 bit mode
unsigned y = reinterpret_cast< unsigned const& >( x );
unsigned exp = ( y >> 23 ) & 0xFF;
return exp != 0 && exp != 0xFF;
}
inline bool isnormal( double x )
{
return ( _fpclass( x ) & ( _FPCLASS_PN | _FPCLASS_NN ) ) != 0;
}
inline bool isnormal( long double x )
{
return boost::core::isnormal( static_cast<double>( x ) );
}
template<class T> bool signbit( T x )
{
return _copysign( 1.0, static_cast<double>( x ) ) < 0.0;
}
int const fp_zero = 0;
int const fp_subnormal = 1;
int const fp_normal = 2;
int const fp_infinite = 3;
int const fp_nan = 4;
inline int fpclassify( float x )
{
switch( _fpclass( x ) )
{
case _FPCLASS_SNAN:
case _FPCLASS_QNAN:
return fp_nan;
case _FPCLASS_NINF:
case _FPCLASS_PINF:
return fp_infinite;
case _FPCLASS_NZ:
case _FPCLASS_PZ:
return fp_zero;
default:
return boost::core::isnormal( x )? fp_normal: fp_subnormal;
}
}
inline int fpclassify( double x )
{
switch( _fpclass( x ) )
{
case _FPCLASS_SNAN:
case _FPCLASS_QNAN:
return fp_nan;
case _FPCLASS_NINF:
case _FPCLASS_PINF:
return fp_infinite;
case _FPCLASS_NZ:
case _FPCLASS_PZ:
return fp_zero;
case _FPCLASS_ND:
case _FPCLASS_PD:
return fp_subnormal;
default:
return fp_normal;
}
}
inline int fpclassify( long double x )
{
return boost::core::fpclassify( static_cast<double>( x ) );
}
#else
using std::isfinite;
using std::isnan;
using std::isinf;
using std::isnormal;
using std::fpclassify;
int const fp_zero = FP_ZERO;
int const fp_subnormal = FP_SUBNORMAL;
int const fp_normal = FP_NORMAL;
int const fp_infinite = FP_INFINITE;
int const fp_nan = FP_NAN;
using std::signbit;
// std::copysign doesn't exist in libstdc++ under -std=c++03
#if !defined(__GNUC__)
template<class T> T copysign( T x, T y )
{
return std::copysign( x, y );
}
#else
namespace detail
{
// ::copysignl is unreliable, use the built-ins
inline float copysign_impl( float x, float y )
{
return __builtin_copysignf( x, y );
}
inline double copysign_impl( double x, double y )
{
return __builtin_copysign( x, y );
}
inline long double copysign_impl( long double x, long double y )
{
return __builtin_copysignl( x, y );
}
} // namespace detail
template<class T> T copysign( T x, T y )
{
return boost::core::detail::copysign_impl( x, y );
}
#endif // !defined(__GNUC__)
#endif // #if defined(_MSC_VER) && _MSC_VER < 1800
} // namespace core
} // namespace boost
#endif // defined(BOOST_CORE_USE_GENERIC_CMATH)
#endif // #ifndef BOOST_CORE_CMATH_HPP_INCLUDED

View File

@@ -0,0 +1,54 @@
#ifndef BOOST_CORE_DETAIL_SPLITMIX64_HPP_INCLUDED
#define BOOST_CORE_DETAIL_SPLITMIX64_HPP_INCLUDED
// Copyright 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
//
// An implementation of splitmix64 for testing purposes,
// derived from Sebastiano Vigna's public domain implementation
// http://xorshift.di.unimi.it/splitmix64.c
#include <boost/cstdint.hpp>
namespace boost
{
namespace detail
{
class splitmix64
{
private:
boost::uint64_t x_;
public:
splitmix64(): x_( 0 )
{
}
explicit splitmix64( boost::uint64_t seed ): x_( seed )
{
}
boost::uint64_t operator()()
{
x_ += 0x9e3779b97f4a7c15;
boost::uint64_t z = x_;
z ^= z >> 30;
z *= 0xbf58476d1ce4e5b9;
z ^= z >> 27;
z *= 0x94d049bb133111eb;
z ^= z >> 31;
return z;
}
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_CORE_DETAIL_SPLITMIX64_HPP_INCLUDED

View File

@@ -11,34 +11,64 @@
namespace boost {
#ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template <typename... Ts>
BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(Ts&& ...)
{}
#else
template <typename... Ts>
BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(Ts const& ...)
{}
#endif
template <typename... Ts>
BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused()
{}
#else
#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template <typename T1>
BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1&)
{}
template <typename T1>
BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1 const&)
{}
template <typename T1, typename T2>
BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1&, T2&)
{}
template <typename T1, typename T2>
BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1 const&, T2 const&)
{}
template <typename T1, typename T2, typename T3>
BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1&, T2&, T3&)
{}
template <typename T1, typename T2, typename T3>
BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1 const&, T2 const&, T3 const&)
{}
template <typename T1, typename T2, typename T3, typename T4>
BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1&, T2&, T3&, T4&)
{}
template <typename T1, typename T2, typename T3, typename T4>
BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1 const&, T2 const&, T3 const&, T4 const&)
{}
template <typename T1, typename T2, typename T3, typename T4, typename T5>
BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1&, T2&, T3&, T4&, T5&)
{}
template <typename T1, typename T2, typename T3, typename T4, typename T5>
BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1 const&, T2 const&, T3 const&, T4 const&, T5 const&)
{}

View File

@@ -27,9 +27,12 @@
#include <exception>
#include <iostream>
#include <iterator>
#include <string>
#include <cstdlib>
#include <cstring>
#include <cstddef>
#include <cctype>
#include <cstdio>
#if defined(_MSC_VER) && defined(_CPPLIB_VER) && defined(_DEBUG)
# include <crtdbg.h>
@@ -173,6 +176,51 @@ template<class T> inline const void* test_output_impl(T volatile* v) { return co
inline const void* test_output_impl(std::nullptr_t) { return nullptr; }
#endif
// print chars as numeric
inline int test_output_impl( signed char const& v ) { return v; }
inline unsigned test_output_impl( unsigned char const& v ) { return v; }
// Whether wchar_t is signed is implementation-defined
template<bool Signed> struct lwt_long_type {};
template<> struct lwt_long_type<true> { typedef long type; };
template<> struct lwt_long_type<false> { typedef unsigned long type; };
inline lwt_long_type<(static_cast<wchar_t>(-1) < static_cast<wchar_t>(0))>::type test_output_impl( wchar_t const& v ) { return v; }
#if !defined( BOOST_NO_CXX11_CHAR16_T )
inline unsigned long test_output_impl( char16_t const& v ) { return v; }
#endif
#if !defined( BOOST_NO_CXX11_CHAR32_T )
inline unsigned long test_output_impl( char32_t const& v ) { return v; }
#endif
#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable: 4996)
#endif
inline std::string test_output_impl( char const& v )
{
if( std::isprint( static_cast<unsigned char>( v ) ) )
{
return std::string( 1, v );
}
else
{
char buffer[ 8 ];
std::sprintf( buffer, "\\x%02X", static_cast<unsigned char>( v ) );
return buffer;
}
}
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
// predicates
struct lw_test_eq

View File

@@ -10,6 +10,7 @@
#include <boost/config.hpp>
#include <boost/config/workaround.hpp>
#include <boost/core/addressof.hpp>
#include <boost/core/enable_if.hpp>
//
// ref.hpp - ref/cref, useful helper functions
@@ -46,6 +47,26 @@ namespace boost
#endif
namespace detail
{
template< class Y, class T > struct ref_convertible
{
typedef char (&yes) [1];
typedef char (&no) [2];
static yes f( T* );
static no f( ... );
enum _vt { value = sizeof( (f)( static_cast<Y*>(0) ) ) == sizeof(yes) };
};
struct ref_empty
{
};
} // namespace detail
// reference_wrapper
/**
@@ -87,6 +108,21 @@ public:
public:
#endif
template<class Y> friend class reference_wrapper;
/**
Constructs a `reference_wrapper` object that stores the
reference stored in the compatible `reference_wrapper` `r`.
@remark Only enabled when `Y*` is convertible to `T*`.
@remark Does not throw.
*/
template<class Y> reference_wrapper( reference_wrapper<Y> r,
typename enable_if_c<boost::detail::ref_convertible<Y, T>::value,
boost::detail::ref_empty>::type = boost::detail::ref_empty() ): t_( r.t_ )
{
}
/**
@return The stored reference.
@remark Does not throw.

View File

@@ -0,0 +1,855 @@
#ifndef BOOST_CORE_TYPE_NAME_HPP_INCLUDED
#define BOOST_CORE_TYPE_NAME_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
// std::string boost::core::type_name<T>()
//
// Copyright 2021 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/core/is_same.hpp>
#include <boost/config.hpp>
#include <string>
#include <functional>
#include <memory>
#include <utility>
#include <cstdio>
#include <cstddef>
#include <iosfwd>
#if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
# include <string_view>
#endif
namespace boost
{
namespace core
{
namespace detail
{
// tn_identity
template<class T> struct tn_identity
{
typedef T type;
};
// tn_enable_if
template<bool C, class T> struct tn_enable_if
{
};
template<class T> struct tn_enable_if<true, T>
{
typedef T type;
};
// tn_is_reference
template<class T> struct tn_is_reference
{
static const bool value = false;
};
template<class T> struct tn_is_reference<T&>
{
static const bool value = true;
};
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template<class T> struct tn_is_reference<T&&>
{
static const bool value = true;
};
#endif
// tn_remove_const
template<class T> struct tn_remove_const
{
typedef T type;
};
template<class T> struct tn_remove_const<T const>
{
typedef T type;
};
// tn_is_function (also catches references but that's OK)
#if defined(BOOST_MSVC)
# pragma warning(push)
# pragma warning(disable: 4180 4181)
#endif
template<class T, class U = typename tn_remove_const<T>::type> struct tn_is_function: core::is_same<U, U const>
{
};
#if defined(BOOST_MSVC)
# pragma warning(pop)
#endif
#if !defined(BOOST_NO_TYPEID)
// typeid_name
template<class T> std::string typeid_name()
{
std::string r = boost::core::demangle( typeid(T).name() );
#if defined(_MSC_VER)
if( r.substr( 0, 6 ) == "class " )
{
r = r.substr( 6 );
}
if( r.substr( 0, 7 ) == "struct " )
{
r = r.substr( 7 );
}
if( r.substr( 0, 5 ) == "enum " )
{
r = r.substr( 5 );
}
#endif
// libc++ inline namespace
if( r.substr( 0, 10 ) == "std::__1::" )
{
r = "std::" + r.substr( 10 );
}
// libstdc++ inline namespace
if( r.substr( 0, 14 ) == "std::__cxx11::" )
{
r = "std::" + r.substr( 14 );
}
#if defined(BOOST_MSVC) && BOOST_MSVC == 1600
// msvc-10.0 puts TR1 things in std::tr1
if( r.substr( 0, 10 ) == "std::tr1::" )
{
r = "std::" + r.substr( 10 );
}
#endif
return r;
}
// template names
template<class T> std::string class_template_name()
{
std::string r = typeid_name<T>();
return r.substr( 0, r.find( '<' ) );
}
template<class T> std::string sequence_template_name()
{
return class_template_name<T>();
}
template<class T> std::string set_template_name()
{
return class_template_name<T>();
}
template<class T> std::string map_template_name()
{
return class_template_name<T>();
}
template<class T> std::string array_template_name()
{
return class_template_name<T>();
}
#else // #if !defined(BOOST_NO_TYPEID)
template<class T> std::string typeid_name()
{
return "_Tp";
}
template<class T> std::string class_template_name()
{
return "_Tm";
}
template<class T> std::string sequence_template_name()
{
return "_Sq";
}
template<class T> std::string set_template_name()
{
return "_St";
}
template<class T> std::string map_template_name()
{
return "_Mp";
}
template<class T> std::string array_template_name()
{
return "_Ar";
}
#endif
// tn_to_string
#if defined(BOOST_MSVC)
# pragma warning( push )
# pragma warning( disable: 4996 )
#endif
inline std::string tn_to_string( std::size_t n )
{
char buffer[ 32 ];
std::sprintf( buffer, "%lu", static_cast< unsigned long >( n ) );
return buffer;
}
#if defined(BOOST_MSVC)
# pragma warning( pop )
#endif
// tn_add_each
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<class T> int tn_add_each_impl( std::string& st )
{
if( !st.empty() ) st += ", ";
st += type_name( tn_identity<T>(), "" );
return 0;
}
template<class... T> std::string tn_add_each()
{
std::string st;
typedef int A[ sizeof...(T) + 1 ];
(void)A{ 0, tn_add_each_impl<T>( st )... };
return st;
}
#endif
// primary
template<class T> std::string type_name( tn_identity<T>, std::string const& suffix )
{
return typeid_name<T>() + suffix;
}
// integrals
inline std::string type_name( tn_identity<unsigned>, std::string const& suffix )
{
return "unsigned" + suffix;
}
#if defined(_MSC_VER)
inline std::string type_name( tn_identity<long long>, std::string const& suffix )
{
return "long long" + suffix;
}
inline std::string type_name( tn_identity<unsigned long long>, std::string const& suffix )
{
return "unsigned long long" + suffix;
}
#endif
#if defined(__cpp_char8_t) && __cpp_char8_t >= 201811L
inline std::string type_name( tn_identity<char8_t>, std::string const& suffix )
{
return "char8_t" + suffix;
}
#endif
// cv
#if !defined(BOOST_MSVC) || BOOST_MSVC >= 1900
template<class T> std::string type_name( tn_identity<T const>, std::string const& suffix )
{
return type_name( tn_identity<T>(), " const" + suffix );
}
template<class T> std::string type_name( tn_identity<T volatile>, std::string const& suffix )
{
return type_name( tn_identity<T>(), " volatile" + suffix );
}
template<class T> std::string type_name( tn_identity<T const volatile>, std::string const& suffix )
{
return type_name( tn_identity<T>(), " const volatile" + suffix );
}
#else
template<class T>
typename tn_enable_if<!tn_is_function<T>::value, std::string>::type
type_name( tn_identity<T const>, std::string const& suffix )
{
return type_name( tn_identity<T>(), " const" + suffix );
}
template<class T>
typename tn_enable_if<!tn_is_function<T>::value, std::string>::type
type_name( tn_identity<T volatile>, std::string const& suffix )
{
return type_name( tn_identity<T>(), " volatile" + suffix );
}
template<class T>
typename tn_enable_if<!tn_is_function<T>::value, std::string>::type
type_name( tn_identity<T const volatile>, std::string const& suffix )
{
return type_name( tn_identity<T>(), " const volatile" + suffix );
}
#endif
// refs
#if !defined(BOOST_MSVC) || BOOST_MSVC >= 1900
template<class T> std::string type_name( tn_identity<T&>, std::string const& suffix )
{
return type_name( tn_identity<T>(), "&" + suffix );
}
#else
template<class T>
typename tn_enable_if<!tn_is_reference<T>::value, std::string>::type
type_name( tn_identity<T&>, std::string const& suffix )
{
return type_name( tn_identity<T>(), "&" + suffix );
}
#endif
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template<class T> std::string type_name( tn_identity<T&&>, std::string const& suffix )
{
return type_name( tn_identity<T>(), "&&" + suffix );
}
#endif
// function types
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<class R, class... A> std::string function_type_name( tn_identity<R(A...)>, std::string const& trailer, std::string const& suffix )
{
std::string r = type_name( tn_identity<R>(), "" );
if( !suffix.empty() )
{
r += '(';
if( suffix[ 0 ] == ' ' )
{
r += suffix.substr( 1 );
}
else
{
r += suffix;
}
r += ')';
}
r += '(' + tn_add_each<A...>() + ')';
r += trailer;
return r;
}
template<class R, class... A> std::string type_name( tn_identity<R(A...)>, std::string const& suffix )
{
return function_type_name( tn_identity<R(A...)>(), "", suffix );
}
#if !defined(BOOST_MSVC) || BOOST_MSVC >= 1900
template<class R, class... A> std::string type_name( tn_identity<R(A...) const>, std::string const& suffix )
{
return function_type_name( tn_identity<R(A...)>(), " const", suffix );
}
template<class R, class... A> std::string type_name( tn_identity<R(A...) volatile>, std::string const& suffix )
{
return function_type_name( tn_identity<R(A...)>(), " volatile", suffix );
}
template<class R, class... A> std::string type_name( tn_identity<R(A...) const volatile>, std::string const& suffix )
{
return function_type_name( tn_identity<R(A...)>(), " const volatile", suffix );
}
#endif
#if !defined(BOOST_NO_CXX11_REF_QUALIFIERS)
template<class R, class... A> std::string type_name( tn_identity<R(A...) &>, std::string const& suffix )
{
return function_type_name( tn_identity<R(A...)>(), " &", suffix );
}
template<class R, class... A> std::string type_name( tn_identity<R(A...) const &>, std::string const& suffix )
{
return function_type_name( tn_identity<R(A...)>(), " const &", suffix );
}
template<class R, class... A> std::string type_name( tn_identity<R(A...) volatile &>, std::string const& suffix )
{
return function_type_name( tn_identity<R(A...)>(), " volatile &", suffix );
}
template<class R, class... A> std::string type_name( tn_identity<R(A...) const volatile &>, std::string const& suffix )
{
return function_type_name( tn_identity<R(A...)>(), " const volatile &", suffix );
}
template<class R, class... A> std::string type_name( tn_identity<R(A...) &&>, std::string const& suffix )
{
return function_type_name( tn_identity<R(A...)>(), " &&", suffix );
}
template<class R, class... A> std::string type_name( tn_identity<R(A...) const &&>, std::string const& suffix )
{
return function_type_name( tn_identity<R(A...)>(), " const &&", suffix );
}
template<class R, class... A> std::string type_name( tn_identity<R(A...) volatile &&>, std::string const& suffix )
{
return function_type_name( tn_identity<R(A...)>(), " volatile &&", suffix );
}
template<class R, class... A> std::string type_name( tn_identity<R(A...) const volatile &&>, std::string const& suffix )
{
return function_type_name( tn_identity<R(A...)>(), " const volatile &&", suffix );
}
#endif
#if defined( __cpp_noexcept_function_type ) || defined( _NOEXCEPT_TYPES_SUPPORTED )
template<class R, class... A> std::string type_name( tn_identity<R(A...) noexcept>, std::string const& suffix )
{
return function_type_name( tn_identity<R(A...)>(), " noexcept", suffix );
}
template<class R, class... A> std::string type_name( tn_identity<R(A...) const noexcept>, std::string const& suffix )
{
return function_type_name( tn_identity<R(A...)>(), " const noexcept", suffix );
}
template<class R, class... A> std::string type_name( tn_identity<R(A...) volatile noexcept>, std::string const& suffix )
{
return function_type_name( tn_identity<R(A...)>(), " volatile noexcept", suffix );
}
template<class R, class... A> std::string type_name( tn_identity<R(A...) const volatile noexcept>, std::string const& suffix )
{
return function_type_name( tn_identity<R(A...)>(), " const volatile noexcept", suffix );
}
template<class R, class... A> std::string type_name( tn_identity<R(A...) & noexcept>, std::string const& suffix )
{
return function_type_name( tn_identity<R(A...)>(), " & noexcept", suffix );
}
template<class R, class... A> std::string type_name( tn_identity<R(A...) const & noexcept>, std::string const& suffix )
{
return function_type_name( tn_identity<R(A...)>(), " const & noexcept", suffix );
}
template<class R, class... A> std::string type_name( tn_identity<R(A...) volatile & noexcept>, std::string const& suffix )
{
return function_type_name( tn_identity<R(A...)>(), " volatile & noexcept", suffix );
}
template<class R, class... A> std::string type_name( tn_identity<R(A...) const volatile & noexcept>, std::string const& suffix )
{
return function_type_name( tn_identity<R(A...)>(), " const volatile & noexcept", suffix );
}
template<class R, class... A> std::string type_name( tn_identity<R(A...) && noexcept>, std::string const& suffix )
{
return function_type_name( tn_identity<R(A...)>(), " && noexcept", suffix );
}
template<class R, class... A> std::string type_name( tn_identity<R(A...) const && noexcept>, std::string const& suffix )
{
return function_type_name( tn_identity<R(A...)>(), " const && noexcept", suffix );
}
template<class R, class... A> std::string type_name( tn_identity<R(A...) volatile && noexcept>, std::string const& suffix )
{
return function_type_name( tn_identity<R(A...)>(), " volatile && noexcept", suffix );
}
template<class R, class... A> std::string type_name( tn_identity<R(A...) const volatile && noexcept>, std::string const& suffix )
{
return function_type_name( tn_identity<R(A...)>(), " const volatile && noexcept", suffix );
}
#endif
#endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
// pointers
template<class T> std::string type_name( tn_identity<T*>, std::string const& suffix )
{
return type_name( tn_identity<T>(), "*" + suffix );
}
// arrays
template<class T> std::pair<std::string, std::string> array_prefix_suffix( tn_identity<T> )
{
return std::pair<std::string, std::string>( type_name( tn_identity<T>(), "" ), "" );
}
template<class T, std::size_t N> std::pair<std::string, std::string> array_prefix_suffix( tn_identity<T[N]> )
{
std::pair<std::string, std::string> r = array_prefix_suffix( tn_identity<T>() );
r.second = '[' + tn_to_string( N ) + ']' + r.second;
return r;
}
template<class T> std::string array_type_name( tn_identity<T[]>, std::string const& suffix )
{
std::pair<std::string, std::string> r = array_prefix_suffix( tn_identity<T>() );
if( suffix.empty() )
{
return r.first + "[]" + r.second;
}
else
{
return r.first + '(' + suffix + ")[]" + r.second;
}
}
template<class T> std::string type_name( tn_identity<T[]>, std::string const& suffix )
{
return array_type_name( tn_identity<T[]>(), suffix );
}
template<class T> std::string type_name( tn_identity<T const[]>, std::string const& suffix )
{
return array_type_name( tn_identity<T const[]>(), suffix );
}
template<class T> std::string type_name( tn_identity<T volatile[]>, std::string const& suffix )
{
return array_type_name( tn_identity<T volatile[]>(), suffix );
}
template<class T> std::string type_name( tn_identity<T const volatile[]>, std::string const& suffix )
{
return array_type_name( tn_identity<T const volatile[]>(), suffix );
}
template<class T, std::size_t N> std::string array_type_name( tn_identity<T[N]>, std::string const& suffix )
{
std::pair<std::string, std::string> r = array_prefix_suffix( tn_identity<T[N]>() );
if( suffix.empty() )
{
return r.first + r.second;
}
else
{
return r.first + '(' + suffix + ")" + r.second;
}
}
template<class T, std::size_t N> std::string type_name( tn_identity<T[N]>, std::string const& suffix )
{
return array_type_name( tn_identity<T[N]>(), suffix );
}
template<class T, std::size_t N> std::string type_name( tn_identity<T const[N]>, std::string const& suffix )
{
return array_type_name( tn_identity<T const[N]>(), suffix );
}
template<class T, std::size_t N> std::string type_name( tn_identity<T volatile[N]>, std::string const& suffix )
{
return array_type_name( tn_identity<T volatile[N]>(), suffix );
}
template<class T, std::size_t N> std::string type_name( tn_identity<T const volatile[N]>, std::string const& suffix )
{
return array_type_name( tn_identity<T const volatile[N]>(), suffix );
}
// pointers to members
template<class R, class T> std::string type_name( tn_identity<R T::*>, std::string const& suffix )
{
return type_name( tn_identity<R>(), ' ' + type_name( tn_identity<T>(), "" ) + "::*" + suffix );
}
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1900 && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<class R, class T, class... A> std::string type_name( tn_identity<R(T::*)(A...) const>, std::string const& suffix )
{
return function_type_name( tn_identity<R(A...)>(), " const", ' ' + type_name( tn_identity<T>(), "" ) + "::*" + suffix );
}
template<class R, class T, class... A> std::string type_name( tn_identity<R(T::*)(A...) volatile>, std::string const& suffix )
{
return function_type_name( tn_identity<R(A...)>(), " volatile", ' ' + type_name( tn_identity<T>(), "" ) + "::*" + suffix );
}
template<class R, class T, class... A> std::string type_name( tn_identity<R(T::*)(A...) const volatile>, std::string const& suffix )
{
return function_type_name( tn_identity<R(A...)>(), " const volatile", ' ' + type_name( tn_identity<T>(), "" ) + "::*" + suffix );
}
#endif
// nullptr_t
#if !defined(BOOST_NO_CXX11_NULLPTR)
inline std::string type_name( tn_identity<std::nullptr_t>, std::string const& suffix )
{
return "std::nullptr_t" + suffix;
}
#endif
// strings
template<template<class Ch, class Tr, class A> class L, class Ch> std::string type_name( tn_identity< L<Ch, std::char_traits<Ch>, std::allocator<Ch> > >, std::string const& suffix )
{
std::string tn = sequence_template_name< L<Ch, std::char_traits<Ch>, std::allocator<Ch> > >();
return tn + '<' + type_name( tn_identity<Ch>(), "" ) + '>' + suffix;
}
inline std::string type_name( tn_identity<std::string>, std::string const& suffix )
{
return "std::string" + suffix;
}
inline std::string type_name( tn_identity<std::wstring>, std::string const& suffix )
{
return "std::wstring" + suffix;
}
#if !defined(BOOST_NO_CXX11_CHAR16_T)
inline std::string type_name( tn_identity<std::u16string>, std::string const& suffix )
{
return "std::u16string" + suffix;
}
#endif
#if !defined(BOOST_NO_CXX11_CHAR32_T)
inline std::string type_name( tn_identity<std::u32string>, std::string const& suffix )
{
return "std::u32string" + suffix;
}
#endif
#if defined(__cpp_char8_t) && __cpp_char8_t >= 201811L
inline std::string type_name( tn_identity<std::basic_string<char8_t>>, std::string const& suffix )
{
return "std::u8string" + suffix;
}
#endif
// string views (et al)
template<template<class Ch, class Tr> class L, class Ch> std::string type_name( tn_identity< L<Ch, std::char_traits<Ch> > >, std::string const& suffix )
{
std::string tn = sequence_template_name< L<Ch, std::char_traits<Ch> > >();
return tn + '<' + type_name( tn_identity<Ch>(), "" ) + '>' + suffix;
}
// needed for libstdc++
inline std::string type_name( tn_identity<std::ostream>, std::string const& suffix )
{
return "std::ostream" + suffix;
}
#if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
inline std::string type_name( tn_identity<std::string_view>, std::string const& suffix )
{
return "std::string_view" + suffix;
}
inline std::string type_name( tn_identity<std::wstring_view>, std::string const& suffix )
{
return "std::wstring_view" + suffix;
}
#if !defined(BOOST_NO_CXX11_CHAR16_T)
inline std::string type_name( tn_identity<std::u16string_view>, std::string const& suffix )
{
return "std::u16string_view" + suffix;
}
#endif
#if !defined(BOOST_NO_CXX11_CHAR32_T)
inline std::string type_name( tn_identity<std::u32string_view>, std::string const& suffix )
{
return "std::u32string_view" + suffix;
}
#endif
#if defined(__cpp_char8_t) && __cpp_char8_t >= 201811L
inline std::string type_name( tn_identity<std::basic_string_view<char8_t>>, std::string const& suffix )
{
return "std::u8string_view" + suffix;
}
#endif
#endif
// class templates
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<template<class...> class L, class... T> std::string type_name( tn_identity< L<T...> >, std::string const& suffix )
{
std::string tn = class_template_name< L<T...> >();
std::string st = tn_add_each<T...>();
return tn + '<' + st + '>' + suffix;
}
#else
template<template<class T1> class L, class T1> std::string type_name( tn_identity< L<T1> >, std::string const& suffix )
{
std::string tn = class_template_name< L<T1> >();
return tn + '<' + type_name( tn_identity<T1>(), "" ) + '>' + suffix;
}
template<template<class T1, class T2> class L, class T1, class T2> std::string type_name( tn_identity< L<T1, T2> >, std::string const& suffix )
{
std::string tn = class_template_name< L<T1, T2> >();
return tn + '<' + type_name( tn_identity<T1>(), "" ) + ", " + type_name( tn_identity<T2>(), "" ) + '>' + suffix;
}
#endif
// sequence containers
template<template<class T, class A> class L, class T> std::string type_name( tn_identity< L<T, std::allocator<T> > >, std::string const& suffix )
{
std::string tn = sequence_template_name< L<T, std::allocator<T> > >();
return tn + '<' + type_name( tn_identity<T>(), "" ) + '>' + suffix;
}
// set
template<template<class T, class Pr, class A> class L, class T> std::string type_name( tn_identity< L<T, std::less<T>, std::allocator<T> > >, std::string const& suffix )
{
std::string tn = set_template_name< L<T, std::less<T>, std::allocator<T> > >();
return tn + '<' + type_name( tn_identity<T>(), "" ) + '>' + suffix;
}
// map
template<template<class T, class U, class Pr, class A> class L, class T, class U> std::string type_name( tn_identity< L<T, U, std::less<T>, std::allocator<std::pair<T const, U> > > >, std::string const& suffix )
{
std::string tn = map_template_name< L<T, U, std::less<T>, std::allocator<std::pair<T const, U> > > >();
return tn + '<' + type_name( tn_identity<T>(), "" ) + ", " + type_name( tn_identity<U>(), "" ) + '>' + suffix;
}
#if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
// unordered_set
template<template<class T, class H, class Eq, class A> class L, class T> std::string type_name( tn_identity< L<T, std::hash<T>, std::equal_to<T>, std::allocator<T> > >, std::string const& suffix )
{
std::string tn = set_template_name< L<T, std::hash<T>, std::equal_to<T>, std::allocator<T> > >();
return tn + '<' + type_name( tn_identity<T>(), "" ) + '>' + suffix;
}
// unordered_map
template<template<class T, class U, class H, class Eq, class A> class L, class T, class U> std::string type_name( tn_identity< L<T, U, std::hash<T>, std::equal_to<T>, std::allocator<std::pair<T const, U> > > >, std::string const& suffix )
{
std::string tn = map_template_name< L<T, U, std::hash<T>, std::equal_to<T>, std::allocator<std::pair<T const, U> > > >();
return tn + '<' + type_name( tn_identity<T>(), "" ) + ", " + type_name( tn_identity<U>(), "" ) + '>' + suffix;
}
#endif
// array
template<template<class T, std::size_t N> class L, class T, std::size_t N> std::string type_name( tn_identity< L<T, N> >, std::string const& suffix )
{
std::string tn = array_template_name< L<T, N> >();
return tn + '<' + type_name( tn_identity<T>(), "" ) + ", " + tn_to_string( N ) + '>' + suffix;
}
} // namespace detail
template<class T> std::string type_name()
{
return core::detail::type_name( core::detail::tn_identity<T>(), "" );
}
} // namespace core
} // namespace boost
#endif // #ifndef BOOST_CORE_TYPE_NAME_HPP_INCLUDED

View File

@@ -26,6 +26,7 @@
#pragma once
#endif
#if (defined(__cpp_lib_uncaught_exceptions) && __cpp_lib_uncaught_exceptions >= 201411)
#if defined(__APPLE__)
#include <Availability.h>
// Apple systems only support std::uncaught_exceptions starting with specific versions:
@@ -34,16 +35,15 @@
// - tvOS >= 10.0
// - watchOS >= 3.0
// https://github.com/boostorg/core/issues/80
#if (defined(__cpp_lib_uncaught_exceptions) && __cpp_lib_uncaught_exceptions >= 201411) && \
( \
(defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200) || \
(defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 100000) \
)
#if (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200) || \
(defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 100000)
#define BOOST_CORE_HAS_UNCAUGHT_EXCEPTIONS
#endif
#else
#define BOOST_CORE_HAS_UNCAUGHT_EXCEPTIONS
#endif // defined(__APPLE__)
// Visual Studio 14.0 supports N4152 std::uncaught_exceptions() but doesn't define __cpp_lib_uncaught_exceptions
#elif (defined(__cpp_lib_uncaught_exceptions) && __cpp_lib_uncaught_exceptions >= 201411) || \
(defined(_MSC_VER) && _MSC_VER >= 1900)
#elif (defined(_MSC_VER) && _MSC_VER >= 1900)
#define BOOST_CORE_HAS_UNCAUGHT_EXCEPTIONS
#endif

View File

@@ -8,14 +8,15 @@
"Andrey Semashev"
],
"maintainers": [
"Peter Dimov <pdimov -at- pdimov.com>",
"Peter Dimov <pdimov -at- gmail.com>",
"Glen Fernandes <glenjofe -at- gmail.com>",
"Andrey Semashev <andrey.semashev -at- gmail.com>"
],
"description": "A collection of simple core utilities with minimal dependencies.",
"category": [
"Miscellaneous"
]
],
"cxxstd": "03"
},
{
"key": "utility/enable_if",
@@ -33,7 +34,8 @@
"maintainers": [
"Jaakko Jarvi <jarvi -at- cs.tamu.edu>",
"Jeremiah Willcock <jewillco -at- osl.iu.edu>"
]
],
"cxxstd": "03"
},
{
"key": "utility/swap",
@@ -49,7 +51,8 @@
],
"maintainers": [
"Joseph Gauterin <joseph.gauterin -at- googlemail.com>"
]
],
"cxxstd": "03"
},
{
"key": "bind/ref",
@@ -67,6 +70,7 @@
],
"category": [
"Function-objects"
]
],
"cxxstd": "03"
}
]

View File

@@ -35,7 +35,10 @@ compile-fail ref_rv_fail4.cpp ;
compile-fail ref_rv_fail5.cpp ;
compile-fail ref_implicit_fail.cpp ;
compile-fail ref_implicit_fail2.cpp ;
compile-fail ref_implicit_fail3.cpp ;
compile-fail ref_implicit_fail4.cpp ;
run ref_cv_test.cpp ;
run ref_conversion_test.cpp ;
run eif_constructors.cpp ;
run eif_dummy_arg_disambiguation.cpp ;
@@ -93,7 +96,11 @@ run lightweight_test_test4.cpp
: : : $(pedantic-errors) ;
run lightweight_test_test5.cpp
: : : $(pedantic-errors)
<toolset>gcc-4.4.7:<cxxflags>-Wno-sign-compare ;
<toolset>gcc-4.4.7:<cxxflags>-Wno-sign-compare
<toolset>gcc-4.4:<cxxflags>-Wno-sign-compare
;
run lightweight_test_test6.cpp
: : : $(pedantic-errors) ;
run-fail lightweight_test_all_eq_test.cpp ;
run-fail lightweight_test_all_with_fail.cpp ;
@@ -114,6 +121,7 @@ run-fail lightweight_test_fail11.cpp : ;
run-fail lightweight_test_fail12.cpp ;
run-fail lightweight_test_fail13.cpp ;
run-fail lightweight_test_fail14.cpp ;
run-fail lightweight_test_fail15.cpp ;
run-fail lightweight_test_lt_fail.cpp ;
run-fail lightweight_test_le_fail.cpp ;
run-fail lightweight_test_gt_fail.cpp ;
@@ -209,6 +217,12 @@ run test_lib_typeid.cpp lib_typeid : : : <link>static : test_lib_typeid_static ;
run test_lib_typeid.cpp lib_typeid : : : <link>shared <rtti>off : test_lib_typeid_shared_no_rtti ;
run test_lib_typeid.cpp lib_typeid : : : <link>static <rtti>off : test_lib_typeid_static_no_rtti ;
run test_lib_typeid2.cpp lib_typeid : : : <link>shared : test_lib_typeid2_shared ;
run test_lib_typeid2.cpp lib_typeid : : : <link>static : test_lib_typeid2_static ;
run test_lib_typeid2.cpp lib_typeid : : : <link>shared <rtti>off : test_lib_typeid2_shared_no_rtti ;
run test_lib_typeid2.cpp lib_typeid : : : <link>static <rtti>off : test_lib_typeid2_static_no_rtti ;
run uncaught_exceptions.cpp
: : : <exception-handling>on ;
run uncaught_exceptions_np.cpp
@@ -217,5 +231,21 @@ 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 : : : <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 type_name_test.cpp ;
use-project /boost/core/swap : ./swap ;
build-project ./swap ;

View File

@@ -27,7 +27,8 @@ int main()
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<int,
boost::allocator_size_type<A1<char> >::type>));
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<std::size_t,
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<
std::make_unsigned<std::ptrdiff_t>::type,
boost::allocator_size_type<A2<int> >::type>));
#endif
return boost::report_errors();

29
test/bit_cast_test.cpp Normal file
View File

@@ -0,0 +1,29 @@
// Test for boost/core/bit.hpp (bit_cast)
//
// Copyright 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/core/bit.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/cstdint.hpp>
#include <cstring>
int main()
{
{
float x = 0.89f;
boost::uint32_t y = boost::core::bit_cast<boost::uint32_t>( x );
BOOST_TEST( std::memcmp( &x, &y, sizeof(x) ) == 0 );
}
{
double x = 0.89;
boost::uint64_t y = boost::core::bit_cast<boost::uint64_t>( x );
BOOST_TEST( std::memcmp( &x, &y, sizeof(x) ) == 0 );
}
return boost::report_errors();
}

65
test/bit_ceil_test.cpp Normal file
View File

@@ -0,0 +1,65 @@
// Test for boost/core/bit.hpp (bit_ceil)
//
// Copyright 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/core/bit.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/core/detail/splitmix64.hpp>
#include <boost/cstdint.hpp>
#include <limits>
template<class T> void test_bit_ceil( T x )
{
if( !boost::core::has_single_bit( x ) )
{
x >>= 1;
}
T y = boost::core::bit_ceil( x );
if( x == 0 )
{
BOOST_TEST_EQ( y, 0 );
}
else
{
BOOST_TEST( boost::core::has_single_bit( y ) );
BOOST_TEST_GE( +y, +x );
BOOST_TEST_LT( y >> 1, +x );
}
}
int main()
{
{
test_bit_ceil( static_cast<unsigned char>( 0 ) );
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::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 ) );
}
boost::detail::splitmix64 rng;
for( int i = 0; i < 1000; ++i )
{
boost::uint64_t x = rng();
test_bit_ceil( static_cast<unsigned char>( x ) );
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 ) );
}
return boost::report_errors();
}

46
test/bit_countl_test.cpp Normal file
View File

@@ -0,0 +1,46 @@
// Test for boost/core/bit.hpp (countl_zero, countl_one)
//
// Copyright 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/core/bit.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/core/detail/splitmix64.hpp>
#include <boost/cstdint.hpp>
#include <limits>
template<class T> void test_countl( T x )
{
x |= static_cast<T>( 1 ) << ( std::numeric_limits<T>::digits - 1 );
for( int i = 0; i <= std::numeric_limits<T>::digits; ++i, x >>= 1 )
{
BOOST_TEST_EQ( boost::core::countl_zero( x ), i );
BOOST_TEST_EQ( boost::core::countl_one( static_cast<T>( ~x ) ), i );
}
}
int main()
{
test_countl( static_cast<unsigned char>( 0 ) );
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 ) );
boost::detail::splitmix64 rng;
for( int i = 0; i < 1000; ++i )
{
boost::uint64_t x = rng();
test_countl( static_cast<unsigned char>( x ) );
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 ) );
}
return boost::report_errors();
}

46
test/bit_countr_test.cpp Normal file
View File

@@ -0,0 +1,46 @@
// Test for boost/core/bit.hpp (countr_zero, countr_one)
//
// Copyright 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/core/bit.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/core/detail/splitmix64.hpp>
#include <boost/cstdint.hpp>
#include <limits>
template<class T> void test_countr( T x )
{
x |= 1;
for( int i = 0; i <= std::numeric_limits<T>::digits; ++i, x <<= 1 )
{
BOOST_TEST_EQ( boost::core::countr_zero( x ), i );
BOOST_TEST_EQ( boost::core::countr_one( static_cast<T>( ~x ) ), i );
}
}
int main()
{
test_countr( static_cast<unsigned char>( 0 ) );
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 ) );
boost::detail::splitmix64 rng;
for( int i = 0; i < 1000; ++i )
{
boost::uint64_t x = rng();
test_countr( static_cast<unsigned char>( x ) );
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 ) );
}
return boost::report_errors();
}

36
test/bit_endian_test.cpp Normal file
View File

@@ -0,0 +1,36 @@
// Test for boost/core/bit.hpp (bit_ceil)
//
// Copyright 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/core/bit.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/cstdint.hpp>
#include <cstring>
int main()
{
boost::uint64_t v = static_cast<boost::uint64_t>( 0x0102030405060708ull );
if( boost::core::endian::native == boost::core::endian::little )
{
unsigned char w[] = { 8, 7, 6, 5, 4, 3, 2, 1 };
BOOST_TEST( std::memcmp( &v, w, 8 ) == 0 );
}
else if( boost::core::endian::native == boost::core::endian::big )
{
unsigned char w[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
BOOST_TEST( std::memcmp( &v, w, 8 ) == 0 );
}
else
{
unsigned char w1[] = { 8, 7, 6, 5, 4, 3, 2, 1 };
BOOST_TEST( std::memcmp( &v, w1, 8 ) != 0 );
unsigned char w2[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
BOOST_TEST( std::memcmp( &v, w2, 8 ) != 0 );
}
return boost::report_errors();
}

53
test/bit_floor_test.cpp Normal file
View File

@@ -0,0 +1,53 @@
// Test for boost/core/bit.hpp (bit_floor)
//
// Copyright 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/core/bit.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/core/detail/splitmix64.hpp>
#include <boost/cstdint.hpp>
#include <limits>
template<class T> void test_bit_floor( T x )
{
T y = boost::core::bit_floor( x );
if( x == 0 )
{
BOOST_TEST_EQ( y, 0 );
}
else
{
BOOST_TEST( boost::core::has_single_bit( y ) );
BOOST_TEST_LE( +y, +x );
BOOST_TEST_GT( +y, x >> 1 );
}
}
int main()
{
{
test_bit_floor( static_cast<unsigned char>( 0 ) );
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 ) );
}
boost::detail::splitmix64 rng;
for( int i = 0; i < 1000; ++i )
{
boost::uint64_t x = rng();
test_bit_floor( static_cast<unsigned char>( x ) );
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 ) );
}
return boost::report_errors();
}

View File

@@ -0,0 +1,46 @@
// Test for boost/core/bit.hpp (bit_ceil)
//
// Copyright 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/core/bit.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/core/detail/splitmix64.hpp>
#include <boost/cstdint.hpp>
#include <limits>
#include <iostream>
template<class T> void test_popcount( T x )
{
int k = 0;
for( T y = x; y; y &= y - 1, ++k );
BOOST_TEST_EQ( boost::core::popcount( x ), k ) || ( std::cerr << "x: " << +x << std::endl );
}
int main()
{
{
test_popcount( static_cast<unsigned char>( 0 ) );
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 ) );
}
boost::detail::splitmix64 rng;
for( int i = 0; i < 1000; ++i )
{
boost::uint64_t x = rng();
test_popcount( static_cast<unsigned char>( x ) );
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 ) );
}
return boost::report_errors();
}

175
test/bit_rotate_test.cpp Normal file
View File

@@ -0,0 +1,175 @@
// Test for boost/core/bit.hpp (rotl, rotr)
//
// Copyright 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/core/bit.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/core/detail/splitmix64.hpp>
#include <boost/cstdint.hpp>
#include <limits>
int const M = 256;
template<class T> void test_rotate( T x )
{
for( int i = 0; i < M; ++i )
{
BOOST_TEST_EQ( +boost::core::rotl( x, i ), +boost::core::rotr( x, -i ) );
BOOST_TEST_EQ( +boost::core::rotl( x, -i ), +boost::core::rotr( x, i ) );
unsigned const width = std::numeric_limits<T>::digits;
unsigned r = i & ( width - 1 );
if( r == 0 )
{
BOOST_TEST_EQ( +boost::core::rotl( x, i ), +x );
BOOST_TEST_EQ( +boost::core::rotr( x, i ), +x );
}
else
{
BOOST_TEST_EQ( +boost::core::rotl( x, i ), +static_cast<T>( (x << r) | (x >> (width - r)) ) );
BOOST_TEST_EQ( +boost::core::rotr( x, i ), +static_cast<T>( (x >> r) | (x << (width - r)) ) );
}
}
}
int main()
{
{
boost::uint8_t x = 0x11;
BOOST_TEST_EQ( +boost::core::rotl( x, 1 ), 0x22 );
BOOST_TEST_EQ( +boost::core::rotr( x, 1 ), 0x88 );
x = 0x22;
BOOST_TEST_EQ( +boost::core::rotl( x, 1 ), 0x44 );
BOOST_TEST_EQ( +boost::core::rotr( x, 1 ), 0x11 );
x = 0x44;
BOOST_TEST_EQ( +boost::core::rotl( x, 1 ), 0x88 );
BOOST_TEST_EQ( +boost::core::rotr( x, 1 ), 0x22 );
x = 0x88;
BOOST_TEST_EQ( +boost::core::rotl( x, 1 ), 0x11 );
BOOST_TEST_EQ( +boost::core::rotr( x, 1 ), 0x44 );
}
{
boost::uint16_t x = 0x1111;
BOOST_TEST_EQ( +boost::core::rotl( x, 1 ), 0x2222 );
BOOST_TEST_EQ( +boost::core::rotr( x, 1 ), 0x8888 );
x = 0x2222;
BOOST_TEST_EQ( +boost::core::rotl( x, 1 ), 0x4444 );
BOOST_TEST_EQ( +boost::core::rotr( x, 1 ), 0x1111 );
x = 0x4444;
BOOST_TEST_EQ( +boost::core::rotl( x, 1 ), 0x8888 );
BOOST_TEST_EQ( +boost::core::rotr( x, 1 ), 0x2222 );
x = 0x8888;
BOOST_TEST_EQ( +boost::core::rotl( x, 1 ), 0x1111 );
BOOST_TEST_EQ( +boost::core::rotr( x, 1 ), 0x4444 );
}
{
boost::uint32_t x = 0x11111111;
BOOST_TEST_EQ( +boost::core::rotl( x, 1 ), 0x22222222 );
BOOST_TEST_EQ( +boost::core::rotr( x, 1 ), 0x88888888 );
x = 0x22222222;
BOOST_TEST_EQ( +boost::core::rotl( x, 1 ), 0x44444444 );
BOOST_TEST_EQ( +boost::core::rotr( x, 1 ), 0x11111111 );
x = 0x44444444;
BOOST_TEST_EQ( +boost::core::rotl( x, 1 ), 0x88888888 );
BOOST_TEST_EQ( +boost::core::rotr( x, 1 ), 0x22222222 );
x = 0x88888888;
BOOST_TEST_EQ( +boost::core::rotl( x, 1 ), 0x11111111 );
BOOST_TEST_EQ( +boost::core::rotr( x, 1 ), 0x44444444 );
}
{
boost::uint64_t x = 0x1111111111111111;
BOOST_TEST_EQ( +boost::core::rotl( x, 1 ), 0x2222222222222222 );
BOOST_TEST_EQ( +boost::core::rotr( x, 1 ), 0x8888888888888888 );
x = 0x2222222222222222;
BOOST_TEST_EQ( +boost::core::rotl( x, 1 ), 0x4444444444444444 );
BOOST_TEST_EQ( +boost::core::rotr( x, 1 ), 0x1111111111111111 );
x = 0x4444444444444444;
BOOST_TEST_EQ( +boost::core::rotl( x, 1 ), 0x8888888888888888 );
BOOST_TEST_EQ( +boost::core::rotr( x, 1 ), 0x2222222222222222 );
x = 0x8888888888888888;
BOOST_TEST_EQ( +boost::core::rotl( x, 1 ), 0x1111111111111111 );
BOOST_TEST_EQ( +boost::core::rotr( x, 1 ), 0x4444444444444444 );
}
for( int i = -M; i <= M; ++i )
{
{
unsigned char x = 0;
BOOST_TEST_EQ( +boost::core::rotl( x, i ), +x );
BOOST_TEST_EQ( +boost::core::rotr( x, i ), +x );
}
{
unsigned short x = 0;
BOOST_TEST_EQ( boost::core::rotl( x, i ), x );
BOOST_TEST_EQ( boost::core::rotr( x, i ), x );
}
{
unsigned int x = 0;
BOOST_TEST_EQ( boost::core::rotl( x, i ), x );
BOOST_TEST_EQ( boost::core::rotr( x, i ), x );
}
{
unsigned long x = 0;
BOOST_TEST_EQ( boost::core::rotl( x, i ), x );
BOOST_TEST_EQ( boost::core::rotr( x, i ), x );
}
{
unsigned long long x = 0;
BOOST_TEST_EQ( boost::core::rotl( x, i ), x );
BOOST_TEST_EQ( boost::core::rotr( x, i ), x );
}
}
boost::detail::splitmix64 rng;
for( int i = 0; i < 1000; ++i )
{
boost::uint64_t x = rng();
test_rotate( static_cast<unsigned char>( x ) );
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 ) );
}
return boost::report_errors();
}

94
test/bit_width_test.cpp Normal file
View File

@@ -0,0 +1,94 @@
// Test for boost/core/bit.hpp (bit_width)
//
// Copyright 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/core/bit.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/core/detail/splitmix64.hpp>
#include <boost/cstdint.hpp>
#include <limits>
template<class T> void test_width( T x )
{
BOOST_TEST_EQ( boost::core::bit_width( x ), std::numeric_limits<T>::digits - boost::core::countl_zero( x ) );
}
int main()
{
{
boost::uint8_t x = 0;
BOOST_TEST_EQ( boost::core::bit_width( x ), 0 );
x = 1;
for( int i = 0; i < 8; ++i, x <<= 1 )
{
BOOST_TEST_EQ( boost::core::bit_width( x ), i+1 );
BOOST_TEST_EQ( boost::core::bit_width( static_cast<boost::uint8_t>( x | ( x >> 1 ) ) ), i+1 );
BOOST_TEST_EQ( boost::core::bit_width( static_cast<boost::uint8_t>( x | ( x >> 2 ) ) ), i+1 );
}
}
{
boost::uint16_t x = 0;
BOOST_TEST_EQ( boost::core::bit_width( x ), 0 );
x = 1;
for( int i = 0; i < 16; ++i, x <<= 1 )
{
BOOST_TEST_EQ( boost::core::bit_width( x ), i+1 );
BOOST_TEST_EQ( boost::core::bit_width( static_cast<boost::uint16_t>( x | ( x >> 1 ) ) ), i+1 );
BOOST_TEST_EQ( boost::core::bit_width( static_cast<boost::uint16_t>( x | ( x >> 2 ) ) ), i+1 );
}
}
{
boost::uint32_t x = 0;
BOOST_TEST_EQ( boost::core::bit_width( x ), 0 );
x = 1;
for( int i = 0; i < 32; ++i, x <<= 1 )
{
BOOST_TEST_EQ( boost::core::bit_width( x ), i+1 );
BOOST_TEST_EQ( boost::core::bit_width( static_cast<boost::uint32_t>( x | ( x >> 1 ) ) ), i+1 );
BOOST_TEST_EQ( boost::core::bit_width( static_cast<boost::uint32_t>( x | ( x >> 2 ) ) ), i+1 );
}
}
{
boost::uint64_t x = 0;
BOOST_TEST_EQ( boost::core::bit_width( x ), 0 );
x = 1;
for( int i = 0; i < 64; ++i, x <<= 1 )
{
BOOST_TEST_EQ( boost::core::bit_width( x ), i+1 );
BOOST_TEST_EQ( boost::core::bit_width( static_cast<boost::uint64_t>( x | ( x >> 1 ) ) ), i+1 );
BOOST_TEST_EQ( boost::core::bit_width( static_cast<boost::uint64_t>( x | ( x >> 2 ) ) ), i+1 );
}
}
boost::detail::splitmix64 rng;
for( int i = 0; i < 1000; ++i )
{
boost::uint64_t x = rng();
test_width( static_cast<unsigned char>( x ) );
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 ) );
}
return boost::report_errors();
}

296
test/cmath_test.cpp Normal file
View File

@@ -0,0 +1,296 @@
// Test for boost/core/cmath.hpp
//
// Copyright 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/core/cmath.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/config.hpp>
#include <boost/config/workaround.hpp>
#include <limits>
#include <cfloat>
template<class T> void test_positive_normal( T x )
{
BOOST_TEST( boost::core::isfinite( x ) );
BOOST_TEST( !boost::core::isinf( x ) );
BOOST_TEST( !boost::core::isnan( x ) );
BOOST_TEST( boost::core::isnormal( x ) );
BOOST_TEST_EQ( boost::core::fpclassify( x ), boost::core::fp_normal );
BOOST_TEST( !boost::core::signbit( x ) );
BOOST_TEST_EQ( boost::core::copysign( T(+2), x ), T(+2) );
BOOST_TEST_EQ( boost::core::copysign( T(-2), x ), T(+2) );
}
template<class T> void test_negative_normal( T x )
{
BOOST_TEST( boost::core::isfinite( x ) );
BOOST_TEST( !boost::core::isinf( x ) );
BOOST_TEST( !boost::core::isnan( x ) );
BOOST_TEST( boost::core::isnormal( x ) );
BOOST_TEST_EQ( boost::core::fpclassify( x ), boost::core::fp_normal );
BOOST_TEST( boost::core::signbit( x ) );
BOOST_TEST_EQ( boost::core::copysign( T(+2), x ), T(-2) );
BOOST_TEST_EQ( boost::core::copysign( T(-2), x ), T(-2) );
}
template<class T> void test_positive_zero( T x )
{
BOOST_TEST( boost::core::isfinite( x ) );
BOOST_TEST( !boost::core::isinf( x ) );
BOOST_TEST( !boost::core::isnan( x ) );
BOOST_TEST( !boost::core::isnormal( x ) );
BOOST_TEST_EQ( boost::core::fpclassify( x ), boost::core::fp_zero );
BOOST_TEST( !boost::core::signbit( x ) );
BOOST_TEST_EQ( boost::core::copysign( T(+2), x ), T(+2) );
BOOST_TEST_EQ( boost::core::copysign( T(-2), x ), T(+2) );
}
template<class T> void test_negative_zero( T x )
{
BOOST_TEST( boost::core::isfinite( x ) );
BOOST_TEST( !boost::core::isinf( x ) );
BOOST_TEST( !boost::core::isnan( x ) );
BOOST_TEST( !boost::core::isnormal( x ) );
BOOST_TEST_EQ( boost::core::fpclassify( x ), boost::core::fp_zero );
#if defined(BOOST_CORE_USE_GENERIC_CMATH) && BOOST_WORKAROUND(BOOST_GCC, < 40700)
// g++ 4.4, 4.6 fail these tests with optimizations on
#else
BOOST_TEST( boost::core::signbit( x ) );
BOOST_TEST_EQ( boost::core::copysign( T(+2), x ), T(-2) );
BOOST_TEST_EQ( boost::core::copysign( T(-2), x ), T(-2) );
#endif
}
template<class T> void test_positive_infinity( T x )
{
BOOST_TEST( !boost::core::isfinite( x ) );
BOOST_TEST( boost::core::isinf( x ) );
BOOST_TEST( !boost::core::isnan( x ) );
BOOST_TEST( !boost::core::isnormal( x ) );
BOOST_TEST_EQ( boost::core::fpclassify( x ), boost::core::fp_infinite );
BOOST_TEST( !boost::core::signbit( x ) );
BOOST_TEST_EQ( boost::core::copysign( T(+2), x ), T(+2) );
BOOST_TEST_EQ( boost::core::copysign( T(-2), x ), T(+2) );
}
template<class T> void test_negative_infinity( T x )
{
BOOST_TEST( !boost::core::isfinite( x ) );
BOOST_TEST( boost::core::isinf( x ) );
BOOST_TEST( !boost::core::isnan( x ) );
BOOST_TEST( !boost::core::isnormal( x ) );
BOOST_TEST_EQ( boost::core::fpclassify( x ), boost::core::fp_infinite );
BOOST_TEST( boost::core::signbit( x ) );
BOOST_TEST_EQ( boost::core::copysign( T(+2), x ), T(-2) );
BOOST_TEST_EQ( boost::core::copysign( T(-2), x ), T(-2) );
}
template<class T> void test_positive_nan( T x )
{
BOOST_TEST( !boost::core::isfinite( x ) );
BOOST_TEST( !boost::core::isinf( x ) );
BOOST_TEST( boost::core::isnan( x ) );
BOOST_TEST( !boost::core::isnormal( x ) );
BOOST_TEST_EQ( boost::core::fpclassify( x ), boost::core::fp_nan );
BOOST_TEST( !boost::core::signbit( x ) );
BOOST_TEST_EQ( boost::core::copysign( T(+2), x ), T(+2) );
BOOST_TEST_EQ( boost::core::copysign( T(-2), x ), T(+2) );
}
template<class T> void test_negative_nan( T x )
{
BOOST_TEST( !boost::core::isfinite( x ) );
BOOST_TEST( !boost::core::isinf( x ) );
BOOST_TEST( boost::core::isnan( x ) );
BOOST_TEST( !boost::core::isnormal( x ) );
BOOST_TEST_EQ( boost::core::fpclassify( x ), boost::core::fp_nan );
BOOST_TEST( boost::core::signbit( x ) );
BOOST_TEST_EQ( boost::core::copysign( T(+2), x ), T(-2) );
BOOST_TEST_EQ( boost::core::copysign( T(-2), x ), T(-2) );
}
template<class T> void test_positive_subnormal( T x )
{
BOOST_TEST( boost::core::isfinite( x ) );
BOOST_TEST( !boost::core::isinf( x ) );
BOOST_TEST( !boost::core::isnan( x ) );
BOOST_TEST( !boost::core::isnormal( x ) );
BOOST_TEST_EQ( boost::core::fpclassify( x ), boost::core::fp_subnormal );
BOOST_TEST( !boost::core::signbit( x ) );
BOOST_TEST_EQ( boost::core::copysign( T(+2), x ), T(+2) );
BOOST_TEST_EQ( boost::core::copysign( T(-2), x ), T(+2) );
}
template<class T> void test_negative_subnormal( T x )
{
BOOST_TEST( boost::core::isfinite( x ) );
BOOST_TEST( !boost::core::isinf( x ) );
BOOST_TEST( !boost::core::isnan( x ) );
BOOST_TEST( !boost::core::isnormal( x ) );
BOOST_TEST_EQ( boost::core::fpclassify( x ), boost::core::fp_subnormal );
BOOST_TEST( boost::core::signbit( x ) );
BOOST_TEST_EQ( boost::core::copysign( T(+2), x ), T(-2) );
BOOST_TEST_EQ( boost::core::copysign( T(-2), x ), T(-2) );
}
template<class T> void test_positive_normal_( T x )
{
test_positive_normal( x );
test_positive_normal( boost::core::copysign( x, T(+1) ) );
test_negative_normal( boost::core::copysign( x, T(-1) ) );
}
template<class T> void test_negative_normal_( T x )
{
test_negative_normal( x );
test_positive_normal( boost::core::copysign( x, T(+1) ) );
test_negative_normal( boost::core::copysign( x, T(-1) ) );
}
template<class T> void test_positive_zero_( T x )
{
test_positive_zero( x );
test_positive_zero( boost::core::copysign( x, T(+1) ) );
test_negative_zero( boost::core::copysign( x, T(-1) ) );
}
template<class T> void test_negative_zero_( T x )
{
test_negative_zero( x );
test_positive_zero( boost::core::copysign( x, T(+1) ) );
test_negative_zero( boost::core::copysign( x, T(-1) ) );
}
template<class T> void test_positive_infinity_( T x )
{
test_positive_infinity( x );
test_positive_infinity( boost::core::copysign( x, T(+1) ) );
test_negative_infinity( boost::core::copysign( x, T(-1) ) );
}
template<class T> void test_negative_infinity_( T x )
{
test_negative_infinity( x );
test_positive_infinity( boost::core::copysign( x, T(+1) ) );
test_negative_infinity( boost::core::copysign( x, T(-1) ) );
}
template<class T> void test_positive_nan_( T x )
{
test_positive_nan( x );
test_positive_nan( boost::core::copysign( x, T(+1) ) );
test_negative_nan( boost::core::copysign( x, T(-1) ) );
}
template<class T> void test_negative_nan_( T x )
{
test_negative_nan( x );
test_positive_nan( boost::core::copysign( x, T(+1) ) );
test_negative_nan( boost::core::copysign( x, T(-1) ) );
}
template<class T> void test_positive_subnormal_( T x )
{
test_positive_subnormal( x );
test_positive_subnormal( boost::core::copysign( x, T(+1) ) );
test_negative_subnormal( boost::core::copysign( x, T(-1) ) );
}
template<class T> void test_negative_subnormal_( T x )
{
test_negative_subnormal( x );
test_positive_subnormal( boost::core::copysign( x, T(+1) ) );
test_negative_subnormal( boost::core::copysign( x, T(-1) ) );
}
int main()
{
// float
test_positive_normal_( +1.0f );
test_negative_normal_( -1.0f );
test_positive_normal_( FLT_MIN );
test_negative_normal_( -FLT_MIN );
test_positive_normal_( FLT_MAX );
test_negative_normal_( -FLT_MAX );
test_positive_zero_( +0.0f );
test_negative_zero_( -0.0f );
test_positive_infinity_( std::numeric_limits<float>::infinity() );
test_negative_infinity_( -std::numeric_limits<float>::infinity() );
test_positive_nan_( std::numeric_limits<float>::quiet_NaN() );
test_negative_nan_( boost::core::copysign( std::numeric_limits<float>::quiet_NaN(), -1.0f ) );
test_positive_subnormal_( FLT_MIN / 2 );
test_negative_subnormal_( -FLT_MIN / 2 );
// double
test_positive_normal_( +1.0 );
test_negative_normal_( -1.0 );
test_positive_normal_( DBL_MIN );
test_negative_normal_( -DBL_MIN );
test_positive_normal_( DBL_MAX );
test_negative_normal_( -DBL_MAX );
test_positive_zero_( +0.0 );
test_negative_zero_( -0.0 );
test_positive_infinity_( std::numeric_limits<double>::infinity() );
test_negative_infinity_( -std::numeric_limits<double>::infinity() );
test_positive_nan_( std::numeric_limits<double>::quiet_NaN() );
test_negative_nan_( boost::core::copysign( std::numeric_limits<double>::quiet_NaN(), -1.0 ) );
test_positive_subnormal_( DBL_MIN / 2 );
test_negative_subnormal_( -DBL_MIN / 2 );
// long double
test_positive_normal_( +1.0l );
test_negative_normal_( -1.0l );
test_positive_normal_( LDBL_MIN );
test_negative_normal_( -LDBL_MIN );
test_positive_normal_( LDBL_MAX );
test_negative_normal_( -LDBL_MAX );
test_positive_zero_( +0.0l );
test_negative_zero_( -0.0l );
test_positive_infinity_( std::numeric_limits<long double>::infinity() );
test_negative_infinity_( -std::numeric_limits<long double>::infinity() );
test_positive_nan_( std::numeric_limits<long double>::quiet_NaN() );
test_negative_nan_( boost::core::copysign( std::numeric_limits<long double>::quiet_NaN(), -1.0l ) );
test_positive_subnormal_( LDBL_MIN / 2 );
test_negative_subnormal_( -LDBL_MIN / 2 );
return boost::report_errors();
}

View File

@@ -0,0 +1,110 @@
// Test for boost/core/bit.hpp (has_single_bit)
//
// Copyright 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/core/bit.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/core/detail/splitmix64.hpp>
#include <boost/cstdint.hpp>
#include <limits>
template<class T> void test_single_bit( T x )
{
BOOST_TEST_EQ( boost::core::has_single_bit( x ), boost::core::popcount( x ) == 1 );
}
int main()
{
{
boost::uint8_t x = 0;
BOOST_TEST_EQ( boost::core::has_single_bit( x ), false );
x = 1;
BOOST_TEST_EQ( boost::core::has_single_bit( x ), true );
x = 2;
for( int i = 1; i < 8; ++i, x <<= 1 )
{
BOOST_TEST_EQ( boost::core::has_single_bit( x ), true );
BOOST_TEST_EQ( boost::core::has_single_bit( static_cast<boost::uint8_t>( x | ( x >> 1 ) ) ), false );
BOOST_TEST_EQ( boost::core::has_single_bit( static_cast<boost::uint8_t>( x | ( x >> 1 ) | ( x >> 2 ) ) ), false );
}
}
{
boost::uint16_t x = 0;
BOOST_TEST_EQ( boost::core::has_single_bit( x ), false );
x = 1;
BOOST_TEST_EQ( boost::core::has_single_bit( x ), true );
x = 2;
for( int i = 1; i < 16; ++i, x <<= 1 )
{
BOOST_TEST_EQ( boost::core::has_single_bit( x ), true );
BOOST_TEST_EQ( boost::core::has_single_bit( static_cast<boost::uint16_t>( x | ( x >> 1 ) ) ), false );
BOOST_TEST_EQ( boost::core::has_single_bit( static_cast<boost::uint16_t>( x | ( x >> 1 ) | ( x >> 2 ) ) ), false );
}
}
{
boost::uint32_t x = 0;
BOOST_TEST_EQ( boost::core::has_single_bit( x ), false );
x = 1;
BOOST_TEST_EQ( boost::core::has_single_bit( x ), true );
x = 2;
for( int i = 1; i < 32; ++i, x <<= 1 )
{
BOOST_TEST_EQ( boost::core::has_single_bit( x ), true );
BOOST_TEST_EQ( boost::core::has_single_bit( static_cast<boost::uint32_t>( x | ( x >> 1 ) ) ), false );
BOOST_TEST_EQ( boost::core::has_single_bit( static_cast<boost::uint32_t>( x | ( x >> 1 ) | ( x >> 2 ) ) ), false );
}
}
{
boost::uint64_t x = 0;
BOOST_TEST_EQ( boost::core::has_single_bit( x ), false );
x = 1;
BOOST_TEST_EQ( boost::core::has_single_bit( x ), true );
x = 2;
for( int i = 1; i < 64; ++i, x <<= 1 )
{
BOOST_TEST_EQ( boost::core::has_single_bit( x ), true );
BOOST_TEST_EQ( boost::core::has_single_bit( static_cast<boost::uint64_t>( x | ( x >> 1 ) ) ), false );
BOOST_TEST_EQ( boost::core::has_single_bit( static_cast<boost::uint64_t>( x | ( x >> 1 ) | ( x >> 2 ) ) ), false );
}
}
boost::detail::splitmix64 rng;
for( int i = 0; i < 1000; ++i )
{
boost::uint64_t x = rng();
test_single_bit( static_cast<unsigned char>( x ) );
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 ) );
}
return boost::report_errors();
}

View File

@@ -15,3 +15,12 @@ EXPORT boost::core::typeinfo const & get_typeid_int()
{
return BOOST_CORE_TYPEID( int );
}
struct BOOST_SYMBOL_VISIBLE X
{
};
EXPORT boost::core::typeinfo const & get_typeid_X()
{
return BOOST_CORE_TYPEID( X );
}

View File

@@ -0,0 +1,37 @@
// Test BOOST_TEST_NE with character types
//
// Copyright 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/core/lightweight_test.hpp>
#include <boost/config.hpp>
int main()
{
BOOST_TEST_NE( 'A', 'A' );
BOOST_TEST_NE( (char)1, (char)1 );
BOOST_TEST_NE( (unsigned char)1, (unsigned char)1 );
BOOST_TEST_NE( (signed char)-1, (signed char)-1 );
BOOST_TEST_NE( L'A', L'A' );
BOOST_TEST_NE( (wchar_t)1, (wchar_t)1 );
int exp = 6;
#if !defined(BOOST_NO_CXX11_CHAR16_T)
BOOST_TEST_NE( (char16_t)1, (char16_t)1 );
++exp;
#endif
#if !defined(BOOST_NO_CXX11_CHAR32_T)
BOOST_TEST_NE( (char32_t)1, (char32_t)1 );
++exp;
#endif
return boost::report_errors() == exp;
}

View File

@@ -0,0 +1,33 @@
// Test BOOST_TEST_EQ with character types
//
// Copyright 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/core/lightweight_test.hpp>
#include <boost/config.hpp>
int main()
{
BOOST_TEST_EQ( 'A', 'A' );
BOOST_TEST_EQ( (char)1, (char)1 );
BOOST_TEST_EQ( (unsigned char)1, (unsigned char)1 );
BOOST_TEST_EQ( (signed char)-1, (signed char)-1 );
BOOST_TEST_EQ( L'A', L'A' );
BOOST_TEST_EQ( (wchar_t)1, (wchar_t)1 );
#if !defined(BOOST_NO_CXX11_CHAR16_T)
BOOST_TEST_EQ( (char16_t)1, (char16_t)1 );
#endif
#if !defined(BOOST_NO_CXX11_CHAR32_T)
BOOST_TEST_EQ( (char32_t)1, (char32_t)1 );
#endif
return boost::report_errors();
}

View File

@@ -0,0 +1,39 @@
// Implicit conversions between compatible reference wrappers
//
// Copyright 2020 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/ref.hpp>
#include <boost/core/lightweight_test.hpp>
struct X
{
};
struct Y: public X
{
};
void f1( boost::reference_wrapper<X> r, Y * p )
{
BOOST_TEST_EQ( r.get_pointer(), p );
}
void f2( boost::reference_wrapper<int const> r, int * p )
{
BOOST_TEST_EQ( r.get_pointer(), p );
}
int main()
{
Y y;
f1( boost::ref(y), &y );
int i = 0;
f2( boost::ref(i), &i );
return boost::report_errors();
}

View File

@@ -0,0 +1,29 @@
//
// Incompatible reference_wrappers must not implicitly convert to each other
//
// Copyright 2020 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
#include <boost/ref.hpp>
struct X
{
};
struct Y
{
};
void f( boost::reference_wrapper<X> )
{
}
int main()
{
Y y;
f( boost::ref(y) ); // should fail
}

View File

@@ -0,0 +1,21 @@
//
// Incompatible reference_wrappers must not implicitly convert to each other
//
// Copyright 2020 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
#include <boost/ref.hpp>
void f( boost::reference_wrapper< int const > )
{
}
int main()
{
long y = 0;
f( boost::ref(y) ); // should fail
}

34
test/test_lib_typeid2.cpp Normal file
View File

@@ -0,0 +1,34 @@
// Copyright 2018, 2021 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
#include <boost/core/typeinfo.hpp>
#include <boost/core/lightweight_test.hpp>
boost::core::typeinfo const & get_typeid_X();
struct BOOST_SYMBOL_VISIBLE X
{
};
struct Y
{
};
int main()
{
boost::core::typeinfo const & tx = BOOST_CORE_TYPEID( X );
boost::core::typeinfo const & ty = BOOST_CORE_TYPEID( Y );
boost::core::typeinfo const & tx2 = get_typeid_X();
BOOST_TEST( tx2 == tx );
BOOST_TEST( tx2 != ty );
BOOST_TEST( !tx2.before( tx ) );
BOOST_TEST( !tx.before( tx2 ) );
BOOST_TEST( tx2.before( ty ) != ty.before( tx2 ) );
return boost::report_errors();
}

357
test/type_name_test.cpp Normal file
View File

@@ -0,0 +1,357 @@
// Copyright 2021 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/core/type_name.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/config.hpp>
#include <string>
#include <vector>
#include <list>
#include <deque>
#include <set>
#include <map>
#include <utility>
#include <cstddef>
#include <iosfwd>
#if !defined(BOOST_NO_CXX11_HDR_UNORDERED_SET)
# include <unordered_set>
#endif
#if !defined(BOOST_NO_CXX11_HDR_UNORDERED_MAP)
# include <unordered_map>
#endif
#if !defined(BOOST_NO_CXX11_HDR_ARRAY)
# include <array>
#endif
#if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
# include <string_view>
#endif
//
#define TEST(...) BOOST_TEST_EQ((boost::core::type_name<__VA_ARGS__>()), std::string(#__VA_ARGS__))
struct A
{
};
class B
{
};
template<class T1, class T2> struct X
{
};
enum E1
{
e1
};
#if !defined(BOOST_NO_CXX11_SCOPED_ENUMS)
enum class E2
{
e2
};
#endif
struct Ch
{
};
int main()
{
TEST(signed char);
TEST(unsigned char);
TEST(short);
TEST(unsigned short);
TEST(int);
TEST(unsigned);
TEST(long);
TEST(unsigned long);
TEST(long long);
TEST(unsigned long long);
TEST(char);
TEST(wchar_t);
#if !defined(BOOST_NO_CXX11_CHAR16_T)
TEST(char16_t);
#endif
#if !defined(BOOST_NO_CXX11_CHAR16_T)
TEST(char32_t);
#endif
#if defined(__cpp_char8_t) && __cpp_char8_t >= 201811L
TEST(char8_t);
#endif
#if defined(__cpp_lib_byte) && __cpp_lib_byte >= 201603L
TEST(std::byte);
#endif
TEST(bool);
TEST(float);
TEST(double);
TEST(long double);
TEST(void);
TEST(void const);
TEST(void volatile);
TEST(void const volatile);
TEST(A);
TEST(B);
TEST(E1);
#if !defined(BOOST_NO_CXX11_SCOPED_ENUMS)
TEST(E2);
#endif
TEST(A const);
TEST(A volatile);
TEST(A const volatile);
TEST(B&);
TEST(B const&);
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
TEST(B&&);
TEST(B const&&);
#endif
TEST(A*);
TEST(B const* volatile*);
TEST(void*);
TEST(void const* volatile*);
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
TEST(void());
TEST(int(float, A, B*));
TEST(void(*)());
TEST(void(**)());
TEST(void(***)());
TEST(void(* const* const*)());
TEST(void(* const* const&)());
TEST(void(&)());
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
TEST(void(&&)());
#endif
#if !defined(BOOST_MSVC) || BOOST_MSVC >= 1900
TEST(void() const);
TEST(void() volatile);
TEST(void() const volatile);
#endif
#if !defined(BOOST_NO_CXX11_REF_QUALIFIERS)
TEST(void() &);
TEST(void() const &);
TEST(void() volatile &);
TEST(void() const volatile &);
TEST(void() &&);
TEST(void() const &&);
TEST(void() volatile &&);
TEST(void() const volatile &&);
#endif
#if defined( __cpp_noexcept_function_type ) || defined( _NOEXCEPT_TYPES_SUPPORTED )
TEST(void() noexcept);
TEST(void() const noexcept);
TEST(void() volatile noexcept);
TEST(void() const volatile noexcept);
TEST(void() & noexcept);
TEST(void() const & noexcept);
TEST(void() volatile & noexcept);
TEST(void() const volatile & noexcept);
TEST(void() && noexcept);
TEST(void() const && noexcept);
TEST(void() volatile && noexcept);
TEST(void() const volatile && noexcept);
#endif
#endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
TEST(A[]);
TEST(A const[]);
TEST(A volatile[]);
TEST(A const volatile[]);
#if !defined(BOOST_MSVC) || BOOST_MSVC >= 1500
TEST(A(&)[]);
#endif
TEST(A const(***)[]);
TEST(B[1]);
TEST(B const[1]);
TEST(B volatile[1]);
TEST(B const volatile[1]);
TEST(B(&)[1]);
TEST(B const(***)[1]);
TEST(A[][2][3]);
TEST(A const[][2][3]);
#if !defined(BOOST_MSVC) || BOOST_MSVC >= 1500
TEST(A(&)[][2][3]);
#endif
TEST(A const(***)[][2][3]);
TEST(B[1][2][3]);
TEST(B const volatile[1][2][3]);
TEST(B(&)[1][2][3]);
TEST(B const volatile(***)[1][2][3]);
TEST(int A::*);
TEST(int const B::*);
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
TEST(void(A::*)());
TEST(void(A::*)() const);
TEST(void(A::*)() volatile);
TEST(void(A::*)() const volatile);
#endif
#if !defined(BOOST_NO_CXX11_REF_QUALIFIERS)
TEST(void(A::*)() &);
TEST(void(A::*)() const &&);
#endif
#if defined( __cpp_noexcept_function_type ) || defined( _NOEXCEPT_TYPES_SUPPORTED )
TEST(void(A::*)() volatile & noexcept);
TEST(void(A::*)() const volatile && noexcept);
#endif
#if !defined(BOOST_NO_CXX11_NULLPTR)
TEST(std::nullptr_t);
#endif
TEST(std::pair<A, B>);
TEST(std::pair<A const*, B*> volatile&);
TEST(std::basic_string<Ch>);
TEST(std::string);
TEST(std::wstring);
#if BOOST_CXX_VERSION >= 201100L
TEST(std::u16string);
TEST(std::u32string);
#endif
#if BOOST_CXX_VERSION >= 202000L
TEST(std::u8string);
#endif
TEST(X<A, B>);
TEST(X<A const&, B&> volatile&);
TEST(std::vector<int>);
TEST(std::vector<A>);
TEST(std::vector<std::string>);
TEST(std::list<int>);
TEST(std::list<B>);
TEST(std::list<std::wstring>);
TEST(std::deque<int>);
TEST(std::deque<A>);
TEST(std::deque<std::string>);
TEST(std::set<int>);
TEST(std::set<B>);
TEST(std::set<std::string>);
TEST(std::map<int, A>);
TEST(std::map<std::string, B>);
TEST(std::map<std::wstring, std::vector<std::string> const*> const&);
#if !defined(BOOST_NO_CXX11_HDR_UNORDERED_SET)
TEST(std::unordered_set<int>);
TEST(std::unordered_set<std::string>);
#endif
#if !defined(BOOST_NO_CXX11_HDR_UNORDERED_MAP)
TEST(std::unordered_map<int, A>);
TEST(std::unordered_map<std::string, B>);
TEST(std::unordered_map<std::wstring, std::set<std::string>*>);
#endif
#if !defined(BOOST_NO_CXX11_HDR_ARRAY)
TEST(std::array<std::string, 7>);
TEST(std::array<std::wstring const*, 0> const&);
#endif
TEST(std::ostream);
TEST(std::basic_ostream<wchar_t>);
#if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
TEST(std::basic_string_view<Ch>);
TEST(std::string_view);
TEST(std::wstring_view);
#if BOOST_CXX_VERSION >= 201100L
TEST(std::u16string_view);
TEST(std::u32string_view);
#endif
#if BOOST_CXX_VERSION >= 202000L
TEST(std::u8string_view);
#endif
#endif
return boost::report_errors();
}