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. # 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 # 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 cmake_minimum_required(VERSION 3.5...3.20)
# Subject to change; please do not rely on the contents of this file yet.
cmake_minimum_required(VERSION 3.5) project(boost_detail VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX)
project(BoostDetail LANGUAGES CXX)
add_library(boost_detail INTERFACE) add_library(boost_detail INTERFACE)
add_library(Boost::detail ALIAS boost_detail) 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

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

View File

@ -1,6 +1,7 @@
// boost/detail/bitmask.hpp ------------------------------------------------// // boost/detail/bitmask.hpp ------------------------------------------------//
// Copyright Beman Dawes 2006 // Copyright Beman Dawes 2006
// Copyright Andrey Semashev 2025
// Distributed under the Boost Software License, Version 1.0 // Distributed under the Boost Software License, Version 1.0
// http://www.boost.org/LICENSE_1_0.txt // http://www.boost.org/LICENSE_1_0.txt
@ -18,41 +19,73 @@
#define BOOST_BITMASK_HPP #define BOOST_BITMASK_HPP
#include <boost/config.hpp> #include <boost/config.hpp>
#include <boost/cstdint.hpp>
#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) \ #define BOOST_BITMASK(Bitmask) \
\ \
inline BOOST_CONSTEXPR Bitmask operator| (Bitmask x , Bitmask y ) \ inline BOOST_CONSTEXPR Bitmask operator| (Bitmask x, Bitmask y) BOOST_NOEXCEPT \
{ return static_cast<Bitmask>( static_cast<boost::int_least32_t>(x) \ { return static_cast< Bitmask >(static_cast< ::boost::detail::bitmask::underlying_type_t< Bitmask > >(x) \
| static_cast<boost::int_least32_t>(y)); } \ | static_cast< ::boost::detail::bitmask::underlying_type_t< Bitmask > >(y)); } \
\ \
inline BOOST_CONSTEXPR Bitmask operator& (Bitmask x , Bitmask y ) \ inline BOOST_CONSTEXPR Bitmask operator& (Bitmask x, Bitmask y) BOOST_NOEXCEPT \
{ return static_cast<Bitmask>( static_cast<boost::int_least32_t>(x) \ { return static_cast< Bitmask >(static_cast< ::boost::detail::bitmask::underlying_type_t< Bitmask > >(x) \
& static_cast<boost::int_least32_t>(y)); } \ & static_cast< ::boost::detail::bitmask::underlying_type_t< Bitmask > >(y)); } \
\ \
inline BOOST_CONSTEXPR Bitmask operator^ (Bitmask x , Bitmask y ) \ inline BOOST_CONSTEXPR Bitmask operator^ (Bitmask x, Bitmask y) BOOST_NOEXCEPT \
{ return static_cast<Bitmask>( static_cast<boost::int_least32_t>(x) \ { return static_cast< Bitmask >(static_cast< ::boost::detail::bitmask::underlying_type_t< Bitmask > >(x) \
^ static_cast<boost::int_least32_t>(y)); } \ ^ static_cast< ::boost::detail::bitmask::underlying_type_t< Bitmask > >(y)); } \
\ \
inline BOOST_CONSTEXPR Bitmask operator~ (Bitmask x ) \ inline BOOST_CONSTEXPR Bitmask operator~ (Bitmask x) BOOST_NOEXCEPT \
{ return static_cast<Bitmask>(~static_cast<boost::int_least32_t>(x)); } \ { return static_cast< Bitmask >(~static_cast< ::boost::detail::bitmask::underlying_type_t< Bitmask > >(x)); } \
\ \
inline Bitmask & operator&=(Bitmask& x , Bitmask y) \ inline BOOST_CXX14_CONSTEXPR Bitmask& operator&=(Bitmask& x, Bitmask y) BOOST_NOEXCEPT \
{ x = x & y ; return x ; } \ { x = x & y; return x; } \
\ \
inline Bitmask & operator|=(Bitmask& x , Bitmask y) \ inline BOOST_CXX14_CONSTEXPR Bitmask& operator|=(Bitmask& x, Bitmask y) BOOST_NOEXCEPT \
{ x = x | y ; return x ; } \ { x = x | y; return x; } \
\ \
inline Bitmask & operator^=(Bitmask& x , Bitmask y) \ inline BOOST_CXX14_CONSTEXPR Bitmask& operator^=(Bitmask& x, Bitmask y) BOOST_NOEXCEPT \
{ x = x ^ y ; return x ; } \ { x = x ^ y; return x; } \
\ \
/* Boost extensions to [bitmask.types] */ \ /* Boost extensions to [bitmask.types] */ \
\ \
inline BOOST_CONSTEXPR bool operator!(Bitmask x) \ inline BOOST_CONSTEXPR bool operator!(Bitmask x) BOOST_NOEXCEPT \
{ return !static_cast<int>(x); } \ { return !static_cast< ::boost::detail::bitmask::underlying_type_t< Bitmask > >(x); } \
\ \
inline BOOST_CONSTEXPR bool bitmask_set(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; } { return !!x; }
#endif // BOOST_BITMASK_HPP #endif // BOOST_BITMASK_HPP

View File

@ -109,28 +109,29 @@ BOOST_UTF8_BEGIN_NAMESPACE
#define BOOST_UTF8_DECL #define BOOST_UTF8_DECL
#endif #endif
struct BOOST_UTF8_DECL utf8_codecvt_facet : struct BOOST_SYMBOL_VISIBLE utf8_codecvt_facet :
public std::codecvt<wchar_t, char, std::mbstate_t> public std::codecvt<wchar_t, char, std::mbstate_t>
{ {
public: public:
explicit utf8_codecvt_facet(std::size_t no_locale_manage=0); BOOST_UTF8_DECL explicit utf8_codecvt_facet(std::size_t no_locale_manage = 0);
virtual ~utf8_codecvt_facet(); BOOST_UTF8_DECL virtual ~utf8_codecvt_facet();
protected: protected:
virtual std::codecvt_base::result do_in( BOOST_UTF8_DECL virtual std::codecvt_base::result do_in(
std::mbstate_t& state, std::mbstate_t& state,
const char * from, const char * from,
const char * from_end, const char * from_end,
const char * & from_next, const char * & from_next,
wchar_t * to, wchar_t * to,
wchar_t * to_end, wchar_t * to_end,
wchar_t*& to_next wchar_t * & to_next
) const; ) const;
virtual std::codecvt_base::result do_out( BOOST_UTF8_DECL virtual std::codecvt_base::result do_out(
std::mbstate_t & state, std::mbstate_t & state,
const wchar_t * from, const wchar_t * from,
const wchar_t * from_end, const wchar_t * from_end,
const wchar_t* & from_next, const wchar_t * & from_next,
char * to, char * to,
char * to_end, char * to_end,
char * & to_next char * & to_next
@ -150,11 +151,11 @@ protected:
return get_octet_count(lead_octet) - 1; 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 // How many "continuing octets" will be needed for this word
// == total octets - 1. // == 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 { virtual bool do_always_noconv() const BOOST_NOEXCEPT_OR_NOTHROW {
return false; return false;
@ -162,7 +163,7 @@ protected:
// UTF-8 isn't really stateful since we rewind on partial conversions // UTF-8 isn't really stateful since we rewind on partial conversions
virtual std::codecvt_base::result do_unshift( virtual std::codecvt_base::result do_unshift(
std::mbstate_t&, std::mbstate_t &,
char * from, char * from,
char * /*to*/, char * /*to*/,
char * & next char * & next
@ -178,7 +179,7 @@ protected:
// How many char objects can I process to get <= max_limit // How many char objects can I process to get <= max_limit
// wchar_t objects? // wchar_t objects?
virtual int do_length( BOOST_UTF8_DECL virtual int do_length(
std::mbstate_t &, std::mbstate_t &,
const char * from, const char * from,
const char * from_end, const char * from_end,

View File

@ -30,17 +30,30 @@ BOOST_UTF8_BEGIN_NAMESPACE
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// implementation for wchar_t // 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::size_t no_locale_manage
) : ) :
std::codecvt<wchar_t, char, std::mbstate_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 // Translate incoming UTF-8 into UCS-4
std::codecvt_base::result utf8_codecvt_facet::do_in( BOOST_UTF8_DECL std::codecvt_base::result utf8_codecvt_facet::do_in(
std::mbstate_t& /*state*/, std::mbstate_t& /*state*/,
const char * from, const char * from,
const char * from_end, const char * from_end,
@ -57,10 +70,11 @@ std::codecvt_base::result utf8_codecvt_facet::do_in(
// then mash the whole lot together. Note that each continuing // then mash the whole lot together. Note that each continuing
// octet only uses 6 bits as unique values, so only shift by // octet only uses 6 bits as unique values, so only shift by
// multiples of 6 to combine. // multiples of 6 to combine.
const wchar_t * const octet1_modifier_table = detail::get_octet1_modifier_table();
while (from != from_end && to != to_end) { while (from != from_end && to != to_end) {
// Error checking on the first octet // Error checking on the first octet
if (invalid_leading_octet(*from)){ if (invalid_leading_octet(*from)) {
from_next = from; from_next = from;
to_next = to; to_next = to;
return std::codecvt_base::error; return std::codecvt_base::error;
@ -69,21 +83,18 @@ std::codecvt_base::result utf8_codecvt_facet::do_in(
// The first octet is adjusted by a value dependent upon // The first octet is adjusted by a value dependent upon
// the number of "continuing octets" encoding the character // the number of "continuing octets" encoding the character
const int cont_octet_count = get_cont_octet_count(*from); const int cont_octet_count = get_cont_octet_count(*from);
const wchar_t octet1_modifier_table[] = {
0x00, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc
};
// The unsigned char conversion is necessary in case char is // The unsigned char conversion is necessary in case char is
// signed (I learned this the hard way) // signed (I learned this the hard way)
wchar_t ucs_result = wchar_t ucs_result =
(unsigned char)(*from++) - octet1_modifier_table[cont_octet_count]; (unsigned char)(*from++) - octet1_modifier_table[cont_octet_count];
// Invariants : // Invariants:
// 1) At the start of the loop, 'i' continuing characters have been // 1) At the start of the loop, 'i' continuing characters have been
// processed // processed
// 2) *from points to the next continuing character to be processed. // 2) *from points to the next continuing character to be processed.
int i = 0; int i = 0;
while(i != cont_octet_count && from != from_end) { while (i != cont_octet_count && from != from_end) {
// Error checking on continuing characters // Error checking on continuing characters
if (invalid_continuing_octet(*from)) { if (invalid_continuing_octet(*from)) {
@ -103,7 +114,7 @@ std::codecvt_base::result utf8_codecvt_facet::do_in(
// If the buffer ends with an incomplete unicode character... // If the buffer ends with an incomplete unicode character...
if (from == from_end && i != cont_octet_count) { if (from == from_end && i != cont_octet_count) {
// rewind "from" to before the current character translation // rewind "from" to before the current character translation
from_next = from - (i+1); from_next = from - (i + 1);
to_next = to; to_next = to;
return std::codecvt_base::partial; return std::codecvt_base::partial;
} }
@ -113,11 +124,13 @@ std::codecvt_base::result utf8_codecvt_facet::do_in(
to_next = to; to_next = to;
// Were we done converting or did we run out of destination space? // Were we done converting or did we run out of destination space?
if(from == from_end) return std::codecvt_base::ok; if (from == from_end)
else return std::codecvt_base::partial; return std::codecvt_base::ok;
else
return std::codecvt_base::partial;
} }
std::codecvt_base::result utf8_codecvt_facet::do_out( BOOST_UTF8_DECL std::codecvt_base::result utf8_codecvt_facet::do_out(
std::mbstate_t& /*state*/, std::mbstate_t& /*state*/,
const wchar_t * from, const wchar_t * from,
const wchar_t * from_end, const wchar_t * from_end,
@ -127,11 +140,7 @@ std::codecvt_base::result utf8_codecvt_facet::do_out(
char * & to_next char * & to_next
) const ) const
{ {
// RG - consider merging this table with the other one const wchar_t * const octet1_modifier_table = detail::get_octet1_modifier_table();
const wchar_t octet1_modifier_table[] = {
0x00, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc
};
wchar_t max_wchar = (std::numeric_limits<wchar_t>::max)(); wchar_t max_wchar = (std::numeric_limits<wchar_t>::max)();
while (from != from_end && to != to_end) { while (from != from_end && to != to_end) {
@ -145,7 +154,7 @@ std::codecvt_base::result utf8_codecvt_facet::do_out(
int cont_octet_count = get_cont_octet_out_count(*from); int cont_octet_count = get_cont_octet_out_count(*from);
// RG - comment this formula better // RG - comment this formula better
int shift_exponent = (cont_octet_count) * 6; int shift_exponent = cont_octet_count * 6;
// Process the first character // Process the first character
*to++ = static_cast<char>(octet1_modifier_table[cont_octet_count] + *to++ = static_cast<char>(octet1_modifier_table[cont_octet_count] +
@ -163,23 +172,26 @@ std::codecvt_base::result utf8_codecvt_facet::do_out(
++i; ++i;
} }
// If we filled up the out buffer before encoding the character // If we filled up the out buffer before encoding the character
if(to == to_end && i != cont_octet_count) { if (to == to_end && i != cont_octet_count) {
from_next = from; from_next = from;
to_next = to - (i+1); to_next = to - (i + 1);
return std::codecvt_base::partial; return std::codecvt_base::partial;
} }
++from; ++from;
} }
from_next = from; from_next = from;
to_next = to; to_next = to;
// Were we done or did we run out of destination space // Were we done or did we run out of destination space
if(from == from_end) return std::codecvt_base::ok; if (from == from_end)
else return std::codecvt_base::partial; return std::codecvt_base::ok;
else
return std::codecvt_base::partial;
} }
// How many char objects can I process to get <= max_limit // How many char objects can I process to get <= max_limit
// wchar_t objects? // wchar_t objects?
int utf8_codecvt_facet::do_length( BOOST_UTF8_DECL int utf8_codecvt_facet::do_length(
std::mbstate_t &, std::mbstate_t &,
const char * from, const char * from,
const char * from_end, const char * from_end,
@ -189,30 +201,21 @@ int utf8_codecvt_facet::do_length(
throw() throw()
#endif #endif
{ {
// RG - this code is confusing! I need a better way to express it. const char * from_next = from;
// and test cases. 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);
// Invariants: // The buffer may represent incomplete characters, so terminate early if one is found
// 1) last_octet_count has the size of the last measured character if (octet_count > static_cast<std::size_t>(from_end - from_next))
// 2) char_count holds the number of characters shown to fit break;
// within the bounds so far (no greater than max_limit) from_next += octet_count;
// 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;
} }
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 unsigned char lead_octet
){ ) {
// if the 0-bit (MSB) is 0, then 1 character // if the 0-bit (MSB) is 0, then 1 character
if (lead_octet <= 0x7f) return 1; if (lead_octet <= 0x7f) return 1;
@ -229,7 +232,7 @@ unsigned int utf8_codecvt_facet::get_octet_count(
namespace detail { namespace detail {
template<std::size_t s> 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) { if (word < 0x80) {
return 0; return 0;
} }
@ -240,7 +243,7 @@ int get_cont_octet_out_count_impl(wchar_t word){
} }
template<> 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) { if (word < 0x80) {
return 0; return 0;
} }
@ -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 // How many "continuing octets" will be needed for this word
// == total octets - 1. // == 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 wchar_t word
) const { ) {
return detail::get_cont_octet_out_count_impl<sizeof(wchar_t)>(word); return detail::get_cont_octet_out_count_impl<sizeof(wchar_t)>(word);
} }
BOOST_UTF8_END_NAMESPACE BOOST_UTF8_END_NAMESPACE
#endif #endif

View File

@ -19,7 +19,6 @@
"Miscellaneous" "Miscellaneous"
], ],
"maintainers": [ "maintainers": [
"Beman Dawes <bdawes -at- acm.org>",
"Robert Ramey <ramey -at- rrsd.com>", "Robert Ramey <ramey -at- rrsd.com>",
"Rene Rivera <grafikrobot -at- gmail.com>", "Rene Rivera <grafikrobot -at- gmail.com>",
"Andrey Semashev <andrey.semashev -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) # 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 ; build-project container_fwd ;
project detail/test project detail/test
: requirements : 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-unused
<toolset>clang:<cxxflags>-Wno-tautological-compare <toolset>clang:<cxxflags>-Wno-tautological-compare
<toolset>clang:<cxxflags>-ftemplate-depth-300
<toolset>gcc:<cxxflags>-ftemplate-depth-300
<toolset>gcc:<define>_STLP_DEBUG <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 # 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>gcc:<define>_GLIBCXX_DEBUG
<toolset>darwin:<cxxflags>-ftemplate-depth-300
; ;
# import rules for testing conditional on config file variables # 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 binary_search_test.cpp ;
run blank_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 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 : : : [ requires std_wstreambuf ] ;
run test_utf8_codecvt.cpp ; run test_utf8_codecvt.cpp ;
run allocator_utilities_test.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 : requirements
<warnings>all <warnings>all
<toolset>intel:<warnings>on <toolset>intel:<warnings>on
<toolset>gcc:<cxxflags>"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter -Wconversion" <toolset>gcc:<warnings>pedantic
<toolset>darwin:<cxxflags>"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter -Wconversion" <toolset>gcc:<cxxflags>"-Wstrict-aliasing -fstrict-aliasing -Wsign-promo -Wunused-parameter -Wconversion"
<toolset>clang:<cxxflags>"-pedantic -Wextra -Wmismatched-tags" <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 <warnings-as-errors>on
; ;

View File

@ -19,6 +19,10 @@
#include <boost/config.hpp> #include <boost/config.hpp>
#include <boost/core/no_exceptions_support.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_BEGIN_NAMESPACE namespace boost { namespace detail {
#define BOOST_UTF8_END_NAMESPACE } } #define BOOST_UTF8_END_NAMESPACE } }
#include <boost/detail/utf8_codecvt_facet.hpp> #include <boost/detail/utf8_codecvt_facet.hpp>
@ -47,6 +51,9 @@ namespace std{
#include <boost/core/lightweight_test.hpp> #include <boost/core/lightweight_test.hpp>
// Directory of the test executable
std::string executable_dir;
template<std::size_t s> template<std::size_t s>
struct test_data struct test_data
{ {
@ -134,7 +141,7 @@ test_main(int /* argc */, char * /* argv */[]) {
// Send our test UTF-8 data to file // Send our test UTF-8 data to file
{ {
std::ofstream ofs; std::ofstream ofs;
ofs.open("test.dat"); ofs.open((executable_dir + "test.dat").c_str());
std::copy( std::copy(
td::utf8_encoding, td::utf8_encoding,
td::utf8_encoding + sizeof(td::utf8_encoding) / sizeof(unsigned char), td::utf8_encoding + sizeof(td::utf8_encoding) / sizeof(unsigned char),
@ -147,7 +154,7 @@ test_main(int /* argc */, char * /* argv */[]) {
{ {
std::wifstream ifs; std::wifstream ifs;
ifs.imbue(utf8_locale); ifs.imbue(utf8_locale);
ifs.open("test.dat"); ifs.open((executable_dir + "test.dat").c_str());
std::wint_t item = 0; std::wint_t item = 0;
// note can't use normal vector from iterator constructor because // note can't use normal vector from iterator constructor because
@ -169,7 +176,7 @@ test_main(int /* argc */, char * /* argv */[]) {
{ {
std::wofstream ofs; std::wofstream ofs;
ofs.imbue(utf8_locale); ofs.imbue(utf8_locale);
ofs.open("test2.dat"); ofs.open((executable_dir + "test2.dat").c_str());
std::copy( std::copy(
from_file.begin(), from_file.begin(),
from_file.end(), from_file.end(),
@ -182,17 +189,17 @@ test_main(int /* argc */, char * /* argv */[]) {
typedef std::istream_iterator<utf8_t> is_iter; typedef std::istream_iterator<utf8_t> is_iter;
is_iter end_iter; is_iter end_iter;
std::ifstream ifs1("test.dat"); std::ifstream ifs1((executable_dir + "test.dat").c_str());
is_iter it1(ifs1); is_iter it1(ifs1);
std::vector<utf8_t> data1; std::vector<utf8_t> data1;
std::copy(it1, end_iter, std::back_inserter(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); is_iter it2(ifs2);
std::vector<utf8_t> data2; std::vector<utf8_t> data2;
std::copy(it2, end_iter, std::back_inserter(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 // some libraries have trouble that only shows up with longer strings
@ -230,7 +237,7 @@ test_main(int /* argc */, char * /* argv */[]) {
{ {
std::wofstream ofs; std::wofstream ofs;
ofs.imbue(utf8_locale); ofs.imbue(utf8_locale);
ofs.open("test3.dat"); ofs.open((executable_dir + "test3.dat").c_str());
std::copy( std::copy(
test3_data, test3_data,
test3_data + l, test3_data + l,
@ -242,7 +249,7 @@ test_main(int /* argc */, char * /* argv */[]) {
{ {
std::wifstream ifs; std::wifstream ifs;
ifs.imbue(utf8_locale); ifs.imbue(utf8_locale);
ifs.open("test3.dat"); ifs.open((executable_dir + "test3.dat").c_str());
ifs >> std::noskipws; ifs >> std::noskipws;
BOOST_TEST( BOOST_TEST(
std::equal( std::equal(
@ -278,25 +285,32 @@ test_main(int /* argc */, char * /* argv */[]) {
} }
int 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; int retval = 1;
BOOST_TRY{ BOOST_TRY{
retval = test_main(argc, argv); retval = test_main(argc, argv);
} }
#ifndef BOOST_NO_EXCEPTION_STD_NAMESPACE #ifndef BOOST_NO_EXCEPTION_STD_NAMESPACE
BOOST_CATCH(const std::exception & e){ BOOST_CATCH(const std::exception & e){
BOOST_ERROR(e.what()); BOOST_ERROR(e.what());
} }
#endif #endif
BOOST_CATCH(...){ BOOST_CATCH(...){
BOOST_ERROR("failed with uncaught exception:"); BOOST_ERROR("failed with uncaught exception:");
} }
BOOST_CATCH_END BOOST_CATCH_END
int error_count = boost::report_errors(); int error_count = boost::report_errors();
if(error_count > 0) if (error_count > 0)
retval = error_count; retval = error_count;
return retval; return retval;
} }