1
0
forked from boostorg/core

Compare commits

...

50 Commits

Author SHA1 Message Date
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
Andrey Semashev
ca4893063f Switch to from c++2a to c++20 for gcc-10 and clang-10. 2020-08-20 15:10:47 +03:00
Andrey Semashev
dcc04c5508 Added a workaround for uncaught_exceptions for older Mac OS and iOS.
libc++ disables std::uncaught_exceptions for Mac OS < 10.12 and
iOS < 10.0, even though it defines __cpp_lib_uncaught_exceptions.

Fixes https://github.com/boostorg/core/issues/80.
2020-07-20 23:13:42 +03:00
Glen Fernandes
484487f958 MSVC2017 /std:c++17 warnings in allocator access 2020-07-17 09:30:00 -04:00
Andrey Semashev
503d035b7f Added a workaround for uncaught_exceptions on AIX with xlclang++.
The compiler provides cxxabi.h header but doesn't have __cxa_get_globals,
even in the ABI library. We have to disable __cxa_get_globals-based
implementation and fall back to std::uncaught_exception.

Fixes https://github.com/boostorg/core/issues/78.
2020-07-16 20:53:09 +03:00
Peter Dimov
35a025d59b Untabify lightweight_test_with_fail 2020-06-15 21:32:50 +03:00
33 changed files with 2695 additions and 260 deletions

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

@@ -0,0 +1,201 @@
name: CI
on:
pull_request:
push:
branches:
- master
- develop
- feature/**
env:
UBSAN_OPTIONS: print_stacktrace=1
jobs:
posix:
strategy:
fail-fast: false
matrix:
include:
- toolset: gcc-4.7
cxxstd: "03,11"
os: ubuntu-16.04
install: g++-4.7
- toolset: gcc-4.8
cxxstd: "03,11"
os: ubuntu-16.04
install: g++-4.8
- toolset: gcc-4.9
cxxstd: "03,11"
os: ubuntu-16.04
install: g++-4.9
- toolset: gcc-5
cxxstd: "03,11,14,1z"
os: ubuntu-16.04
- toolset: gcc-6
cxxstd: "03,11,14,1z"
os: ubuntu-16.04
install: g++-6
- toolset: gcc-7
cxxstd: "03,11,14,17"
os: ubuntu-18.04
- toolset: gcc-8
cxxstd: "03,11,14,17,2a"
os: ubuntu-18.04
- toolset: gcc-9
cxxstd: "03,11,14,17,2a"
os: ubuntu-18.04
- toolset: gcc-10
cxxstd: "03,11,14,17,2a"
os: ubuntu-18.04
- toolset: clang
compiler: clang++-3.5
cxxstd: "03,11,14"
os: ubuntu-16.04
install: clang-3.5
- toolset: clang
compiler: clang++-3.6
cxxstd: "03,11,14"
os: ubuntu-16.04
install: clang-3.6
- toolset: clang
compiler: clang++-3.7
cxxstd: "03,11,14"
os: ubuntu-16.04
install: clang-3.7
- toolset: clang
compiler: clang++-3.8
cxxstd: "03,11,14"
os: ubuntu-16.04
install: clang-3.8
- toolset: clang
compiler: clang++-3.9
cxxstd: "03,11,14"
os: ubuntu-16.04
install: clang-3.9
- toolset: clang
compiler: clang++-4.0
cxxstd: "03,11,14"
os: ubuntu-16.04
install: clang-4.0
- toolset: clang
compiler: clang++-5.0
cxxstd: "03,11,14,1z"
os: ubuntu-16.04
install: clang-5.0
- toolset: clang
compiler: clang++-6.0
cxxstd: "03,11,14,17"
os: ubuntu-18.04
- toolset: clang
compiler: clang++-7
cxxstd: "03,11,14,17"
os: ubuntu-18.04
install: clang-7
- toolset: clang
compiler: clang++-8
cxxstd: "03,11,14,17,2a"
os: ubuntu-20.04
- toolset: clang
compiler: clang++-9
cxxstd: "03,11,14,17,2a"
os: ubuntu-20.04
- toolset: clang
compiler: clang++-10
cxxstd: "03,11,14,17,2a"
os: ubuntu-20.04
- toolset: clang
cxxstd: "03,11,14,17,2a"
os: macos-10.15
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v2
- name: Install packages
if: matrix.install
run: sudo apt install ${{matrix.install}}
- name: Setup Boost
run: |
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
LIBRARY=${GITHUB_REPOSITORY#*/}
echo LIBRARY: $LIBRARY
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
echo GITHUB_REF: $GITHUB_REF
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
REF=${REF#refs/heads/}
echo REF: $REF
BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true
echo BOOST_BRANCH: $BOOST_BRANCH
cd ..
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
./bootstrap.sh
./b2 -d0 headers
- name: Create user-config.jam
if: matrix.compiler
run: |
echo "using ${{matrix.toolset}} : : ${{matrix.compiler}} ;" > ~/user-config.jam
- name: Run tests
run: |
cd ../boost-root
./b2 -j3 libs/$LIBRARY/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} variant=debug,release
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 3" %LIBRARY%
cmd /c bootstrap
b2 -d0 headers
- name: Run tests
shell: cmd
run: |
cd ../boost-root
b2 -j3 libs/%LIBRARY%/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release

View File

@@ -24,7 +24,26 @@ matrix:
include:
- os: linux
compiler: g++
env: TOOLSET=gcc COMPILER=g++ CXXSTD=03,11
env: TOOLSET=gcc COMPILER=g++ CXXSTD=03,11,14 ADDRMD=32,64
addons:
apt:
packages:
- g++-multilib
- os: linux
arch: arm64
compiler: g++
env: TOOLSET=gcc COMPILER=g++ CXXSTD=03,11,14 ADDRMD=32,64
- os: linux
arch: ppc64le
compiler: g++
env: TOOLSET=gcc COMPILER=g++ CXXSTD=03,11,14
- os: linux
arch: s390x
compiler: g++
env: TOOLSET=gcc COMPILER=g++ CXXSTD=03,11,14 ADDRMD=32,64
- os: linux
compiler: g++-4.4
@@ -46,90 +65,10 @@ matrix:
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,2a
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:
@@ -137,21 +76,6 @@ matrix:
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,2a 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++
@@ -171,177 +95,44 @@ matrix:
- clang-3.4
- os: linux
dist: trusty
compiler: clang++-3.5
env: TOOLSET=clang COMPILER=clang++-3.5 CXXSTD=03,11
compiler: clang++-11
env: UBSAN=1 TOOLSET=clang COMPILER=clang++-11 CXXSTD=03,11,14,17,20 UBSAN_OPTIONS=print_stacktrace=1
addons:
apt:
packages:
- clang-3.5
- clang-11
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'
- sourceline: 'deb https://apt.llvm.org/xenial/ llvm-toolchain-xenial-11 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,2a
addons:
apt:
packages:
- clang-10
sources:
- ubuntu-toolchain-r-test
- sourceline: 'deb https://apt.llvm.org/xenial/ llvm-toolchain-xenial-10 main'
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
- os: linux
compiler: clang++-10
env: UBSAN=1 TOOLSET=clang COMPILER=clang++-10 CXXSTD=03,11,14,17,2a 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
dist: bionic
compiler: clang++-libc++
env: TOOLSET=clang COMPILER=clang++-libc++ CXXSTD=03,11,14,1z
env: UBSAN=1 TOOLSET=clang COMPILER=clang++-libc++ CXXSTD=03,11,14,17,2a UBSAN_OPTIONS=print_stacktrace=1
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: freebsd
compiler: clang++
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,17,2a
- os: osx
compiler: clang++
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z ADDRMD=32,64
osx_image: xcode7.3
- os: osx
compiler: clang++
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z ADDRMD=32,64
osx_image: xcode8.3
- os: osx
compiler: clang++
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z ADDRMD=32,64
osx_image: xcode9.4
- os: osx
@@ -349,6 +140,11 @@ matrix:
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z
osx_image: xcode10.1
- os: osx
osx_image: xcode11.3
compiler: clang++
env: UBSAN=1 TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z UBSAN_OPTIONS=print_stacktrace=1
- os: linux
env: CMAKE_TEST=1
script:
@@ -396,7 +192,7 @@ install:
- git submodule init tools/build
- git submodule init tools/boost_install
- git submodule init tools/cmake
- git submodule update --jobs 4
- git submodule update
- cp -r $TRAVIS_BUILD_DIR/* libs/core
- ./bootstrap.sh
- ./b2 headers
@@ -405,7 +201,7 @@ 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}
- ./b2 -j $BUILD_JOBS libs/core/test toolset=$TOOLSET cxxstd=$CXXSTD variant=debug,release ${ADDRMD:+address-model=$ADDRMD} ${UBSAN:+cxxflags=-fsanitize=undefined cxxflags=-fno-sanitize-recover=undefined linkflags=-fsanitize=undefined define=UBSAN=1 debug-symbols=on} ${LINKFLAGS:+linkflags=$LINKFLAGS}
notifications:
email:

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]

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

@@ -41,7 +41,9 @@ criteria for inclusion is that the utility component be:
[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]

View File

@@ -137,6 +137,11 @@ 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 {
@@ -156,6 +161,11 @@ 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 {

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,199 @@
#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 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <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 // #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

@@ -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,45 @@ 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; }
inline unsigned long 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

@@ -1,5 +1,5 @@
/*
* Copyright Andrey Semashev 2018.
* Copyright Andrey Semashev 2018 - 2020.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* https://www.boost.org/LICENSE_1_0.txt)
@@ -26,8 +26,23 @@
#pragma once
#endif
// Visual Studio 14 supports N4152 std::uncaught_exceptions()
#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:
// - Mac OS >= 10.12
// - iOS >= 10.0
// - 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) \
)
#define BOOST_CORE_HAS_UNCAUGHT_EXCEPTIONS
#endif
// 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)
#define BOOST_CORE_HAS_UNCAUGHT_EXCEPTIONS
#endif
@@ -46,7 +61,11 @@
#if defined(BOOST_CORE_HAS_CXXABI_H)
// MinGW GCC 4.4 seem to not work the same way the newer GCC versions do. As a result, __cxa_get_globals based implementation will always return 0.
// Just disable it for now and fall back to std::uncaught_exception().
#if !(defined(__MINGW32__) && (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) < 405))
// On AIX, xlclang++ does have cxxabi.h but doesn't have __cxa_get_globals (https://github.com/boostorg/core/issues/78).
#if !( \
(defined(__MINGW32__) && (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) < 405)) || \
defined(__ibmxl__) \
)
#include <cxxabi.h>
#include <cstring>
#define BOOST_CORE_HAS_CXA_GET_GLOBALS
@@ -76,7 +95,7 @@ extern "C" __cxa_eh_globals* __cxa_get_globals() BOOST_NOEXCEPT_OR_NOTHROW __att
#endif
} // namespace __cxxabiv1
#endif
#endif // !(defined(__MINGW32__) && (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) < 405))
#endif
#endif // defined(BOOST_CORE_HAS_CXXABI_H)
#if defined(_MSC_VER) && _MSC_VER >= 1400

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 ;
@@ -94,6 +97,8 @@ run lightweight_test_test4.cpp
run lightweight_test_test5.cpp
: : : $(pedantic-errors)
<toolset>gcc-4.4.7:<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 +119,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 ;
@@ -217,5 +223,18 @@ 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 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 ;
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();
}

286
test/cmath_test.cpp Normal file
View File

@@ -0,0 +1,286 @@
// 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 <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 );
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_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

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

@@ -13,17 +13,17 @@ template <typename T>
struct with_tolerance
{
with_tolerance( T tolerance ): tolerance( tolerance )
{
}
{
}
bool operator()( T lhs, T rhs ) const
bool operator()( T lhs, T rhs ) const
{
return std::abs( lhs - rhs ) <= tolerance;
}
private:
T tolerance;
T tolerance;
};
void test_tolerance_predicate()

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
}