Compare commits

...

40 Commits

Author SHA1 Message Date
43238b75ce Added AppVeyor CI config.
AppVeyor CI is useful for testing older MSVC versions that are no longer
supported by GitHub Actions.
2025-06-13 15:43:18 +03:00
8651f245fe Added new gcc and clang jobs to GitHub Actions. 2025-06-13 15:43:18 +03:00
5628638ade Added a workaround for MSVC 14.0 for BOOST_BITMASK.
Apparently, MSVC 14.0 does not import type aliases into namespaces via
a using-declaration. Work around the problem by enabling the use of
a compiler intrinsic for deducing the underlyng type of the enum.
2025-06-12 23:56:02 +03:00
d3a556f694 Removed gcc 4.6 GitHub Action job.
The compiler doesn't support std::underlying_type trait,
which is needed by BOOST_BITMASK.
2025-06-12 19:01:48 +03:00
d533b69b87 Removed windows-2019 GitHub Actions jobs.
The windows-2019 image is deprecated and will soon be removevd.
2025-06-12 18:41:01 +03:00
1a28d9d60f Mark bitmask_set generated by BOOST_BITMASK as deprecated.
This function is not really needed and can be replaced with double
negation (!!) or comparison with an enum value of zero. We should
prefer to minimize polluting the user's namespace with new names.
2025-06-12 18:41:01 +03:00
002caaa54f Added tests for BOOST_BITMASK. 2025-06-12 18:41:01 +03:00
f7fdaf08a3 Use C++11 underlying_type trait in BOOST_BITMASK.
This bumps the language requirement to C++11, although for compilers
that support the __underlying_type intrinsic this may work even in C++03
mode.

The operators generated by BOOST_BITMASK now use proper underlying types
for casts, which means the operators will no longer truncate bits from
large enums.

Also mark the operators as noexcept and constexpr (since C++14).
2025-06-12 18:40:55 +03:00
5b10a0b9b5 Removed outdated GHA images, added new compilers. 2025-04-19 19:19:12 +03:00
a54b2619f8 Add support for modular build structure. (#24)
* Make the library modular usable.

* Switch to library requirements instead of source. As source puts extra source in install targets.

* Add missing b2 testing module import.

* Add missing import-search for cconfig/predef checks.

* Add requires-b2 check to top-level build file.

* Bump B2 require to 5.2

* Update copyright dates.

* Move inter-lib dependencies to a project variable and into the build targets.

* Update build deps.
2024-08-19 01:25:34 +03:00
804767983f Added macos-12 and 13 testing in addition to latest (which is 14). 2024-05-21 01:18:57 +03:00
a8a43b4778 Use macos-latest image as macos-11 is being removed. 2024-05-21 00:59:59 +03:00
080df0554b Added a missing trailing newline. 2024-04-27 19:35:02 +03:00
9c3a0022b2 Added gcc-13 and clang-17 CI jobs. 2024-02-06 00:44:24 +03:00
6488652b08 Reduced CI job timeouts. 2024-02-05 23:43:39 +03:00
8a0d14a862 Replaced actions/checkout usage with manual download commands.
This fixes the deprecation warnings for actions/checkout@v3. actions/checkout@v4
is not functional because of the upstream bug:

https://github.com/actions/checkout/issues/1590
2024-02-05 23:39:59 +03:00
845567f026 Remove C++03 CI jobs, use gcc-11 libstdc++ in clang-12 through 15. 2023-11-17 20:07:56 +03:00
b75c261492 Add clang-16 CI jobs, switch to clang-15 from stock Ubuntu repos. 2023-06-05 15:36:30 +03:00
c6dac76110 Updated to GHA checkout@v3 to avoid deprecation warnings. 2022-10-18 17:56:52 +03:00
15cc27d2bd GitHub Actions config update.
- Added gcc-12 and clang-13 through 15 jobs.
- Added C++23 testing for gcc and clang on Linux.
- Updated clang version for UBSAN job.
- Updated Ubuntu version for clang jobs to avoid having to use external APT
  repository.
- Updated python package installation for compatibility with Ubuntu 22.04.
2022-09-10 01:09:35 +03:00
f9888ad051 Use ubuntu-latest for GHA CI jobs that run in a container. 2022-08-14 14:05:52 +03:00
00efa0a0fb Removed compiler options that are not supported by clang-cl. 2022-08-14 11:36:17 +03:00
c22d18ee32 Updated GHA config to resolve CI failures. 2022-08-14 11:01:16 +03:00
0583b51d35 Updated GHA CI config to remove deprecated Windows and Ubuntu images. 2022-08-14 02:06:31 +03:00
90d5395868 Switch to macos-11 GHA image as macos-10.15 is deprecated. 2022-08-12 15:56:52 +03:00
8c603a1894 Fixed copyright character encoding in css.
Replaced ISO-8859-1 copyright character with (c) and changed the order
of date and name to be consistent with other copyrights.

Closes https://github.com/boostorg/detail/pull/22.
2022-02-03 11:58:40 +03:00
fc31e65e0d Updated check for apt-add-repository capabilities.
In Ubuntu 20.04 there appeared an updated version of the
software-properties-common package in focal-updates, which ships a newer
apt-add-repository version that doesn't support -P/-S/-U command line arguments.

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

Also, made source list processing more protected against spaces.
2021-11-16 00:38:41 +03:00
c5de1e6848 Another fix in git version check. 2021-09-26 20:36:43 +03:00
ab84a1cb11 Fixed git version check on Mac OS. 2021-09-26 20:34:00 +03:00
2ca25f118d Fix running multiple configs of test_utf8_codecvt in parallel.
When running multiple different configurations of test_utf8_codecvt, e.g.
debug/release or different C++ versions, the test used to spuriously fail
because the test processes would conflict through the files the test creates.

To work around this, the test now creates the files in the same directory
where the test executable is located. With Boost.Build, that means the files
will be created in different directories for different configs.

This should fix spurious test failures in CI.
2021-09-16 01:26:08 +03:00
399a7a65b8 Added GHA CI timeout. 2021-09-15 21:30:44 +03:00
3986d6b7e6 Updated test_utf8_codecvt to show data differences on test failures. 2021-09-12 20:57:37 +03:00
b9f29ff43a Added GitHub Actions config. 2021-09-12 19:34:54 +03:00
3ec1c642f0 Removed Travis CI config file.
Since Travis CI no longer runs free jobs for open source projects,
we are switching to GitHub Actions.
2021-09-12 19:24:52 +03:00
87489a4346 Fixed inconsistent linkage specification on MSVC. Code cleanup.
cc32906071 introduced inconsistent
BOOST_UTF8_DECL markup between function declarations and definitions,
which caused MSVC build errors. This commit fixes this.

Also, replaced unneeded BOOST_UTF8_DECL markup with inline for functions
that are only used internally. Made get_cont_octet_out_count static.

Additionally, removed duplicate octet1_modifier_table definitions
and moved it to a function-local static.

Whitespace and formatting cleanup.

Closes https://github.com/boostorg/filesystem/issues/204.
2021-08-18 00:47:12 +03:00
db4c8248c0 Merge commit 'a01fe6d57b906edf0400daebfb5ea88bb4582f44' into develop
* commit 'a01fe6d57b906edf0400daebfb5ea88bb4582f44':
  Update CMakeLists.txt
  Fixed out-of-bounds access in utf8_codecvt_facet::do_length.
  Update maintainer list
  Disabled libstdc++ debug mode to work around gcc 10.1 bug.
  Added a workaround for removed nested typedefs in std::allocator.
  Added a workaround for C++20 ostream having deleted operator<< for wchar_t.
  Added gcc 10 build jobs to Travis CI.
  Use more up-to-date location of lightweight_test.hpp
  Converted binary_search_test to lightweight_test.hpp
  Converted allocator_utilities_test to lightweight_test.hpp
  Converted blank_test to lightweight_test.hpp.
  Removed use of deprecated header boost/detail/iterator.hpp.
  Reordered includes.
  Added boost/config.hpp.
  Changed because config.hpp is not being included
  Added clang-10 jobs to Travis CI.
  Change __BORLANDC__ to BOOST_BORLANDC, which is defined in Boost config for the Embarcadero non-clang-based compilers.
  Disabled OS X builds because they are slow on Travis CI.
  Updated CI configs, added compilers.
2021-08-14 11:08:29 -07:00
cc32906071 adjustments to visibiity 2021-08-14 11:08:14 -07:00
a01fe6d57b Update CMakeLists.txt 2021-06-10 01:15:48 +03:00
131208d8cc Fixed out-of-bounds access in utf8_codecvt_facet::do_length.
The loop in do_length used to dereference from_end pointer, which
could point to an out-of-bounds memory. Rewritten the loop to
avoid this and also make the logic a bit more clear.

Closes https://github.com/boostorg/detail/pull/21.
2021-03-17 14:12:36 +03:00
99fc546b78 Update maintainer list 2021-01-26 15:53:19 -05:00
16 changed files with 1140 additions and 577 deletions

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

@ -0,0 +1,594 @@
# Copyright 2021-2025 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.7
cxxstd: "11"
os: ubuntu-latest
container: ubuntu:16.04
install:
- g++-4.7
- toolset: gcc-4.8
cxxstd: "11"
os: ubuntu-latest
container: ubuntu:18.04
install:
- g++-4.8
- toolset: gcc-4.9
cxxstd: "11"
os: ubuntu-latest
container: ubuntu:16.04
install:
- g++-4.9
- toolset: gcc-5
cxxstd: "11,14,1z"
os: ubuntu-latest
container: ubuntu:16.04
install:
- g++-5
- toolset: gcc-6
cxxstd: "11,14,1z"
os: ubuntu-latest
container: ubuntu:18.04
install:
- g++-6
- toolset: gcc-7
cxxstd: "11,14,17"
os: ubuntu-latest
container: ubuntu:18.04
install:
- g++-7
- toolset: gcc-8
cxxstd: "11,14,17,2a"
os: ubuntu-latest
container: ubuntu:18.04
install:
- g++-8
- toolset: gcc-9
cxxstd: "11,14,17,2a"
os: ubuntu-latest
container: ubuntu:20.04
install:
- g++-9
- toolset: gcc-10
cxxstd: "11,14,17,20"
os: ubuntu-latest
container: ubuntu:20.04
install:
- g++-10
- toolset: gcc-11
cxxstd: "11,14,17,20,23"
os: ubuntu-22.04
install:
- g++-11
- toolset: gcc-12
cxxstd: "11,14,17,20,23"
os: ubuntu-22.04
install:
- g++-12
- toolset: gcc-13
cxxstd: "11,14,17,20,23"
os: ubuntu-24.04
install:
- g++-13
- toolset: gcc-14
cxxstd: "11,14,17,20,23,26"
os: ubuntu-24.04
install:
- g++-14
- toolset: gcc-15
cxxstd: "11,14,17,20,23,26"
os: ubuntu-latest
container: ubuntu:25.04
install:
- g++-15
- name: UBSAN
toolset: gcc-13
cxxstd: "11,14,17,20,23"
ubsan: 1
build_variant: debug
os: ubuntu-24.04
install:
- g++-13
# Linux, clang
- toolset: clang
compiler: clang++-3.5
cxxstd: "11"
os: ubuntu-latest
container: ubuntu:16.04
install:
- clang-3.5
- toolset: clang
compiler: clang++-3.6
cxxstd: "11,14"
os: ubuntu-latest
container: ubuntu:16.04
install:
- clang-3.6
- toolset: clang
compiler: clang++-3.7
cxxstd: "11,14"
os: ubuntu-latest
container: ubuntu:16.04
install:
- clang-3.7
- toolset: clang
compiler: clang++-3.8
cxxstd: "11,14"
os: ubuntu-latest
container: ubuntu:16.04
install:
- clang-3.8
- toolset: clang
compiler: clang++-3.9
cxxstd: "11,14"
os: ubuntu-latest
container: ubuntu:18.04
install:
- clang-3.9
- toolset: clang
compiler: clang++-4.0
cxxstd: "11,14"
os: ubuntu-latest
container: ubuntu:18.04
install:
- clang-4.0
- toolset: clang
compiler: clang++-5.0
cxxstd: "11,14,1z"
os: ubuntu-latest
container: ubuntu:18.04
install:
- clang-5.0
- toolset: clang
compiler: clang++-6.0
cxxstd: "11,14,17"
os: ubuntu-latest
container: ubuntu:18.04
install:
- clang-6.0
- toolset: clang
compiler: clang++-7
cxxstd: "11,14,17"
os: ubuntu-latest
container: ubuntu:18.04
install:
- clang-7
# Note: clang-8 does not fully support C++20, so it is not compatible with libstdc++-8 in this mode
- toolset: clang
compiler: clang++-8
cxxstd: "11,14,17,2a"
os: ubuntu-latest
container: ubuntu:18.04
install:
- clang-8
- g++-7
gcc_toolchain: 7
- toolset: clang
compiler: clang++-9
cxxstd: "11,14,17,2a"
os: ubuntu-latest
container: ubuntu:20.04
install:
- clang-9
- toolset: clang
compiler: clang++-10
cxxstd: "11,14,17,20"
os: ubuntu-latest
container: ubuntu:20.04
install:
- clang-10
- toolset: clang
compiler: clang++-11
cxxstd: "11,14,17,20"
os: ubuntu-22.04
install:
- clang-11
- toolset: clang
compiler: clang++-12
cxxstd: "11,14,17,20,2b"
os: ubuntu-22.04
install:
- clang-12
- g++-11
gcc_toolchain: 11
- toolset: clang
compiler: clang++-13
cxxstd: "11,14,17,20,2b"
os: ubuntu-22.04
install:
- clang-13
- g++-11
gcc_toolchain: 11
- toolset: clang
compiler: clang++-14
cxxstd: "11,14,17,20,2b"
os: ubuntu-22.04
install:
- clang-14
- g++-11
gcc_toolchain: 11
- toolset: clang
compiler: clang++-15
cxxstd: "11,14,17,20,2b"
os: ubuntu-22.04
install:
- clang-15
- g++-11
gcc_toolchain: 11
- toolset: clang
compiler: clang++-16
cxxstd: "11,14,17,20,2b"
os: ubuntu-24.04
install:
- clang-16
- g++-11
gcc_toolchain: 11
- toolset: clang
compiler: clang++-17
cxxstd: "11,14,17,20,23"
os: ubuntu-24.04
install:
- clang-17
- g++-11
gcc_toolchain: 11
- toolset: clang
compiler: clang++-18
cxxstd: "11,14,17,20,23,26"
os: ubuntu-24.04
install:
- clang-18
- g++-13
- toolset: clang
compiler: clang++-19
cxxstd: "11,14,17,20,23,26"
os: ubuntu-24.04
install:
- clang-19
- toolset: clang
compiler: clang++-20
cxxstd: "11,14,17,20,23,26"
os: ubuntu-latest
container: ubuntu:25.04
install:
- clang-20
- toolset: clang
compiler: clang++-20
cxxstd: "11,14,17,20,23,26"
cxxflags: -stdlib=libc++
linkflags: -stdlib=libc++
os: ubuntu-latest
container: ubuntu:25.04
install:
- clang-20
- libc++-20-dev
- libc++abi-20-dev
- name: UBSAN
toolset: clang
compiler: clang++-18
cxxstd: "11,14,17,20,23,26"
cxxflags: -stdlib=libc++
linkflags: -stdlib=libc++
ubsan: 1
build_variant: debug
os: ubuntu-24.04
install:
- clang-18
- libc++-18-dev
- libc++abi-18-dev
- toolset: clang
cxxstd: "11,14,17,20,2b"
os: macos-13
- toolset: clang
cxxstd: "11,14,17,20,2b"
os: macos-14
timeout-minutes: 15
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
if [ "$(apt-cache search "^python-is-python3$" | wc -l)" -ne 0 ]
then
PYTHON_PACKAGE="python-is-python3"
else
PYTHON_PACKAGE="python"
fi
apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y sudo software-properties-common tzdata wget curl apt-transport-https ca-certificates make build-essential g++ $PYTHON_PACKAGE python3 perl git cmake
fi
fi
git config --global pack.threads 0
- name: Install packages
if: matrix.install
run: |
declare -a SOURCE_KEYS SOURCES
if [ -n "${{join(matrix.source_keys, ' ')}}" ]
then
SOURCE_KEYS=("${{join(matrix.source_keys, '" "')}}")
fi
if [ -n "${{join(matrix.sources, ' ')}}" ]
then
SOURCES=("${{join(matrix.sources, '" "')}}")
fi
for key in "${SOURCE_KEYS[@]}"
do
for i in {1..$NET_RETRY_COUNT}
do
echo "Adding key: $key"
wget -O - "$key" | sudo apt-key add - && break || sleep 2
done
done
if [ ${#SOURCES[@]} -gt 0 ]
then
APT_ADD_REPO_COMMON_ARGS=("-y")
APT_ADD_REPO_SUPPORTED_ARGS="$(apt-add-repository --help | perl -ne 'if (/^\s*-n/) { print "n"; } elsif (/^\s*-P/) { print "P"; } elsif (/^\s*-S/) { print "S"; } elsif (/^\s*-U/) { print "U"; }')"
if [ -n "$APT_ADD_REPO_SUPPORTED_ARGS" -a -z "${APT_ADD_REPO_SUPPORTED_ARGS##*n*}" ]
then
APT_ADD_REPO_COMMON_ARGS+=("-n")
fi
APT_ADD_REPO_HAS_SOURCE_ARGS="$([ -n "$APT_ADD_REPO_SUPPORTED_ARGS" -a -z "${APT_ADD_REPO_SUPPORTED_ARGS##*P*}" -a -z "${APT_ADD_REPO_SUPPORTED_ARGS##*S*}" -a -z "${APT_ADD_REPO_SUPPORTED_ARGS##*U*}" ] && echo 1 || echo 0)"
for source in "${SOURCES[@]}"
do
for i in {1..$NET_RETRY_COUNT}
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")
echo "apt-add-repository ${APT_ADD_REPO_ARGS[@]}"
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
mkdir -p snapshot
cd snapshot
echo "Downloading library snapshot: https://github.com/${GITHUB_REPOSITORY}/archive/${GITHUB_SHA}.tar.gz"
curl -L --retry "$NET_RETRY_COUNT" -o "${LIBRARY}-${GITHUB_SHA}.tar.gz" "https://github.com/${GITHUB_REPOSITORY}/archive/${GITHUB_SHA}.tar.gz"
tar -xf "${LIBRARY}-${GITHUB_SHA}.tar.gz"
if [ ! -d "${LIBRARY}-${GITHUB_SHA}" ]
then
echo "Library snapshot does not contain the library directory ${LIBRARY}-${GITHUB_SHA}:"
ls -la
exit 1
fi
rm -f "${LIBRARY}-${GITHUB_SHA}.tar.gz"
cd ..
git clone -b "$BOOST_BRANCH" --depth 1 "https://github.com/boostorg/boost.git" "boost-root"
cd boost-root
mkdir -p libs
rm -rf "libs/$LIBRARY"
mv -f "../snapshot/${LIBRARY}-${GITHUB_SHA}" "libs/$LIBRARY"
rm -rf "../snapshot"
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[@]}"
windows:
strategy:
fail-fast: false
matrix:
include:
- toolset: msvc-14.3
cxxstd: "14,17,20,latest"
addrmd: 32,64
os: windows-2022
- toolset: clang-win
cxxstd: "14,17,latest"
addrmd: 32,64
os: windows-2022
- toolset: gcc
cxxstd: "11,14,17,20,23"
addrmd: 64
os: windows-2022
timeout-minutes: 15
runs-on: ${{matrix.os}}
steps:
- 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%
mkdir snapshot
cd snapshot
echo Downloading library snapshot: https://github.com/%GITHUB_REPOSITORY%/archive/%GITHUB_SHA%.zip
curl -L --retry %NET_RETRY_COUNT% -o "%LIBRARY%-%GITHUB_SHA%.zip" "https://github.com/%GITHUB_REPOSITORY%/archive/%GITHUB_SHA%.zip"
tar -xf "%LIBRARY%-%GITHUB_SHA%.zip"
if not exist "%LIBRARY%-%GITHUB_SHA%\" (
echo Library snapshot does not contain the library directory %LIBRARY%-%GITHUB_SHA%:
dir
exit /b 1
)
del /f "%LIBRARY%-%GITHUB_SHA%.zip"
cd ..
git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
if not exist "libs\" mkdir libs
if exist "libs\%LIBRARY%\" rmdir /s /q "libs\%LIBRARY%"
move /Y "..\snapshot\%LIBRARY%-%GITHUB_SHA%" "libs\%LIBRARY%"
rmdir /s /q "..\snapshot"
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py --git_args "--jobs %GIT_FETCH_JOBS%" %LIBRARY%
cmd /c bootstrap
b2 headers
- name: Run tests
shell: cmd
run: |
cd boost-root
set BUILD_VARIANT=${{matrix.build_variant}}
if "%BUILD_VARIANT%" == "" set BUILD_VARIANT=%DEFAULT_BUILD_VARIANT%
b2 -j %NUMBER_OF_PROCESSORS% toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=%BUILD_VARIANT% embed-manifest-via=linker libs/%LIBRARY%/test

View File

@ -1,386 +0,0 @@
# Copyright 2016, 2017, 2018 Peter Dimov
# Copyright 2019 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)
language: cpp
sudo: false
branches:
only:
- master
- develop
- /feature\/.*/
env:
matrix:
- BOGUS_JOB=true
matrix:
exclude:
- env: BOGUS_JOB=true
include:
# gcc, Linux
- os: linux
dist: trusty
compiler: gcc-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
dist: trusty
compiler: gcc-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
dist: trusty
compiler: gcc-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
dist: xenial
compiler: gcc-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
dist: xenial
compiler: gcc-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
dist: xenial
compiler: gcc-5
env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- g++-5
sources:
- ubuntu-toolchain-r-test
- os: linux
dist: xenial
compiler: gcc-6
env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- g++-6
sources:
- ubuntu-toolchain-r-test
- os: linux
dist: xenial
compiler: gcc-7
env: TOOLSET=gcc COMPILER=g++-7 CXXSTD=03,11,14,17
addons:
apt:
packages:
- g++-7
sources:
- ubuntu-toolchain-r-test
- os: linux
dist: xenial
compiler: gcc-8
env: TOOLSET=gcc COMPILER=g++-8 CXXSTD=03,11,14,17
addons:
apt:
packages:
- g++-8
sources:
- ubuntu-toolchain-r-test
- os: linux
dist: bionic
compiler: gcc-9
env: TOOLSET=gcc COMPILER=g++-9 CXXSTD=03,11,14,17
addons:
apt:
packages:
- g++-9
sources:
- sourceline: "ppa:ubuntu-toolchain-r/test"
- os: linux
dist: bionic
compiler: gcc-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"
# clang, Linux
- os: linux
dist: trusty
compiler: clang-3.4
env: TOOLSET=clang COMPILER=clang++-3.4 CXXSTD=03,11
addons:
apt:
packages:
- clang-3.4
- libstdc++-4.9-dev
sources:
- ubuntu-toolchain-r-test
- sourceline: "deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-3.4 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- os: linux
dist: trusty
compiler: clang-3.5
env: TOOLSET=clang COMPILER=clang++-3.5 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-3.5
- libstdc++-4.9-dev
sources:
- ubuntu-toolchain-r-test
- sourceline: "deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-3.5 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- os: linux
dist: trusty
compiler: clang-3.6
env: TOOLSET=clang COMPILER=clang++-3.6 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-3.6
- libstdc++-5-dev
sources:
- ubuntu-toolchain-r-test
- sourceline: "deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-3.6 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- os: linux
dist: trusty
compiler: clang-3.7
env: TOOLSET=clang COMPILER=clang++-3.7 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-3.7
- libstdc++-5-dev
sources:
- ubuntu-toolchain-r-test
- sourceline: "deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-3.7 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- os: linux
dist: xenial
compiler: clang-3.8
env: TOOLSET=clang COMPILER=clang++-3.8 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-3.8
- libstdc++-6-dev
sources:
- ubuntu-toolchain-r-test
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-3.8 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- os: linux
dist: xenial
compiler: clang-3.9
env: TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-3.9
- libstdc++-6-dev
sources:
- ubuntu-toolchain-r-test
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-3.9 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- os: linux
dist: xenial
compiler: clang-4
env: TOOLSET=clang COMPILER=clang++-4.0 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-4.0
- libstdc++-6-dev
sources:
- ubuntu-toolchain-r-test
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-4.0 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- os: linux
dist: xenial
compiler: clang-5
env: TOOLSET=clang COMPILER=clang++-5.0 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-5.0
- libstdc++-7-dev
sources:
- ubuntu-toolchain-r-test
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-5.0 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- os: linux
dist: xenial
compiler: clang-6
env: TOOLSET=clang COMPILER=clang++-6.0 CXXSTD=03,11,14,17
addons:
apt:
packages:
- clang-6.0
- libstdc++-8-dev
sources:
- ubuntu-toolchain-r-test
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-6.0 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- os: linux
dist: xenial
compiler: clang-7
env: TOOLSET=clang COMPILER=clang++-7 CXXSTD=03,11,14,17
addons:
apt:
packages:
- clang-7
- libstdc++-8-dev
sources:
- ubuntu-toolchain-r-test
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-7 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- os: linux
dist: xenial
compiler: clang-8
env: TOOLSET=clang COMPILER=clang++-8 CXXSTD=03,11,14,17
addons:
apt:
packages:
- clang-8
- libstdc++-8-dev
sources:
- ubuntu-toolchain-r-test
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-8 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- os: linux
dist: xenial
compiler: clang-9
env: TOOLSET=clang COMPILER=clang++-9 CXXSTD=03,11,14,17
addons:
apt:
packages:
- clang-9
- libstdc++-9-dev
sources:
- sourceline: "ppa:ubuntu-toolchain-r/test"
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-9 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- os: linux
dist: xenial
compiler: clang-10
env: TOOLSET=clang COMPILER=clang++-10 CXXSTD=03,11,14,17,20
addons:
apt:
packages:
- clang-10
- libstdc++-9-dev
sources:
- sourceline: "ppa:ubuntu-toolchain-r/test"
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-10 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- os: linux
dist: xenial
compiler: clang-libc++
env: TOOLSET=clang COMPILER=clang++-10 CXXSTD=03,11,14,17,20 CXXFLAGS="-stdlib=libc++" LINKFLAGS="-stdlib=libc++"
addons:
apt:
packages:
- clang-10
- libc++-10-dev
- libc++abi-10-dev
sources:
- sourceline: "ppa:ubuntu-toolchain-r/test"
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-10 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
# clang, OS X
# Disabled because OS X builds are slow on Travis CI
# - os: osx
# env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z
# osx_image: xcode9.4
#
# - os: osx
# env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z
# osx_image: xcode10.3
#
# - os: osx
# env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,17
# osx_image: xcode11.2
install:
- GIT_FETCH_JOBS=8
- BOOST_BRANCH=develop
- if [ "$TRAVIS_BRANCH" = "master" ]; then BOOST_BRANCH=master; fi
- cd ..
- git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
- cd boost-root
- git submodule init tools/build
- git submodule init tools/boostdep
- git submodule init tools/boost_install
- git submodule init libs/headers
- git submodule init libs/config
- git submodule update --jobs $GIT_FETCH_JOBS
- cp -r $TRAVIS_BUILD_DIR/* libs/detail
- python tools/boostdep/depinst/depinst.py --git_args "--jobs $GIT_FETCH_JOBS" detail
- ./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/detail/test toolset=$TOOLSET cxxstd=$CXXSTD ${CXXFLAGS:+cxxflags="$CXXFLAGS"} ${LINKFLAGS:+linkflags="$LINKFLAGS"}
notifications:
email:
on_success: always

View File

@ -3,12 +3,9 @@
# 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
# Partial (add_subdirectory only) and experimental CMake support
# Subject to change; please do not rely on the contents of this file yet.
cmake_minimum_required(VERSION 3.5...3.20)
cmake_minimum_required(VERSION 3.5)
project(BoostDetail LANGUAGES CXX)
project(boost_detail VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX)
add_library(boost_detail INTERFACE)
add_library(Boost::detail ALIAS boost_detail)

88
appveyor.yml Normal file
View File

@ -0,0 +1,88 @@
# Copyright 2025 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)
version: 1.0.{build}-{branch}
shallow_clone: true
branches:
only:
- master
- develop
- /feature\/.*/
environment:
matrix:
- TOOLSET: msvc-12.0
ADDRMD: 32,64
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
- TOOLSET: msvc-14.0
ADDRMD: 32,64
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
- TOOLSET: msvc-14.1
CXXSTD: 14,17,latest
ADDRMD: 32,64
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
- TOOLSET: msvc-14.2
ADDRMD: 32,64
CXXSTD: 14,17,20,latest
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
- TOOLSET: msvc-14.3
ADDRMD: 32,64
CXXSTD: 14,17,20,latest
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
- TOOLSET: clang-win
ADDRMD: 32
CXXSTD: 14,17,latest
ENV_SCRIPT: C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars32.bat
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
- TOOLSET: clang-win
ADDRMD: 64
CXXSTD: 14,17,latest
ENV_SCRIPT: C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
- TOOLSET: gcc
CXXSTD: 11,14,1z
ADDPATH: C:\cygwin\bin;
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
- TOOLSET: gcc
CXXSTD: 11,14,1z
ADDPATH: C:\cygwin64\bin;
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
- TOOLSET: gcc
CXXSTD: 11,14,17
ADDPATH: C:\mingw-w64\x86_64-7.3.0-posix-seh-rt_v5-rev0\mingw64\bin;
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
- TOOLSET: gcc
CXXSTD: 11,14,17,2a
ADDPATH: C:\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\bin;
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
install:
- set GIT_FETCH_JOBS=8
- set BOOST_BRANCH=develop
- if "%APPVEYOR_REPO_BRANCH%" == "master" set BOOST_BRANCH=master
- cd ..
- git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
- cd boost-root
- git submodule init tools/build
- git submodule init tools/boostdep
- git submodule init tools/boost_install
- git submodule init libs/headers
- git submodule init libs/config
- git submodule update --jobs %GIT_FETCH_JOBS%
- xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\detail
- python tools/boostdep/depinst/depinst.py --git_args "--jobs %GIT_FETCH_JOBS%" detail
- cmd /c bootstrap
- b2 -d0 headers
build: off
test_script:
- PATH=%ADDPATH%%PATH%
- if not "%ENV_SCRIPT%" == "" call "%ENV_SCRIPT%"
- if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
- if not "%ADDRMD%" == "" set ADDRMD=address-model=%ADDRMD%
- if not "%THREADING%" == "" set THREADING=threading=%THREADING%
- b2 -j %NUMBER_OF_PROCESSORS% libs/detail/test toolset=%TOOLSET% %CXXSTD% %ADDRMD% %THREADING%

27
build.jam Normal file
View File

@ -0,0 +1,27 @@
# Copyright René Ferdinand Rivera Morell 2023-2024
# 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)
require-b2 5.2 ;
constant boost_dependencies :
/boost/config//boost_config
/boost/core//boost_core
/boost/preprocessor//boost_preprocessor
/boost/static_assert//boost_static_assert
/boost/type_traits//boost_type_traits ;
project /boost/detail
: common-requirements
<include>include
;
explicit
[ alias boost_detail : : : : <library>$(boost_dependencies) ]
[ alias all : boost_detail test ]
;
call-if : boost-library detail
;

View File

@ -23,7 +23,7 @@ boostbook standalone
<xsl:param>generate.section.toc.level=3
<xsl:param>chunk.section.depth=2
#<xsl:param>chunk.first.sections=1
<dependency>images
<dependency>callouts
<dependency>css

View File

@ -1,6 +1,6 @@
/*
<20> Copyright Beman Dawes, 2007
Copyright (c) 2007 Beman Dawes
Distributed under the Boost Software License, Version 1.0.
See www.boost.org/LICENSE_1_0.txt

View File

@ -1,6 +1,7 @@
// boost/detail/bitmask.hpp ------------------------------------------------//
// Copyright Beman Dawes 2006
// Copyright Andrey Semashev 2025
// Distributed under the Boost Software License, Version 1.0
// http://www.boost.org/LICENSE_1_0.txt
@ -18,41 +19,73 @@
#define BOOST_BITMASK_HPP
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#define BOOST_BITMASK(Bitmask) \
\
inline BOOST_CONSTEXPR Bitmask operator| (Bitmask x , Bitmask y ) \
{ return static_cast<Bitmask>( static_cast<boost::int_least32_t>(x) \
| static_cast<boost::int_least32_t>(y)); } \
\
inline BOOST_CONSTEXPR Bitmask operator& (Bitmask x , Bitmask y ) \
{ return static_cast<Bitmask>( static_cast<boost::int_least32_t>(x) \
& static_cast<boost::int_least32_t>(y)); } \
\
inline BOOST_CONSTEXPR Bitmask operator^ (Bitmask x , Bitmask y ) \
{ return static_cast<Bitmask>( static_cast<boost::int_least32_t>(x) \
^ static_cast<boost::int_least32_t>(y)); } \
\
inline BOOST_CONSTEXPR Bitmask operator~ (Bitmask x ) \
{ return static_cast<Bitmask>(~static_cast<boost::int_least32_t>(x)); } \
\
inline Bitmask & operator&=(Bitmask& x , Bitmask y) \
{ x = x & y ; return x ; } \
\
inline Bitmask & operator|=(Bitmask& x , Bitmask y) \
{ x = x | y ; return x ; } \
\
inline Bitmask & operator^=(Bitmask& x , Bitmask y) \
{ x = x ^ y ; return x ; } \
\
/* Boost extensions to [bitmask.types] */ \
\
inline BOOST_CONSTEXPR bool operator!(Bitmask x) \
{ return !static_cast<int>(x); } \
\
inline BOOST_CONSTEXPR bool bitmask_set(Bitmask x) \
#if defined(__has_builtin)
#if __has_builtin(__underlying_type)
#define BOOST_BITMASK_DETAIL_UNDERLYING_TYPE(enum_type) __underlying_type(enum_type)
#endif
#endif
#if !defined(BOOST_BITMASK_DETAIL_UNDERLYING_TYPE) && \
((defined(BOOST_GCC_VERSION) && (BOOST_GCC_VERSION >= 40700)) || (defined(_MSC_VER) && (_MSC_VER >= 1700)))
#define BOOST_BITMASK_DETAIL_UNDERLYING_TYPE(enum_type) __underlying_type(enum_type)
#endif
#if !defined(BOOST_BITMASK_DETAIL_UNDERLYING_TYPE)
#include <type_traits>
#endif
namespace boost {
namespace detail {
namespace bitmask {
#if defined(BOOST_BITMASK_DETAIL_UNDERLYING_TYPE)
template< typename Enum >
using underlying_type_t = BOOST_BITMASK_DETAIL_UNDERLYING_TYPE(Enum);
#elif (BOOST_CXX_VERSION >= 201402)
using std::underlying_type_t;
#else
template< typename Enum >
using underlying_type_t = typename std::underlying_type< Enum >::type;
#endif
}}}
#undef BOOST_BITMASK_DETAIL_UNDERLYING_TYPE
#define BOOST_BITMASK(Bitmask) \
\
inline BOOST_CONSTEXPR Bitmask operator| (Bitmask x, Bitmask y) BOOST_NOEXCEPT \
{ return static_cast< Bitmask >(static_cast< ::boost::detail::bitmask::underlying_type_t< Bitmask > >(x) \
| static_cast< ::boost::detail::bitmask::underlying_type_t< Bitmask > >(y)); } \
\
inline BOOST_CONSTEXPR Bitmask operator& (Bitmask x, Bitmask y) BOOST_NOEXCEPT \
{ return static_cast< Bitmask >(static_cast< ::boost::detail::bitmask::underlying_type_t< Bitmask > >(x) \
& static_cast< ::boost::detail::bitmask::underlying_type_t< Bitmask > >(y)); } \
\
inline BOOST_CONSTEXPR Bitmask operator^ (Bitmask x, Bitmask y) BOOST_NOEXCEPT \
{ return static_cast< Bitmask >(static_cast< ::boost::detail::bitmask::underlying_type_t< Bitmask > >(x) \
^ static_cast< ::boost::detail::bitmask::underlying_type_t< Bitmask > >(y)); } \
\
inline BOOST_CONSTEXPR Bitmask operator~ (Bitmask x) BOOST_NOEXCEPT \
{ return static_cast< Bitmask >(~static_cast< ::boost::detail::bitmask::underlying_type_t< Bitmask > >(x)); } \
\
inline BOOST_CXX14_CONSTEXPR Bitmask& operator&=(Bitmask& x, Bitmask y) BOOST_NOEXCEPT \
{ x = x & y; return x; } \
\
inline BOOST_CXX14_CONSTEXPR Bitmask& operator|=(Bitmask& x, Bitmask y) BOOST_NOEXCEPT \
{ x = x | y; return x; } \
\
inline BOOST_CXX14_CONSTEXPR Bitmask& operator^=(Bitmask& x, Bitmask y) BOOST_NOEXCEPT \
{ x = x ^ y; return x; } \
\
/* Boost extensions to [bitmask.types] */ \
\
inline BOOST_CONSTEXPR bool operator!(Bitmask x) BOOST_NOEXCEPT \
{ return !static_cast< ::boost::detail::bitmask::underlying_type_t< Bitmask > >(x); } \
\
BOOST_DEPRECATED("bitmask_set(enum) is deprecated, use !!enum or comparison operators instead") \
inline BOOST_CONSTEXPR bool bitmask_set(Bitmask x) BOOST_NOEXCEPT \
{ return !!x; }
#endif // BOOST_BITMASK_HPP

View File

@ -53,4 +53,4 @@ int cpp_main(int argc, char* argv[])
std::cout << std::endl;
return test_main(argc, argv);
}
}

View File

@ -14,7 +14,7 @@
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// utf8_codecvt_facet.hpp
// This header defines class utf8_codecvt_facet, derived from
// This header defines class utf8_codecvt_facet, derived from
// std::codecvt<wchar_t, char>, which can be used to convert utf8 data in
// files into wchar_t strings in the application.
//
@ -23,10 +23,10 @@
// we want to avoid code duplication. It would be possible to create utf8
// library, but:
// - this requires review process first
// - in the case, when linking the a library which uses utf8
// - in the case, when linking the a library which uses utf8
// (say 'program_options'), user should also link to the utf8 library.
// This seems inconvenient, and asking a user to link to an unrevieved
// library is strange.
// This seems inconvenient, and asking a user to link to an unrevieved
// library is strange.
// Until the above points are fixed, a library which wants to use utf8 must:
// - include this header in one of it's headers or sources
// - include the corresponding boost/detail/utf8_codecvt_facet.ipp file in one
@ -39,14 +39,14 @@
// symbols.
//
// For example, program_options library might contain:
// #define BOOST_UTF8_BEGIN_NAMESPACE <backslash character>
// #define BOOST_UTF8_BEGIN_NAMESPACE <backslash character>
// namespace boost { namespace program_options {
// #define BOOST_UTF8_END_NAMESPACE }}
// #define BOOST_UTF8_DECL BOOST_PROGRAM_OPTIONS_DECL
// #include <boost/detail/utf8_codecvt_facet.ipp>
//
// Essentially, each library will have its own copy of utf8 code, in
// different namespaces.
// different namespaces.
// Note:(Robert Ramey). I have made the following alterations in the original
// code.
@ -67,7 +67,7 @@
// use two template parameters
//
// utf8_codecvt_facet
// This is an implementation of a std::codecvt facet for translating
// This is an implementation of a std::codecvt facet for translating
// from UTF-8 externally to UCS-4. Note that this is not tied to
// any specific types in order to allow customization on platforms
// where wchar_t is not big enough.
@ -109,28 +109,29 @@ BOOST_UTF8_BEGIN_NAMESPACE
#define BOOST_UTF8_DECL
#endif
struct BOOST_UTF8_DECL utf8_codecvt_facet :
public std::codecvt<wchar_t, char, std::mbstate_t>
struct BOOST_SYMBOL_VISIBLE utf8_codecvt_facet :
public std::codecvt<wchar_t, char, std::mbstate_t>
{
public:
explicit utf8_codecvt_facet(std::size_t no_locale_manage=0);
virtual ~utf8_codecvt_facet();
BOOST_UTF8_DECL explicit utf8_codecvt_facet(std::size_t no_locale_manage = 0);
BOOST_UTF8_DECL virtual ~utf8_codecvt_facet();
protected:
virtual std::codecvt_base::result do_in(
std::mbstate_t& state,
BOOST_UTF8_DECL virtual std::codecvt_base::result do_in(
std::mbstate_t& state,
const char * from,
const char * from_end,
const char * from_end,
const char * & from_next,
wchar_t * to,
wchar_t * to_end,
wchar_t*& to_next
wchar_t * to,
wchar_t * to_end,
wchar_t * & to_next
) const;
virtual std::codecvt_base::result do_out(
BOOST_UTF8_DECL virtual std::codecvt_base::result do_out(
std::mbstate_t & state,
const wchar_t * from,
const wchar_t * from_end,
const wchar_t* & from_next,
const wchar_t * & from_next,
char * to,
char * to_end,
char * & to_next
@ -140,7 +141,7 @@ protected:
return (octet_1 < 0x80|| 0xbf< octet_1);
}
bool invalid_leading_octet(unsigned char octet_1) const {
bool invalid_leading_octet(unsigned char octet_1) const {
return (0x7f < octet_1 && octet_1 < 0xc0) ||
(octet_1 > 0xfd);
}
@ -150,11 +151,11 @@ protected:
return get_octet_count(lead_octet) - 1;
}
static unsigned int get_octet_count(unsigned char lead_octet);
BOOST_UTF8_DECL static unsigned int get_octet_count(unsigned char lead_octet);
// How many "continuing octets" will be needed for this word
// == total octets - 1.
int get_cont_octet_out_count(wchar_t word) const ;
BOOST_UTF8_DECL static int get_cont_octet_out_count(wchar_t word);
virtual bool do_always_noconv() const BOOST_NOEXCEPT_OR_NOTHROW {
return false;
@ -162,7 +163,7 @@ protected:
// UTF-8 isn't really stateful since we rewind on partial conversions
virtual std::codecvt_base::result do_unshift(
std::mbstate_t&,
std::mbstate_t &,
char * from,
char * /*to*/,
char * & next
@ -178,10 +179,10 @@ protected:
// How many char objects can I process to get <= max_limit
// wchar_t objects?
virtual int do_length(
BOOST_UTF8_DECL virtual int do_length(
std::mbstate_t &,
const char * from,
const char * from_end,
const char * from_end,
std::size_t max_limit
) const
#if BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600))
@ -193,7 +194,7 @@ protected:
virtual int do_length(
const std::mbstate_t & s,
const char * from,
const char * from_end,
const char * from_end,
std::size_t max_limit
) const
#if BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600))

View File

@ -2,7 +2,7 @@
// utf8_codecvt_facet.ipp
// Copyright (c) 2001 Ronald Garcia, Indiana University (garcia@osl.iu.edu)
// Andrew Lumsdaine, Indiana University (lums@osl.iu.edu).
// Andrew Lumsdaine, Indiana University (lums@osl.iu.edu).
// Use, modification and distribution is subject to 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)
@ -18,7 +18,7 @@
#include <boost/limits.hpp>
#include <boost/config.hpp>
// If we don't have wstring, then Unicode support
// If we don't have wstring, then Unicode support
// is not available anyway, so we don't need to even
// compiler this file. This also fixes the problem
// with mingw, which can compile this file, but will
@ -30,108 +30,117 @@ BOOST_UTF8_BEGIN_NAMESPACE
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// implementation for wchar_t
utf8_codecvt_facet::utf8_codecvt_facet(
namespace detail {
inline const wchar_t * get_octet1_modifier_table() BOOST_NOEXCEPT
{
static const wchar_t octet1_modifier_table[] = {
0x00, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc
};
return octet1_modifier_table;
}
} // namespace detail
BOOST_UTF8_DECL utf8_codecvt_facet::utf8_codecvt_facet(
std::size_t no_locale_manage
) :
std::codecvt<wchar_t, char, std::mbstate_t>(no_locale_manage)
{}
utf8_codecvt_facet::~utf8_codecvt_facet()
BOOST_UTF8_DECL utf8_codecvt_facet::~utf8_codecvt_facet()
{}
// Translate incoming UTF-8 into UCS-4
std::codecvt_base::result utf8_codecvt_facet::do_in(
std::mbstate_t& /*state*/,
BOOST_UTF8_DECL std::codecvt_base::result utf8_codecvt_facet::do_in(
std::mbstate_t& /*state*/,
const char * from,
const char * from_end,
const char * from_end,
const char * & from_next,
wchar_t * to,
wchar_t * to_end,
wchar_t * to,
wchar_t * to_end,
wchar_t * & to_next
) const {
// Basic algorithm: The first octet determines how many
// octets total make up the UCS-4 character. The remaining
// Basic algorithm: The first octet determines how many
// octets total make up the UCS-4 character. The remaining
// "continuing octets" all begin with "10". To convert, subtract
// the amount that specifies the number of octets from the first
// octet. Subtract 0x80 (1000 0000) from each continuing octet,
// then mash the whole lot together. Note that each continuing
// octet. Subtract 0x80 (1000 0000) from each continuing octet,
// then mash the whole lot together. Note that each continuing
// octet only uses 6 bits as unique values, so only shift by
// multiples of 6 to combine.
const wchar_t * const octet1_modifier_table = detail::get_octet1_modifier_table();
while (from != from_end && to != to_end) {
// Error checking on the first octet
if (invalid_leading_octet(*from)){
// Error checking on the first octet
if (invalid_leading_octet(*from)) {
from_next = from;
to_next = to;
return std::codecvt_base::error;
}
// The first octet is adjusted by a value dependent upon
// the number of "continuing octets" encoding the character
const int cont_octet_count = get_cont_octet_count(*from);
const wchar_t octet1_modifier_table[] = {
0x00, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc
};
// The first octet is adjusted by a value dependent upon
// the number of "continuing octets" encoding the character
const int cont_octet_count = get_cont_octet_count(*from);
// The unsigned char conversion is necessary in case char is
// signed (I learned this the hard way)
wchar_t ucs_result =
// signed (I learned this the hard way)
wchar_t ucs_result =
(unsigned char)(*from++) - octet1_modifier_table[cont_octet_count];
// Invariants :
// 1) At the start of the loop, 'i' continuing characters have been
// processed
// 2) *from points to the next continuing character to be processed.
int i = 0;
while(i != cont_octet_count && from != from_end) {
// Invariants:
// 1) At the start of the loop, 'i' continuing characters have been
// processed
// 2) *from points to the next continuing character to be processed.
int i = 0;
while (i != cont_octet_count && from != from_end) {
// Error checking on continuing characters
if (invalid_continuing_octet(*from)) {
from_next = from;
to_next = to;
from_next = from;
to_next = to;
return std::codecvt_base::error;
}
ucs_result *= (1 << 6);
ucs_result *= (1 << 6);
// each continuing character has an extra (10xxxxxx)b attached to
// each continuing character has an extra (10xxxxxx)b attached to
// it that must be removed.
ucs_result += (unsigned char)(*from++) - 0x80;
++i;
}
// If the buffer ends with an incomplete unicode character...
if (from == from_end && i != cont_octet_count) {
// If the buffer ends with an incomplete unicode character...
if (from == from_end && i != cont_octet_count) {
// rewind "from" to before the current character translation
from_next = from - (i+1);
from_next = from - (i + 1);
to_next = to;
return std::codecvt_base::partial;
}
*to++ = ucs_result;
*to++ = ucs_result;
}
from_next = from;
to_next = to;
// Were we done converting or did we run out of destination space?
if(from == from_end) return std::codecvt_base::ok;
else return std::codecvt_base::partial;
if (from == from_end)
return std::codecvt_base::ok;
else
return std::codecvt_base::partial;
}
std::codecvt_base::result utf8_codecvt_facet::do_out(
std::mbstate_t& /*state*/,
const wchar_t * from,
const wchar_t * from_end,
BOOST_UTF8_DECL std::codecvt_base::result utf8_codecvt_facet::do_out(
std::mbstate_t& /*state*/,
const wchar_t * from,
const wchar_t * from_end,
const wchar_t * & from_next,
char * to,
char * to_end,
char * to,
char * to_end,
char * & to_next
) const
{
// RG - consider merging this table with the other one
const wchar_t octet1_modifier_table[] = {
0x00, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc
};
const wchar_t * const octet1_modifier_table = detail::get_octet1_modifier_table();
wchar_t max_wchar = (std::numeric_limits<wchar_t>::max)();
while (from != from_end && to != to_end) {
@ -144,75 +153,69 @@ std::codecvt_base::result utf8_codecvt_facet::do_out(
int cont_octet_count = get_cont_octet_out_count(*from);
// RG - comment this formula better
int shift_exponent = (cont_octet_count) * 6;
// RG - comment this formula better
int shift_exponent = cont_octet_count * 6;
// Process the first character
*to++ = static_cast<char>(octet1_modifier_table[cont_octet_count] +
(unsigned char)(*from / (1 << shift_exponent)));
// Process the continuation characters
// Invariants: At the start of the loop:
// 1) 'i' continuing octets have been generated
// 2) '*to' points to the next location to place an octet
// 3) shift_exponent is 6 more than needed for the next octet
int i = 0;
while (i != cont_octet_count && to != to_end) {
// Process the continuation characters
// Invariants: At the start of the loop:
// 1) 'i' continuing octets have been generated
// 2) '*to' points to the next location to place an octet
// 3) shift_exponent is 6 more than needed for the next octet
int i = 0;
while (i != cont_octet_count && to != to_end) {
shift_exponent -= 6;
*to++ = static_cast<char>(0x80 + ((*from / (1 << shift_exponent)) % (1 << 6)));
++i;
}
// If we filled up the out buffer before encoding the character
if(to == to_end && i != cont_octet_count) {
// If we filled up the out buffer before encoding the character
if (to == to_end && i != cont_octet_count) {
from_next = from;
to_next = to - (i+1);
to_next = to - (i + 1);
return std::codecvt_base::partial;
}
++from;
}
from_next = from;
to_next = to;
// Were we done or did we run out of destination space
if(from == from_end) return std::codecvt_base::ok;
else return std::codecvt_base::partial;
if (from == from_end)
return std::codecvt_base::ok;
else
return std::codecvt_base::partial;
}
// How many char objects can I process to get <= max_limit
// wchar_t objects?
int utf8_codecvt_facet::do_length(
BOOST_UTF8_DECL int utf8_codecvt_facet::do_length(
std::mbstate_t &,
const char * from,
const char * from_end,
const char * from_end,
std::size_t max_limit
) const
#if BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600))
throw()
#endif
{
// RG - this code is confusing! I need a better way to express it.
// and test cases.
// Invariants:
// 1) last_octet_count has the size of the last measured character
// 2) char_count holds the number of characters shown to fit
// within the bounds so far (no greater than max_limit)
// 3) from_next points to the octet 'last_octet_count' before the
// last measured character.
int last_octet_count=0;
std::size_t char_count = 0;
const char* from_next = from;
// Use "<" because the buffer may represent incomplete characters
while (from_next+last_octet_count <= from_end && char_count <= max_limit) {
from_next += last_octet_count;
last_octet_count = (get_octet_count(*from_next));
++char_count;
{
const char * from_next = from;
for (std::size_t char_count = 0u; char_count < max_limit && from_next < from_end; ++char_count) {
unsigned int octet_count = get_octet_count(*from_next);
// The buffer may represent incomplete characters, so terminate early if one is found
if (octet_count > static_cast<std::size_t>(from_end - from_next))
break;
from_next += octet_count;
}
return static_cast<int>(from_next-from);
return static_cast<int>(from_next - from);
}
unsigned int utf8_codecvt_facet::get_octet_count(
BOOST_UTF8_DECL unsigned int utf8_codecvt_facet::get_octet_count(
unsigned char lead_octet
){
) {
// if the 0-bit (MSB) is 0, then 1 character
if (lead_octet <= 0x7f) return 1;
@ -229,7 +232,7 @@ unsigned int utf8_codecvt_facet::get_octet_count(
namespace detail {
template<std::size_t s>
int get_cont_octet_out_count_impl(wchar_t word){
inline int get_cont_octet_out_count_impl(wchar_t word) {
if (word < 0x80) {
return 0;
}
@ -240,7 +243,7 @@ int get_cont_octet_out_count_impl(wchar_t word){
}
template<>
int get_cont_octet_out_count_impl<4>(wchar_t word){
inline int get_cont_octet_out_count_impl<4>(wchar_t word) {
if (word < 0x80) {
return 0;
}
@ -252,7 +255,7 @@ int get_cont_octet_out_count_impl<4>(wchar_t word){
// where wchar_t is defined as UCS2. The warnings are superfluous as the
// specialization is never instantitiated with such compilers, but this
// can cause problems if warnings are being treated as errors, so we guard
// against that. Including <boost/detail/utf8_codecvt_facet.hpp> as we do
// against that. Including <boost/detail/utf8_codecvt_facet.hpp> as we do
// should be enough to get WCHAR_MAX defined.
#if !defined(WCHAR_MAX)
# error WCHAR_MAX not defined!
@ -261,8 +264,8 @@ int get_cont_octet_out_count_impl<4>(wchar_t word){
#if defined(_MSC_VER) && _MSC_VER <= 1310 // 7.1 or earlier
return 2;
#elif WCHAR_MAX > 0x10000
if (word < 0x10000) {
if (word < 0x10000) {
return 2;
}
if (word < 0x200000) {
@ -272,7 +275,7 @@ int get_cont_octet_out_count_impl<4>(wchar_t word){
return 4;
}
return 5;
#else
return 2;
#endif
@ -282,11 +285,12 @@ int get_cont_octet_out_count_impl<4>(wchar_t word){
// How many "continuing octets" will be needed for this word
// == total octets - 1.
int utf8_codecvt_facet::get_cont_octet_out_count(
BOOST_UTF8_DECL int utf8_codecvt_facet::get_cont_octet_out_count(
wchar_t word
) const {
) {
return detail::get_cont_octet_out_count_impl<sizeof(wchar_t)>(word);
}
BOOST_UTF8_END_NAMESPACE
#endif

View File

@ -19,7 +19,6 @@
"Miscellaneous"
],
"maintainers": [
"Beman Dawes <bdawes -at- acm.org>",
"Robert Ramey <ramey -at- rrsd.com>",
"Rene Rivera <grafikrobot -at- gmail.com>",
"Andrey Semashev <andrey.semashev -at- gmail.com>"

View File

@ -5,28 +5,33 @@
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
################################################################################
import testing ;
import config : requires ;
build-project container_fwd ;
project detail/test
: requirements
<library>/boost/detail//boost_detail
<library>/boost/type_traits//boost_type_traits
<c++-template-depth>300
<toolset>clang:<cxxflags>-Wno-unused
<toolset>clang:<cxxflags>-Wno-tautological-compare
<toolset>clang:<cxxflags>-ftemplate-depth-300
<toolset>gcc:<cxxflags>-ftemplate-depth-300
<toolset>gcc:<define>_STLP_DEBUG
# Do not enable libstdc++ debug mode because of gcc 10.1 bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95289
# <toolset>gcc:<define>_GLIBCXX_DEBUG
<toolset>darwin:<cxxflags>-ftemplate-depth-300
;
# import rules for testing conditional on config file variables
import ../../config/checks/config : requires ;
import-search /boost/config/checks ;
import config : requires ;
run binary_search_test.cpp ;
run blank_test.cpp ;
run is_sorted_test.cpp ;
run bitmask_test.cpp : : : [ requires cxx11_scoped_enums ] ;
run is_sorted_test.cpp /boost/array//boost_array ;
run numeric_traits_test.cpp ;
run is_xxx_test.cpp ;
run is_xxx_test.cpp /boost/preprocessor//boost_preprocessor ;
# run test_utf8_codecvt.cpp : : : [ requires std_wstreambuf ] ;
run test_utf8_codecvt.cpp ;
run allocator_utilities_test.cpp ;

184
test/bitmask_test.cpp Normal file
View File

@ -0,0 +1,184 @@
/*
* 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)
*
* Copyright (c) 2025 Andrey Semashev
*/
#include <boost/detail/bitmask.hpp>
#include <boost/core/lightweight_test.hpp>
enum unscoped_enum
{
zero = 0,
one = 1,
two = 2,
four = 4
};
BOOST_BITMASK(unscoped_enum)
void test_unscoped_enum()
{
BOOST_TEST((one | two) == ((unscoped_enum)(1 | 2)));
BOOST_TEST((one & two) == ((unscoped_enum)(1 & 2)));
BOOST_TEST((one ^ two) == ((unscoped_enum)(1 ^ 2)));
BOOST_TEST((one | one) == ((unscoped_enum)(1 | 1)));
BOOST_TEST((one & one) == ((unscoped_enum)(1 & 1)));
BOOST_TEST((one ^ one) == ((unscoped_enum)(1 ^ 1)));
BOOST_TEST((~one) == ((unscoped_enum)(~1)));
{
unscoped_enum val = one;
val |= two;
BOOST_TEST(val == ((unscoped_enum)(1 | 2)));
}
{
unscoped_enum val = one;
val &= two;
BOOST_TEST(val == ((unscoped_enum)(1 & 2)));
}
{
unscoped_enum val = one;
val ^= two;
BOOST_TEST(val == ((unscoped_enum)(1 ^ 2)));
}
{
unscoped_enum val = one;
val |= one;
BOOST_TEST(val == ((unscoped_enum)(1 | 1)));
}
{
unscoped_enum val = one;
val &= one;
BOOST_TEST(val == ((unscoped_enum)(1 & 1)));
}
{
unscoped_enum val = one;
val ^= one;
BOOST_TEST(val == ((unscoped_enum)(1 ^ 1)));
}
BOOST_TEST(!zero);
BOOST_TEST(!!one);
}
enum class scoped_enum
{
none = 0,
x = 8,
y = 16,
z = 32
};
BOOST_BITMASK(scoped_enum)
void test_scoped_enum()
{
BOOST_TEST((scoped_enum::x | scoped_enum::y) == ((scoped_enum)(8 | 16)));
BOOST_TEST((scoped_enum::x & scoped_enum::y) == ((scoped_enum)(8 & 16)));
BOOST_TEST((scoped_enum::x ^ scoped_enum::y) == ((scoped_enum)(8 ^ 16)));
BOOST_TEST((scoped_enum::x | scoped_enum::x) == ((scoped_enum)(8 | 8)));
BOOST_TEST((scoped_enum::x & scoped_enum::x) == ((scoped_enum)(8 & 8)));
BOOST_TEST((scoped_enum::x ^ scoped_enum::x) == ((scoped_enum)(8 ^ 8)));
BOOST_TEST((~scoped_enum::x) == ((scoped_enum)(~8)));
{
scoped_enum val = scoped_enum::x;
val |= scoped_enum::y;
BOOST_TEST(val == ((scoped_enum)(8 | 16)));
}
{
scoped_enum val = scoped_enum::x;
val &= scoped_enum::y;
BOOST_TEST(val == ((scoped_enum)(8 & 16)));
}
{
scoped_enum val = scoped_enum::x;
val ^= scoped_enum::y;
BOOST_TEST(val == ((scoped_enum)(8 ^ 16)));
}
{
scoped_enum val = scoped_enum::x;
val |= scoped_enum::x;
BOOST_TEST(val == ((scoped_enum)(8 | 8)));
}
{
scoped_enum val = scoped_enum::x;
val &= scoped_enum::x;
BOOST_TEST(val == ((scoped_enum)(8 & 8)));
}
{
scoped_enum val = scoped_enum::x;
val ^= scoped_enum::x;
BOOST_TEST(val == ((scoped_enum)(8 ^ 8)));
}
BOOST_TEST(!scoped_enum::none);
BOOST_TEST(!!scoped_enum::x);
}
namespace my_namespace {
enum class namespaced_enum : unsigned int
{
empty = 0,
a = 64,
b = 128,
c = 256
};
BOOST_BITMASK(namespaced_enum)
} // namespace my_namespace
void test_namespaced_enum()
{
BOOST_TEST((my_namespace::namespaced_enum::a | my_namespace::namespaced_enum::b) == ((my_namespace::namespaced_enum)(64u | 128u)));
BOOST_TEST((my_namespace::namespaced_enum::a & my_namespace::namespaced_enum::b) == ((my_namespace::namespaced_enum)(64u & 128u)));
BOOST_TEST((my_namespace::namespaced_enum::a ^ my_namespace::namespaced_enum::b) == ((my_namespace::namespaced_enum)(64u ^ 128u)));
BOOST_TEST((my_namespace::namespaced_enum::a | my_namespace::namespaced_enum::a) == ((my_namespace::namespaced_enum)(64u | 64u)));
BOOST_TEST((my_namespace::namespaced_enum::a & my_namespace::namespaced_enum::a) == ((my_namespace::namespaced_enum)(64u & 64u)));
BOOST_TEST((my_namespace::namespaced_enum::a ^ my_namespace::namespaced_enum::a) == ((my_namespace::namespaced_enum)(64u ^ 64u)));
BOOST_TEST((~my_namespace::namespaced_enum::a) == ((my_namespace::namespaced_enum)(~64u)));
{
my_namespace::namespaced_enum val = my_namespace::namespaced_enum::a;
val |= my_namespace::namespaced_enum::b;
BOOST_TEST(val == ((my_namespace::namespaced_enum)(64u | 128u)));
}
{
my_namespace::namespaced_enum val = my_namespace::namespaced_enum::a;
val &= my_namespace::namespaced_enum::b;
BOOST_TEST(val == ((my_namespace::namespaced_enum)(64u & 128u)));
}
{
my_namespace::namespaced_enum val = my_namespace::namespaced_enum::a;
val ^= my_namespace::namespaced_enum::b;
BOOST_TEST(val == ((my_namespace::namespaced_enum)(64u ^ 128u)));
}
{
my_namespace::namespaced_enum val = my_namespace::namespaced_enum::a;
val |= my_namespace::namespaced_enum::a;
BOOST_TEST(val == ((my_namespace::namespaced_enum)(64u | 64u)));
}
{
my_namespace::namespaced_enum val = my_namespace::namespaced_enum::a;
val &= my_namespace::namespaced_enum::a;
BOOST_TEST(val == ((my_namespace::namespaced_enum)(64u & 64u)));
}
{
my_namespace::namespaced_enum val = my_namespace::namespaced_enum::a;
val ^= my_namespace::namespaced_enum::a;
BOOST_TEST(val == ((my_namespace::namespaced_enum)(64u ^ 64u)));
}
BOOST_TEST(!my_namespace::namespaced_enum::empty);
BOOST_TEST(!!my_namespace::namespaced_enum::a);
}
int main()
{
test_unscoped_enum();
test_scoped_enum();
test_namespaced_enum();
return boost::report_errors();
}

View File

@ -9,9 +9,12 @@ project detail/test/container_fwd
: requirements
<warnings>all
<toolset>intel:<warnings>on
<toolset>gcc:<cxxflags>"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter -Wconversion"
<toolset>darwin:<cxxflags>"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter -Wconversion"
<toolset>clang:<cxxflags>"-pedantic -Wextra -Wmismatched-tags"
<toolset>gcc:<warnings>pedantic
<toolset>gcc:<cxxflags>"-Wstrict-aliasing -fstrict-aliasing -Wsign-promo -Wunused-parameter -Wconversion"
<toolset>darwin:<warnings>pedantic
<toolset>darwin:<cxxflags>"-Wstrict-aliasing -fstrict-aliasing -Wsign-promo -Wunused-parameter -Wconversion"
<toolset>clang:<warnings>pedantic
<toolset>clang:<cxxflags>"-Wmismatched-tags"
<warnings-as-errors>on
;

View File

@ -19,6 +19,10 @@
#include <boost/config.hpp>
#include <boost/core/no_exceptions_support.hpp>
#if !defined(BOOST_NO_EXCEPTIONS)
#include <exception>
#endif
#define BOOST_UTF8_BEGIN_NAMESPACE namespace boost { namespace detail {
#define BOOST_UTF8_END_NAMESPACE } }
#include <boost/detail/utf8_codecvt_facet.hpp>
@ -47,6 +51,9 @@ namespace std{
#include <boost/core/lightweight_test.hpp>
// Directory of the test executable
std::string executable_dir;
template<std::size_t s>
struct test_data
{
@ -134,7 +141,7 @@ test_main(int /* argc */, char * /* argv */[]) {
// Send our test UTF-8 data to file
{
std::ofstream ofs;
ofs.open("test.dat");
ofs.open((executable_dir + "test.dat").c_str());
std::copy(
td::utf8_encoding,
td::utf8_encoding + sizeof(td::utf8_encoding) / sizeof(unsigned char),
@ -147,7 +154,7 @@ test_main(int /* argc */, char * /* argv */[]) {
{
std::wifstream ifs;
ifs.imbue(utf8_locale);
ifs.open("test.dat");
ifs.open((executable_dir + "test.dat").c_str());
std::wint_t item = 0;
// note can't use normal vector from iterator constructor because
@ -169,7 +176,7 @@ test_main(int /* argc */, char * /* argv */[]) {
{
std::wofstream ofs;
ofs.imbue(utf8_locale);
ofs.open("test2.dat");
ofs.open((executable_dir + "test2.dat").c_str());
std::copy(
from_file.begin(),
from_file.end(),
@ -182,21 +189,21 @@ test_main(int /* argc */, char * /* argv */[]) {
typedef std::istream_iterator<utf8_t> is_iter;
is_iter end_iter;
std::ifstream ifs1("test.dat");
std::ifstream ifs1((executable_dir + "test.dat").c_str());
is_iter it1(ifs1);
std::vector<utf8_t> data1;
std::copy(it1, end_iter, std::back_inserter(data1));
std::ifstream ifs2("test2.dat");
std::ifstream ifs2((executable_dir + "test2.dat").c_str());
is_iter it2(ifs2);
std::vector<utf8_t> data2;
std::copy(it2, end_iter, std::back_inserter(data2));
BOOST_TEST(data1 == data2);
BOOST_TEST_ALL_EQ(data1.begin(), data1.end(), data2.begin(), data2.end());
}
// some libraries have trouble that only shows up with longer strings
const wchar_t * test3_data = L"\
<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>\
<!DOCTYPE boost_serialization>\
@ -224,13 +231,13 @@ test_main(int /* argc */, char * /* argv */[]) {
</a>\
</boost_serialization>\
";
// Send the UCS4_data back out, converting to UTF-8
std::size_t l = std::wcslen(test3_data);
{
std::wofstream ofs;
ofs.imbue(utf8_locale);
ofs.open("test3.dat");
ofs.open((executable_dir + "test3.dat").c_str());
std::copy(
test3_data,
test3_data + l,
@ -242,7 +249,7 @@ test_main(int /* argc */, char * /* argv */[]) {
{
std::wifstream ifs;
ifs.imbue(utf8_locale);
ifs.open("test3.dat");
ifs.open((executable_dir + "test3.dat").c_str());
ifs >> std::noskipws;
BOOST_TEST(
std::equal(
@ -278,25 +285,32 @@ test_main(int /* argc */, char * /* argv */[]) {
}
int
main(int argc, char * argv[]){
main(int argc, char * argv[]) {
if (argc > 0) {
// We need to save the path to executable to create test files in the same directory.
// This allows running different configurations of the test (release/debug, different C++ versions, etc.) in parallel.
std::string exec_name = argv[0];
std::string::size_type last_dir_sep_pos = exec_name.find_last_of("/\\");
if (last_dir_sep_pos != std::string::npos)
executable_dir = exec_name.substr(0, last_dir_sep_pos + 1); // include the trailing directory separator
}
int retval = 1;
BOOST_TRY{
retval = test_main(argc, argv);
}
#ifndef BOOST_NO_EXCEPTION_STD_NAMESPACE
BOOST_CATCH(const std::exception & e){
BOOST_ERROR(e.what());
}
#endif
#ifndef BOOST_NO_EXCEPTION_STD_NAMESPACE
BOOST_CATCH(const std::exception & e){
BOOST_ERROR(e.what());
}
#endif
BOOST_CATCH(...){
BOOST_ERROR("failed with uncaught exception:");
}
BOOST_CATCH_END
int error_count = boost::report_errors();
if(error_count > 0)
if (error_count > 0)
retval = error_count;
return retval;
}