mirror of
https://github.com/boostorg/compat.git
synced 2026-01-19 16:12:15 +00:00
Compare commits
102 Commits
feature/sh
...
feature/pr
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1a8bb0b574 | ||
|
|
c18e5f2276 | ||
|
|
d2d5cbe094 | ||
|
|
c49f822b2e | ||
|
|
889d2608e6 | ||
|
|
787a5dd4d1 | ||
|
|
a6520ef2e1 | ||
|
|
0d2593326f | ||
|
|
4abae7082a | ||
|
|
d802b97ba8 | ||
|
|
e6d2faa267 | ||
|
|
9244cd17b9 | ||
|
|
37dbb81cce | ||
|
|
8ed23dd6a7 | ||
|
|
915a207fc9 | ||
|
|
2a5e8031f8 | ||
|
|
b9f5082f6e | ||
|
|
6a0f933b2e | ||
|
|
ef0f49933b | ||
|
|
438e0fbbf3 | ||
|
|
df5cd71735 | ||
|
|
6f8c2fe8c1 | ||
|
|
e5f0043abc | ||
|
|
fb5f95b3b2 | ||
|
|
cc45f3198a | ||
|
|
ef87b7c225 | ||
|
|
257ce0b4bd | ||
|
|
ea462a4363 | ||
|
|
d5cf9802bd | ||
|
|
28496a6a01 | ||
|
|
09dd50c8db | ||
|
|
f969df9b2a | ||
|
|
74d9d80471 | ||
|
|
26e3edd0af | ||
|
|
09d1a51778 | ||
|
|
f0aeb3ba95 | ||
|
|
0afd51fcd3 | ||
|
|
ed8837a4ff | ||
|
|
54c72a5033 | ||
|
|
2bc168926b | ||
|
|
3025c1b929 | ||
|
|
04e6d2ce20 | ||
|
|
8cfda56a62 | ||
|
|
430c9b1b60 | ||
|
|
a91461a442 | ||
|
|
984d6b39da | ||
|
|
87e758f538 | ||
|
|
ab2670f0a8 | ||
|
|
0561949e15 | ||
|
|
5e88ebb1d1 | ||
|
|
d071dfc91f | ||
|
|
7fc7795d6b | ||
|
|
30242af2c2 | ||
|
|
9a58caf918 | ||
|
|
28e71552eb | ||
|
|
10ad6ab592 | ||
|
|
39ddb40a47 | ||
|
|
928f2d7255 | ||
|
|
5a5db4a74f | ||
|
|
acd8c12e91 | ||
|
|
710ea6a904 | ||
|
|
a09b9b2c5a | ||
|
|
758b0c2ef9 | ||
|
|
4ea967b756 | ||
|
|
d745abe3a3 | ||
|
|
fa9180b234 | ||
|
|
abcc654046 | ||
|
|
b6deff5638 | ||
|
|
90e76cb4f4 | ||
|
|
c290c03ea3 | ||
|
|
bba8d5f101 | ||
|
|
56b776fc29 | ||
|
|
0598dd0688 | ||
|
|
53c5bcf824 | ||
|
|
e270914326 | ||
|
|
5b6c4ffe95 | ||
|
|
26e18fd796 | ||
|
|
571b48ca51 | ||
|
|
b4b6cacb9d | ||
|
|
6b0825b893 | ||
|
|
dca886ef30 | ||
|
|
4710db471a | ||
|
|
d83085a5d9 | ||
|
|
8633042b73 | ||
|
|
eba152aa8e | ||
|
|
efff37c7a3 | ||
|
|
d745a4cfba | ||
|
|
9743e1e03f | ||
|
|
3980572c34 | ||
|
|
9cad6fbca9 | ||
|
|
31fe10bf54 | ||
|
|
b6858273bd | ||
|
|
0220855d9c | ||
|
|
91c2054151 | ||
|
|
6153916abe | ||
|
|
c511487e78 | ||
|
|
0008d02a62 | ||
|
|
0387e8afe1 | ||
|
|
6292106e68 | ||
|
|
8f75ad2a75 | ||
|
|
f5da663cbc | ||
|
|
8abbc6d979 |
56
.appveyor.yml
Normal file
56
.appveyor.yml
Normal file
@@ -0,0 +1,56 @@
|
||||
# Copyright 2016-2023 Peter Dimov
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
|
||||
version: 1.0.{build}-{branch}
|
||||
|
||||
shallow_clone: true
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- develop
|
||||
- /feature\/.*/
|
||||
|
||||
environment:
|
||||
matrix:
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
TOOLSET: msvc-14.0
|
||||
ADDRMD: 32,64
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
TOOLSET: msvc-14.1
|
||||
ADDRMD: 32,64
|
||||
CXXSTD: 14,17,latest
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
TOOLSET: msvc-14.1
|
||||
ADDRMD: 32,64
|
||||
CXXSTD: 14,17,latest
|
||||
CXXFLAGS: /permissive-
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
TOOLSET: clang-win
|
||||
ADDRMD: 64
|
||||
CXXSTD: 14,17,latest
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
TOOLSET: clang-win
|
||||
ADDRMD: 64
|
||||
CXXSTD: 14,17,latest
|
||||
|
||||
install:
|
||||
- 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 update --init tools/boostdep
|
||||
- xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\compat\
|
||||
- python tools/boostdep/depinst/depinst.py compat
|
||||
- cmd /c bootstrap
|
||||
- b2 -d0 headers
|
||||
|
||||
build: off
|
||||
|
||||
test_script:
|
||||
- if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
|
||||
- if not "%ADDRMD%" == "" set ADDRMD=address-model=%ADDRMD%
|
||||
- if not "%CXXFLAGS%" == "" set CXXFLAGS=cxxflags=%CXXFLAGS%
|
||||
- if "%CMAKE%%CMAKE_SUBDIR%%CMAKE_INSTALL%" == "" b2 -j3 libs/compat/test toolset=%TOOLSET% %CXXSTD% %ADDRMD% %CXXFLAGS% variant=debug,release embed-manifest-via=linker
|
||||
277
.drone.jsonnet
Normal file
277
.drone.jsonnet
Normal file
@@ -0,0 +1,277 @@
|
||||
# Copyright 2022 Peter Dimov
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
local library = "compat";
|
||||
|
||||
local triggers =
|
||||
{
|
||||
branch: [ "master", "develop", "feature/*" ]
|
||||
};
|
||||
|
||||
local ubsan = { UBSAN: '1', UBSAN_OPTIONS: 'print_stacktrace=1' };
|
||||
local asan = { ASAN: '1' };
|
||||
|
||||
local linux_pipeline(name, image, environment, packages = "", sources = [], arch = "amd64") =
|
||||
{
|
||||
name: name,
|
||||
kind: "pipeline",
|
||||
type: "docker",
|
||||
trigger: triggers,
|
||||
platform:
|
||||
{
|
||||
os: "linux",
|
||||
arch: arch
|
||||
},
|
||||
steps:
|
||||
[
|
||||
{
|
||||
name: "everything",
|
||||
image: image,
|
||||
environment: environment,
|
||||
commands:
|
||||
[
|
||||
'set -e',
|
||||
'uname -a',
|
||||
'echo $DRONE_STAGE_MACHINE',
|
||||
'wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -',
|
||||
] +
|
||||
(if sources != [] then [ ('apt-add-repository "' + source + '"') for source in sources ] else []) +
|
||||
(if packages != "" then [ 'apt-get update', 'apt-get -y install ' + packages ] else []) +
|
||||
[
|
||||
'export LIBRARY=' + library,
|
||||
'./.drone/drone.sh',
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
local macos_pipeline(name, environment, xcode_version = "12.2", osx_version = "catalina", arch = "amd64") =
|
||||
{
|
||||
name: name,
|
||||
kind: "pipeline",
|
||||
type: "exec",
|
||||
trigger: triggers,
|
||||
platform: {
|
||||
"os": "darwin",
|
||||
"arch": arch
|
||||
},
|
||||
node: {
|
||||
"os": osx_version
|
||||
},
|
||||
steps: [
|
||||
{
|
||||
name: "everything",
|
||||
environment: environment + { "DEVELOPER_DIR": "/Applications/Xcode-" + xcode_version + ".app/Contents/Developer" },
|
||||
commands:
|
||||
[
|
||||
'export LIBRARY=' + library,
|
||||
'./.drone/drone.sh',
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
local windows_pipeline(name, image, environment, arch = "amd64") =
|
||||
{
|
||||
name: name,
|
||||
kind: "pipeline",
|
||||
type: "docker",
|
||||
trigger: triggers,
|
||||
platform:
|
||||
{
|
||||
os: "windows",
|
||||
arch: arch
|
||||
},
|
||||
"steps":
|
||||
[
|
||||
{
|
||||
name: "everything",
|
||||
image: image,
|
||||
environment: environment,
|
||||
commands:
|
||||
[
|
||||
'cmd /C .drone\\\\drone.bat ' + library,
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
[
|
||||
linux_pipeline(
|
||||
"Linux 16.04 GCC 4.8 32/64",
|
||||
"cppalliance/droneubuntu1604:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-4.8', CXXSTD: '11', ADDRMD: '32,64' },
|
||||
"g++-4.8-multilib",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 16.04 GCC 4.9 32/64",
|
||||
"cppalliance/droneubuntu1604:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-4.9', CXXSTD: '11', ADDRMD: '32,64' },
|
||||
"g++-4.9-multilib",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 16.04 GCC 5* 32/64",
|
||||
"cppalliance/droneubuntu1604:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11,14', ADDRMD: '32,64' },
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 18.04 GCC 7* 32/64",
|
||||
"cppalliance/droneubuntu1804:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11,14,17', ADDRMD: '32,64' },
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 20.04 GCC 9* ARM64 UBSAN",
|
||||
"cppalliance/droneubuntu2004:multiarch",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11,14,17,2a' } + ubsan,
|
||||
arch="arm64",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 20.04 GCC 9* ARM64 ASAN",
|
||||
"cppalliance/droneubuntu2004:multiarch",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11,14,17,2a' } + asan,
|
||||
arch="arm64",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 20.04 GCC 9* S390x UBSAN",
|
||||
"cppalliance/droneubuntu2004:multiarch",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11,14,17,2a' } + ubsan,
|
||||
arch="s390x",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 22.04 GCC 12 32/64",
|
||||
"cppalliance/droneubuntu2204:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-12', CXXSTD: '11,14,17,20', ADDRMD: '32,64' },
|
||||
"g++-12-multilib",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 23.04 GCC 13 32/64",
|
||||
"cppalliance/droneubuntu2304:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-13', CXXSTD: '11,14,17,20,2b', ADDRMD: '32,64' },
|
||||
"g++-13-multilib",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 24.04 GCC 14 32 ASAN",
|
||||
"cppalliance/droneubuntu2404:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-14', CXXSTD: '11,14,17,20,2b', ADDRMD: '32' } + asan,
|
||||
"g++-14-multilib",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 24.04 GCC 14 64 ASAN",
|
||||
"cppalliance/droneubuntu2404:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-14', CXXSTD: '11,14,17,20,2b', ADDRMD: '64' } + asan,
|
||||
"g++-14-multilib",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 24.04 GCC 14 32 UBSAN",
|
||||
"cppalliance/droneubuntu2404:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-14', CXXSTD: '11,14,17,20,2b', ADDRMD: '32' } + ubsan,
|
||||
"g++-14-multilib",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 24.04 GCC 14 64 UBSAN",
|
||||
"cppalliance/droneubuntu2404:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-14', CXXSTD: '11,14,17,20,2b', ADDRMD: '64' } + ubsan,
|
||||
"g++-14-multilib",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 22.04 Clang 15",
|
||||
"cppalliance/droneubuntu2204:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-15', CXXSTD: '11,14,17,20,2b' },
|
||||
"clang-15",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 23.04 Clang 16",
|
||||
"cppalliance/droneubuntu2304:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-16', CXXSTD: '11,14,17,20,2b' },
|
||||
"clang-16",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 23.10 Clang 17 UBSAN",
|
||||
"cppalliance/droneubuntu2310:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-17', CXXSTD: '11,14,17,20,2b' } + ubsan,
|
||||
"clang-17",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 23.10 Clang 17 ASAN",
|
||||
"cppalliance/droneubuntu2310:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-17', CXXSTD: '11,14,17,20,2b' } + asan,
|
||||
"clang-17",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 24.04 Clang 18 UBSAN",
|
||||
"cppalliance/droneubuntu2404:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-18', CXXSTD: '11,14,17,20,2b' } + ubsan,
|
||||
"clang-18",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 24.04 Clang 18 ASAN",
|
||||
"cppalliance/droneubuntu2404:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-18', CXXSTD: '11,14,17,20,2b' } + asan,
|
||||
"clang-18",
|
||||
),
|
||||
|
||||
macos_pipeline(
|
||||
"MacOS 10.15 Xcode 12.2 UBSAN",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '11,14,1z' } + ubsan,
|
||||
),
|
||||
|
||||
macos_pipeline(
|
||||
"MacOS 10.15 Xcode 12.2 ASAN",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '11,14,1z' } + asan,
|
||||
),
|
||||
|
||||
macos_pipeline(
|
||||
"MacOS 12.4 Xcode 13.4.1 UBSAN",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '11,14,17,20,2b' } + ubsan,
|
||||
xcode_version = "13.4.1", osx_version = "monterey", arch = "arm64",
|
||||
),
|
||||
|
||||
macos_pipeline(
|
||||
"MacOS 12.4 Xcode 13.4.1 ASAN",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '11,14,17,20,2b' } + asan,
|
||||
xcode_version = "13.4.1", osx_version = "monterey", arch = "arm64",
|
||||
),
|
||||
|
||||
windows_pipeline(
|
||||
"Windows VS2015 msvc-14.0",
|
||||
"cppalliance/dronevs2015",
|
||||
{ TOOLSET: 'msvc-14.0', CXXSTD: '14,latest', B2_DONT_EMBED_MANIFEST: '1' },
|
||||
),
|
||||
|
||||
windows_pipeline(
|
||||
"Windows VS2017 msvc-14.1",
|
||||
"cppalliance/dronevs2017",
|
||||
{ TOOLSET: 'msvc-14.1', CXXSTD: '14,17,latest' },
|
||||
),
|
||||
|
||||
windows_pipeline(
|
||||
"Windows VS2019 msvc-14.2",
|
||||
"cppalliance/dronevs2019",
|
||||
{ TOOLSET: 'msvc-14.2', CXXSTD: '14,17,20,latest' },
|
||||
),
|
||||
|
||||
windows_pipeline(
|
||||
"Windows VS2022 msvc-14.3",
|
||||
"cppalliance/dronevs2022:1",
|
||||
{ TOOLSET: 'msvc-14.3', CXXSTD: '14,17,20,latest' },
|
||||
),
|
||||
]
|
||||
25
.drone/drone.bat
Normal file
25
.drone/drone.bat
Normal file
@@ -0,0 +1,25 @@
|
||||
@REM Copyright 2022 Peter Dimov
|
||||
@REM Distributed under the Boost Software License, Version 1.0.
|
||||
@REM https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
@ECHO ON
|
||||
|
||||
set LIBRARY=%1
|
||||
set DRONE_BUILD_DIR=%CD%
|
||||
|
||||
echo %DRONE_STAGE_MACHINE%
|
||||
|
||||
set BOOST_BRANCH=develop
|
||||
if "%DRONE_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 update --init tools/boostdep
|
||||
xcopy /s /e /q %DRONE_BUILD_DIR% libs\%LIBRARY%\
|
||||
python tools/boostdep/depinst/depinst.py %LIBRARY%
|
||||
cmd /c bootstrap
|
||||
b2 -d0 headers
|
||||
|
||||
if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
|
||||
if not "%ADDRMD%" == "" set ADDRMD=address-model=%ADDRMD%
|
||||
b2 -j3 libs/%LIBRARY%/test toolset=%TOOLSET% %CXXSTD% %ADDRMD% variant=debug,release embed-manifest-via=linker
|
||||
31
.drone/drone.sh
Executable file
31
.drone/drone.sh
Executable file
@@ -0,0 +1,31 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright 2022 Peter Dimov
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
set -ex
|
||||
export PATH=~/.local/bin:/usr/local/bin:$PATH
|
||||
|
||||
uname -a
|
||||
echo $DRONE_STAGE_MACHINE
|
||||
command -v lscpu && lscpu
|
||||
|
||||
DRONE_BUILD_DIR=$(pwd)
|
||||
|
||||
BOOST_BRANCH=develop
|
||||
if [ "$DRONE_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 update --init tools/boostdep
|
||||
cp -r $DRONE_BUILD_DIR/* libs/$LIBRARY
|
||||
python tools/boostdep/depinst/depinst.py $LIBRARY
|
||||
CXXFLAGS= ./bootstrap.sh
|
||||
./b2 -d0 headers
|
||||
|
||||
echo "using $TOOLSET : : $COMPILER ;" > ~/user-config.jam
|
||||
./b2 -j2 libs/$LIBRARY/test toolset=$TOOLSET cxxstd=$CXXSTD variant=debug,release \
|
||||
${ADDRMD:+address-model=$ADDRMD} ${CXXFLAGS:+cxxflags=$CXXFLAGS} ${LINKFLAGS:+linkflags=$LINKFLAGS} \
|
||||
${UBSAN:+undefined-sanitizer=norecover debug-symbols=on} ${ASAN:+address-sanitizer=norecover debug-symbols=on}
|
||||
99
.github/workflows/ci.yml
vendored
99
.github/workflows/ci.yml
vendored
@@ -19,18 +19,23 @@ jobs:
|
||||
include:
|
||||
- toolset: gcc-4.8
|
||||
cxxstd: "03,11"
|
||||
os: ubuntu-latest
|
||||
container: ubuntu:18.04
|
||||
os: ubuntu-latest
|
||||
install: g++-4.8
|
||||
- toolset: gcc-4.9
|
||||
cxxstd: "03,11"
|
||||
container: ubuntu:16.04
|
||||
os: ubuntu-latest
|
||||
install: g++-4.9
|
||||
- toolset: gcc-5
|
||||
cxxstd: "03,11,14,1z"
|
||||
os: ubuntu-latest
|
||||
container: ubuntu:18.04
|
||||
os: ubuntu-latest
|
||||
install: g++-5
|
||||
- toolset: gcc-6
|
||||
cxxstd: "03,11,14,1z"
|
||||
os: ubuntu-latest
|
||||
container: ubuntu:18.04
|
||||
os: ubuntu-latest
|
||||
install: g++-6
|
||||
- toolset: gcc-7
|
||||
cxxstd: "03,11,14,17"
|
||||
@@ -49,29 +54,38 @@ jobs:
|
||||
install: g++-10
|
||||
- toolset: gcc-11
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: ubuntu-20.04
|
||||
install: g++-11
|
||||
os: ubuntu-22.04
|
||||
- toolset: gcc-12
|
||||
cxxstd: "03,11,14,17,20,2b"
|
||||
os: ubuntu-22.04
|
||||
install: g++-12
|
||||
- toolset: gcc-13
|
||||
cxxstd: "03,11,14,17,20,2b"
|
||||
container: ubuntu:23.04
|
||||
os: ubuntu-latest
|
||||
install: g++-13
|
||||
- toolset: gcc-14
|
||||
cxxstd: "03,11,14,17,20,2b"
|
||||
container: ubuntu:24.04
|
||||
os: ubuntu-latest
|
||||
install: g++-14
|
||||
- toolset: clang
|
||||
compiler: clang++-3.9
|
||||
cxxstd: "03,11,14"
|
||||
os: ubuntu-latest
|
||||
container: ubuntu:18.04
|
||||
os: ubuntu-latest
|
||||
install: clang-3.9
|
||||
- toolset: clang
|
||||
compiler: clang++-4.0
|
||||
cxxstd: "03,11,14"
|
||||
os: ubuntu-latest
|
||||
container: ubuntu:18.04
|
||||
os: ubuntu-latest
|
||||
install: clang-4.0
|
||||
- toolset: clang
|
||||
compiler: clang++-5.0
|
||||
cxxstd: "03,11,14,1z"
|
||||
os: ubuntu-latest
|
||||
container: ubuntu:18.04
|
||||
os: ubuntu-latest
|
||||
install: clang-5.0
|
||||
- toolset: clang
|
||||
compiler: clang++-6.0
|
||||
@@ -111,24 +125,48 @@ jobs:
|
||||
- toolset: clang
|
||||
compiler: clang++-13
|
||||
cxxstd: "03,11,14,17,20,2b"
|
||||
os: ubuntu-22.04
|
||||
container: ubuntu:22.04
|
||||
os: ubuntu-latest
|
||||
install: clang-13
|
||||
- toolset: clang
|
||||
compiler: clang++-14
|
||||
cxxstd: "03,11,14,17,20,2b"
|
||||
os: ubuntu-22.04
|
||||
container: ubuntu:22.04
|
||||
os: ubuntu-latest
|
||||
install: clang-14
|
||||
- toolset: clang
|
||||
compiler: clang++-15
|
||||
cxxstd: "03,11,14,17,20,2b"
|
||||
os: ubuntu-22.04
|
||||
container: ubuntu:22.04
|
||||
os: ubuntu-latest
|
||||
install: clang-15
|
||||
- toolset: clang
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: macos-11
|
||||
compiler: clang++-16
|
||||
cxxstd: "03,11,14,17,20,2b"
|
||||
container: ubuntu:23.04
|
||||
os: ubuntu-latest
|
||||
install: clang-16
|
||||
- toolset: clang
|
||||
compiler: clang++-17
|
||||
cxxstd: "03,11,14,17,20,2b"
|
||||
container: ubuntu:23.10
|
||||
os: ubuntu-latest
|
||||
install: clang-17
|
||||
- toolset: clang
|
||||
compiler: clang++-18
|
||||
cxxstd: "03,11,14,17,20,2b"
|
||||
container: ubuntu:24.04
|
||||
os: ubuntu-latest
|
||||
install: clang-18
|
||||
- toolset: clang
|
||||
cxxstd: "03,11,14,17,20,2b"
|
||||
os: macos-12
|
||||
- toolset: clang
|
||||
cxxstd: "03,11,14,17,20,2b"
|
||||
os: macos-13
|
||||
- toolset: clang
|
||||
cxxstd: "03,11,14,17,20,2b"
|
||||
os: macos-14
|
||||
|
||||
runs-on: ${{matrix.os}}
|
||||
container: ${{matrix.container}}
|
||||
@@ -138,17 +176,23 @@ jobs:
|
||||
shell: bash
|
||||
|
||||
steps:
|
||||
- name: Enable Node 16
|
||||
run: |
|
||||
echo "ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION=true" >> $GITHUB_ENV
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Setup container environment
|
||||
if: matrix.container
|
||||
run: |
|
||||
apt-get update
|
||||
apt-get -y install sudo python git g++
|
||||
apt-get -y install sudo python3 git g++
|
||||
|
||||
- name: Install packages
|
||||
if: matrix.install
|
||||
run: sudo apt-get -y install ${{matrix.install}}
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get -y install ${{matrix.install}}
|
||||
|
||||
- name: Setup Boost
|
||||
run: |
|
||||
@@ -169,7 +213,7 @@ jobs:
|
||||
mkdir -p libs/$LIBRARY
|
||||
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
|
||||
git submodule update --init tools/boostdep
|
||||
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
|
||||
python3 tools/boostdep/depinst/depinst.py $LIBRARY
|
||||
./bootstrap.sh
|
||||
./b2 -d0 headers
|
||||
|
||||
@@ -212,7 +256,7 @@ jobs:
|
||||
runs-on: ${{matrix.os}}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Boost
|
||||
shell: cmd
|
||||
@@ -249,13 +293,14 @@ jobs:
|
||||
include:
|
||||
- os: ubuntu-20.04
|
||||
- os: ubuntu-22.04
|
||||
- os: macos-11
|
||||
- os: macos-12
|
||||
- os: macos-13
|
||||
- os: macos-14
|
||||
|
||||
runs-on: ${{matrix.os}}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install packages
|
||||
if: matrix.install
|
||||
@@ -297,13 +342,14 @@ jobs:
|
||||
include:
|
||||
- os: ubuntu-20.04
|
||||
- os: ubuntu-22.04
|
||||
- os: macos-11
|
||||
- os: macos-12
|
||||
- os: macos-13
|
||||
- os: macos-14
|
||||
|
||||
runs-on: ${{matrix.os}}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install packages
|
||||
if: matrix.install
|
||||
@@ -355,13 +401,14 @@ jobs:
|
||||
include:
|
||||
- os: ubuntu-20.04
|
||||
- os: ubuntu-22.04
|
||||
- os: macos-11
|
||||
- os: macos-12
|
||||
- os: macos-13
|
||||
- os: macos-14
|
||||
|
||||
runs-on: ${{matrix.os}}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install packages
|
||||
if: matrix.install
|
||||
@@ -415,7 +462,7 @@ jobs:
|
||||
runs-on: ${{matrix.os}}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Boost
|
||||
shell: cmd
|
||||
@@ -464,7 +511,7 @@ jobs:
|
||||
runs-on: ${{matrix.os}}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Boost
|
||||
shell: cmd
|
||||
@@ -531,7 +578,7 @@ jobs:
|
||||
runs-on: ${{matrix.os}}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Boost
|
||||
shell: cmd
|
||||
|
||||
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
/__build__
|
||||
/toolchain.cmake
|
||||
/compile_commands.json
|
||||
/.cache
|
||||
/.vscode
|
||||
@@ -15,6 +15,8 @@ target_include_directories(boost_compat INTERFACE include)
|
||||
target_link_libraries(boost_compat
|
||||
INTERFACE
|
||||
Boost::assert
|
||||
Boost::config
|
||||
Boost::throw_exception
|
||||
)
|
||||
|
||||
target_compile_features(boost_compat INTERFACE cxx_std_11)
|
||||
|
||||
22
build.jam
Normal file
22
build.jam
Normal file
@@ -0,0 +1,22 @@
|
||||
# Copyright 2024 René Ferdinand Rivera Morell
|
||||
# Copyright 2024 Peter Dimov
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
require-b2 5.2 ;
|
||||
|
||||
constant boost_dependencies :
|
||||
/boost/assert//boost_assert
|
||||
/boost/config//boost_config
|
||||
/boost/throw_exception//boost_throw_exception
|
||||
;
|
||||
|
||||
project /boost/compat ;
|
||||
|
||||
explicit
|
||||
[ alias boost_compat : : : : <include>include <library>$(boost_dependencies) ]
|
||||
[ alias all : boost_compat test ]
|
||||
;
|
||||
|
||||
call-if : boost-library compat
|
||||
;
|
||||
@@ -17,8 +17,7 @@ https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
include::compat/overview.adoc[]
|
||||
include::compat/changelog.adoc[]
|
||||
include::compat/latch.adoc[]
|
||||
include::compat/shared_lock.adoc[]
|
||||
include::compat/reference.adoc[]
|
||||
include::compat/copyright.adoc[]
|
||||
|
||||
:leveloffset: -1
|
||||
|
||||
58
doc/compat/bind_back.adoc
Normal file
58
doc/compat/bind_back.adoc
Normal file
@@ -0,0 +1,58 @@
|
||||
////
|
||||
Copyright 2024 Peter Dimov
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
https://www.boost.org/LICENSE_1_0.txt
|
||||
////
|
||||
|
||||
[#bind_back]
|
||||
# <boost/compat/bind_back.hpp>
|
||||
:idprefix: ref_bind_back_
|
||||
|
||||
## Description
|
||||
|
||||
The header `<boost/compat/bind_back.hpp>` implements the {cpp}20 function
|
||||
`std::bind_back`.
|
||||
|
||||
`bind_back` is a limited variant of `std::bind`. It only supports binding
|
||||
the last several parameters of a function object to specific argument values.
|
||||
|
||||
## Example
|
||||
|
||||
```
|
||||
struct X
|
||||
{
|
||||
void f(int a, int b) const noexcept;
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
auto fn = boost::compat::bind_back(&X::f, 1, 2);
|
||||
|
||||
X x;
|
||||
fn(x); // calls x.f(1, 2)
|
||||
}
|
||||
```
|
||||
|
||||
## Synopsis
|
||||
|
||||
```
|
||||
namespace boost
|
||||
{
|
||||
namespace compat
|
||||
{
|
||||
|
||||
template<class F, class... A> auto bind_back(F&& f, A&&... a);
|
||||
|
||||
} // namespace compat
|
||||
} // namespace boost
|
||||
```
|
||||
|
||||
## bind_back
|
||||
|
||||
```
|
||||
template<class F, class... A> auto bind_back( F&& f, A&&... a );
|
||||
```
|
||||
|
||||
[horizontal]
|
||||
Returns:;; A function object `fn` such that `fn(b...)` is equivalent to
|
||||
`invoke(f, b..., a...)`.
|
||||
58
doc/compat/bind_front.adoc
Normal file
58
doc/compat/bind_front.adoc
Normal file
@@ -0,0 +1,58 @@
|
||||
////
|
||||
Copyright 2024 Peter Dimov
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
https://www.boost.org/LICENSE_1_0.txt
|
||||
////
|
||||
|
||||
[#bind_front]
|
||||
# <boost/compat/bind_front.hpp>
|
||||
:idprefix: ref_bind_front_
|
||||
|
||||
## Description
|
||||
|
||||
The header `<boost/compat/bind_front.hpp>` implements the {cpp}20 function
|
||||
`std::bind_front`.
|
||||
|
||||
`bind_front` is a limited variant of `std::bind`. It only supports binding
|
||||
the first several parameters of a function object to specific argument values.
|
||||
|
||||
## Example
|
||||
|
||||
```
|
||||
struct X
|
||||
{
|
||||
void f(int a, int b) const noexcept;
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
X x;
|
||||
auto fn = boost::compat::bind_front(&X::f, &x);
|
||||
|
||||
fn(1, 2); // calls x.f(1, 2)
|
||||
}
|
||||
```
|
||||
|
||||
## Synopsis
|
||||
|
||||
```
|
||||
namespace boost
|
||||
{
|
||||
namespace compat
|
||||
{
|
||||
|
||||
template<class F, class... A> auto bind_front(F&& f, A&&... a);
|
||||
|
||||
} // namespace compat
|
||||
} // namespace boost
|
||||
```
|
||||
|
||||
## bind_front
|
||||
|
||||
```
|
||||
template<class F, class... A> auto bind_front(F&& f, A&&... a);
|
||||
```
|
||||
|
||||
[horizontal]
|
||||
Returns:;; A function object `fn` such that `fn(b...)` is equivalent to
|
||||
`invoke(f, a..., b...)`.
|
||||
@@ -8,6 +8,15 @@ https://www.boost.org/LICENSE_1_0.txt
|
||||
# Revision History
|
||||
:idprefix: changelog_
|
||||
|
||||
## Changes in 1.87.0
|
||||
|
||||
* Added `to_array.hpp` (contributed by Ruben Perez Hidalgo.)
|
||||
|
||||
## Changes in 1.86.0
|
||||
|
||||
* Added `bind_front.hpp`, `bind_back.hpp`, `invoke.hpp`, `mem_fn.hpp`, `integer_sequence.hpp` and `type_traits.hpp`.
|
||||
* Added `function_ref.hpp`.
|
||||
|
||||
## Changes in 1.83.0
|
||||
|
||||
* Added `latch.hpp`, an implementation of `std::latch` (contributed by Christian Mazakas.)
|
||||
|
||||
@@ -8,6 +8,6 @@ https://www.boost.org/LICENSE_1_0.txt
|
||||
# Copyright and License
|
||||
:idprefix:
|
||||
|
||||
This documentation is copyright 2023 Peter Dimov and contributors and is
|
||||
distributed under the
|
||||
This documentation is copyright 2023, 2024 Peter Dimov and
|
||||
contributors and is distributed under the
|
||||
http://www.boost.org/LICENSE_1_0.txt[Boost Software License, Version 1.0].
|
||||
|
||||
200
doc/compat/function_ref.adoc
Normal file
200
doc/compat/function_ref.adoc
Normal file
@@ -0,0 +1,200 @@
|
||||
////
|
||||
Copyright 2024 Christian Mazakas
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
https://www.boost.org/LICENSE_1_0.txt
|
||||
////
|
||||
|
||||
[#function_ref]
|
||||
# <boost/compat/function_ref.hpp>
|
||||
:idprefix: ref_function_ref_
|
||||
|
||||
## Description
|
||||
|
||||
The header `<boost/compat/function_ref.hpp>` implements the {cpp}26 class
|
||||
`std::function_ref`.
|
||||
|
||||
`function_ref` is a lightweight polymorphic function wrapper that only stores a pointer to the supplied https://en.cppreference.com/w/cpp/named_req/Callable[Callable] object and a pointer to an unspecified function, meaning it does not participate in ownership of the Callable and does not allocate. All specializations of `function_ref` satisfy https://en.cppreference.com/w/cpp/named_req/TriviallyCopyable[TriviallyCopyable].
|
||||
|
||||
`function_ref` supports every combination of `const` and `noexcept` and is useful for writing higher-order functions as
|
||||
it can avoid a template parameter or an allocation (as `std::function` is known for).
|
||||
|
||||
## Example
|
||||
|
||||
```cpp
|
||||
int add(int x, int y) noexcept { return x * 10 + y; }
|
||||
|
||||
auto add2 = [](int x, int y) { return x * 100 + y; };
|
||||
|
||||
std::vector<boost::compat::function_ref<int(int, int)>> fns;
|
||||
fns.push_back({add});
|
||||
fns.push_back({add2});
|
||||
|
||||
for (auto fn : fns) {
|
||||
std::cout << fn(1, 2) << std::endl;
|
||||
}
|
||||
```
|
||||
|
||||
## Synopsis
|
||||
|
||||
```cpp
|
||||
namespace boost
|
||||
{
|
||||
namespace compat
|
||||
{
|
||||
|
||||
template <class... S>
|
||||
struct function_ref;
|
||||
|
||||
// cv is either `const` or empty
|
||||
// noex is either `true` or `false`
|
||||
template<class R, class... ArgTypes>
|
||||
class function_ref<R(ArgTypes...) cv noexcept(noex)> {
|
||||
public:
|
||||
template<class F> function_ref(F*) noexcept;
|
||||
template<class F> function_ref(F&&) noexcept;
|
||||
template<auto f> function_ref(nontype_t<f>) noexcept;
|
||||
template<auto f, class U> function_ref(nontype_t<f>, U&&) noexcept;
|
||||
template<auto f, class T> function_ref(nontype_t<f>, cv T*) noexcept;
|
||||
|
||||
function_ref(const function_ref&) noexcept = default;
|
||||
function_ref& operator=(const function_ref&) noexcept = default;
|
||||
template<class T> function_ref& operator=(T) = delete;
|
||||
|
||||
R operator()(ArgTypes...) const noexcept(noex);
|
||||
};
|
||||
|
||||
} // namespace compat
|
||||
} // namespace boost
|
||||
```
|
||||
|
||||
## Constructors
|
||||
|
||||
### Function Pointer Constructor
|
||||
|
||||
```cpp
|
||||
template<class F> function_ref(F* fn) noexcept;
|
||||
```
|
||||
|
||||
[horizontal]
|
||||
Preconditions:: `fn` != `nullptr`.
|
||||
Effects::
|
||||
Constructs a `function_ref` which uses the supplied function pointer as its Callable. +
|
||||
+
|
||||
Calling the `function_ref` is expression-equivalent to `invoke_r<R>(f, call-args...)`.
|
||||
|
||||
|
||||
### Object Constructor
|
||||
|
||||
```cpp
|
||||
template<class F> function_ref(F&& fn) noexcept;
|
||||
```
|
||||
|
||||
[horizontal]
|
||||
Effects:;; Constructs a `function_ref` that stores the address of the supplied Callable object `fn`. This overload only
|
||||
participates in resolution when `fn` is not a pointer-to-member or pointer-to-member-function. +
|
||||
+
|
||||
Calling the `function_ref` is expression-equivalent to: + `invoke_r<R>(static_cast<cv T&>(f), call-args...)`.
|
||||
|
||||
### Pointer to Member Function Constructor
|
||||
|
||||
```cpp
|
||||
template<auto f> function_ref(nontype_t<f>) noexcept;
|
||||
```
|
||||
|
||||
[horizontal]
|
||||
Effects:;; Constructs a `function_ref` using the supplied pointer to member function. This overload only participates
|
||||
in resolution when `f` is a pointer to member or pointer to member function. +
|
||||
+
|
||||
Calling the `function_ref` is express-equivalent to: `invoke_r<R>(f, class-args)`.
|
||||
Example:;;
|
||||
+
|
||||
--
|
||||
```cpp
|
||||
struct point { int x = 1, y = 2; };
|
||||
|
||||
point p;
|
||||
compat::function_ref<int(point const&)> f(compat::nontype_t<&point::x>{});
|
||||
|
||||
BOOST_TEST_EQ(f(p), 1);
|
||||
```
|
||||
--
|
||||
|
||||
### Bound Object Constructor
|
||||
|
||||
```cpp
|
||||
template<auto f, class U> function_ref(nontype_t<f>, U&&) noexcept;
|
||||
```
|
||||
|
||||
[horizontal]
|
||||
Effects:;; Constructs a `function_ref` using the supplied pointer to member or pointer to member function and a reference
|
||||
to an object to bind it to. +
|
||||
+
|
||||
This overload only participates in resolution if `is_rvalue_reference_v<U&&>` is false.
|
||||
Example:;;
|
||||
+
|
||||
--
|
||||
```cpp
|
||||
struct point { int x = 1, y = 2; };
|
||||
|
||||
point p;
|
||||
compat::function_ref<int()> f(compat::nontype_t<&point::x>{}, p);
|
||||
|
||||
BOOST_TEST_EQ(f(), 1);
|
||||
```
|
||||
--
|
||||
|
||||
### Bound Pointer Constructor
|
||||
|
||||
```cpp
|
||||
template<auto f, class T> function_ref(nontype_t<f>, cv T*) noexcept;
|
||||
```
|
||||
|
||||
[horizontal]
|
||||
Effects:;; Constructs a `function_ref` using the supplied pointer to member or pointer to member function and a pointer
|
||||
to an object.
|
||||
Example:;;
|
||||
+
|
||||
--
|
||||
```cpp
|
||||
struct point { int x = 1, y = 2; };
|
||||
|
||||
point p;
|
||||
compat::function_ref<int()> f(compat::nontype_t<&point::x>{}, &p);
|
||||
|
||||
BOOST_TEST_EQ(f(), 1);
|
||||
```
|
||||
--
|
||||
|
||||
### Copy Constructor
|
||||
|
||||
```cpp
|
||||
function_ref(const function_ref&) noexcept = default;
|
||||
```
|
||||
|
||||
[horizontal]
|
||||
Effects:;; `function_ref` is a TriviallyCopyable type.
|
||||
|
||||
## Member Functions
|
||||
|
||||
### call operator
|
||||
|
||||
```cpp
|
||||
R operator()(ArgTypes...) const noexcept(noex);
|
||||
```
|
||||
|
||||
[horizontal]
|
||||
Effects:;; Invokes the underlying Callable object by forwarding the supplied arguments.
|
||||
|
||||
## Assignment
|
||||
|
||||
### Copy Assignment
|
||||
|
||||
```cpp
|
||||
function_ref& operator=(const function_ref&) noexcept = default;
|
||||
template<class T> function_ref& operator=(T) = delete;
|
||||
```
|
||||
|
||||
[horizontal]
|
||||
Effects:;; `operator=(T)` participates in overload resolution if:
|
||||
* `T` is not the same as `function_ref`
|
||||
* `is_pointer_v<T>` is `false`.
|
||||
69
doc/compat/integer_sequence.adoc
Normal file
69
doc/compat/integer_sequence.adoc
Normal file
@@ -0,0 +1,69 @@
|
||||
////
|
||||
Copyright 2024 Peter Dimov
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
https://www.boost.org/LICENSE_1_0.txt
|
||||
////
|
||||
|
||||
[#integer_sequence]
|
||||
# <boost/compat/integer_sequence.hpp>
|
||||
:idprefix: ref_integer_sequence_
|
||||
|
||||
## Description
|
||||
|
||||
The header `<boost/compat/integer_sequence.hpp>` implements the {cpp}14 utilities
|
||||
`std::integer_sequence`, `std::index_sequence`, `std::make_integer_sequence`,
|
||||
`std::make_index_sequence`, and `std::index_sequence_for`.
|
||||
|
||||
## Synopsis
|
||||
|
||||
```
|
||||
namespace boost
|
||||
{
|
||||
namespace compat
|
||||
{
|
||||
|
||||
template<class T, T... I> struct integer_sequence;
|
||||
|
||||
template<class T, T N> using make_integer_sequence = /*...*/;
|
||||
|
||||
template<std::size_t... I> using index_sequence = /*...*/;
|
||||
|
||||
template<std::size_t N> using make_index_sequence = /*...*/;
|
||||
|
||||
template<class... T> using index_sequence_for = /*...*/;
|
||||
|
||||
} // namespace compat
|
||||
} // namespace boost
|
||||
```
|
||||
|
||||
## integer_sequence
|
||||
|
||||
```
|
||||
template<class T, T... I> struct integer_sequence {};
|
||||
```
|
||||
|
||||
## make_integer_sequence
|
||||
|
||||
```
|
||||
template<class T, T N> using make_integer_sequence = /*...*/;
|
||||
```
|
||||
|
||||
`make_integer_sequence<T, N>` is an alias for `integer_sequence<T, 0, 1, 2, ..., N-1>`.
|
||||
|
||||
## index_sequence
|
||||
|
||||
```
|
||||
template<std::size_t... I> using index_sequence = integer_sequence<std::size_t, I...>;
|
||||
```
|
||||
|
||||
## make_index_sequence
|
||||
|
||||
```
|
||||
template<std::size_t N> using make_index_sequence = make_integer_sequence<std::size_t, N>;
|
||||
```
|
||||
|
||||
## index_sequence_for
|
||||
|
||||
```
|
||||
template<class... T> using index_sequence_for = make_integer_sequence<std::size_t, sizeof...(T)>;
|
||||
```
|
||||
130
doc/compat/invoke.adoc
Normal file
130
doc/compat/invoke.adoc
Normal file
@@ -0,0 +1,130 @@
|
||||
////
|
||||
Copyright 2024 Peter Dimov
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
https://www.boost.org/LICENSE_1_0.txt
|
||||
////
|
||||
|
||||
[#invoke]
|
||||
# <boost/compat/invoke.hpp>
|
||||
:idprefix: ref_invoke_
|
||||
|
||||
## Description
|
||||
|
||||
The header `<boost/compat/invoke.hpp>` implements the {cpp}17 function
|
||||
`std::invoke`, the {cpp}23 function `std::invoke_r`, and the associated
|
||||
utilities `invoke_result_t`, `is_invocable`, `is_invocable_r`,
|
||||
`is_nothrow_invocable`, and `is_nothrow_invocable_r`.
|
||||
|
||||
`invoke(f, a...)` generally returns `f(a...)`, but when `f` is a pointer to
|
||||
member, it invokes it as if by returning `mem_fn(f)(a...)`. This allows
|
||||
functions, function objects, and pointers to members to be treated uniformly
|
||||
by components such as `bind_front`.
|
||||
|
||||
`invoke_r<R>(f, a...)` returns `invoke(f, a...)`, converted to `R`.
|
||||
|
||||
## Example
|
||||
|
||||
```
|
||||
struct X
|
||||
{
|
||||
void f(int a, int b) const noexcept;
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
X x;
|
||||
boost::compat::invoke(&X::f, x, 1, 2); // calls x.f(1, 2)
|
||||
}
|
||||
```
|
||||
|
||||
## Synopsis
|
||||
|
||||
```
|
||||
namespace boost
|
||||
{
|
||||
namespace compat
|
||||
{
|
||||
|
||||
template<class F, class... A> auto invoke(F&& f, A&&... a);
|
||||
|
||||
template<class F, class... A> using invoke_result_t = /*...*/;
|
||||
|
||||
template<class F, class... A> struct is_invocable;
|
||||
|
||||
template<class F, class... A> struct is_nothrow_invocable;
|
||||
|
||||
template<class R, class F, class... A> R invoke_r(F&& f, A&&... a);
|
||||
|
||||
template<class R, class F, class... A> struct is_invocable_r;
|
||||
|
||||
template<class R, class F, class... A> struct is_nothrow_invocable_r;
|
||||
|
||||
} // namespace compat
|
||||
} // namespace boost
|
||||
```
|
||||
|
||||
## invoke
|
||||
|
||||
```
|
||||
template<class F, class... A> auto invoke(F&& f, A&&... a) noexcept(/*...*/) -> /*...*/;
|
||||
```
|
||||
|
||||
[horizontal]
|
||||
Returns:;;
|
||||
* `std::forward<F>(f)(std::forward<A>(a)...)`, when `f` is not a pointer to member;
|
||||
* `mem_fn(f)(std::forward<A>(a)...)`, otherwise.
|
||||
Constraints:;; the return expression must be valid.
|
||||
Remarks:;; The return type is `decltype(r)`, and the `noexcept` clause is `noexcept(noexcept(r))`, where `r` is the return expression.
|
||||
|
||||
## invoke_result_t
|
||||
|
||||
```
|
||||
template<class F, class... A> using invoke_result_t =
|
||||
decltype( invoke(std::declval<F>(), std::declval<A>()...) );
|
||||
```
|
||||
|
||||
## is_invocable
|
||||
|
||||
```
|
||||
template<class F, class... A> struct is_invocable: public /*...*/;
|
||||
```
|
||||
|
||||
The base class of `is_invocable<F, A...>` is `std::true_type` when `invoke(std::declval<F>(), std::declval<A>()...)` is a valid expression, `std::false_type` otherwise.
|
||||
|
||||
## is_nothrow_invocable
|
||||
|
||||
```
|
||||
template<class F, class... A> struct is_nothrow_invocable: public /*...*/;
|
||||
```
|
||||
|
||||
The base class of `is_nothrow_invocable<F, A...>` is `std::false_type` when `is_invocable<F, A...>::value` is `false`, `std::integral_constant<bool, noexcept(invoke(std::declval<F>(), std::declval<A>()...))>` otherwise.
|
||||
|
||||
## invoke_r
|
||||
|
||||
```
|
||||
template<class R, class F, class... A> R invoke_r(F&& f, A&&... a) noexcept(/*...*/);
|
||||
```
|
||||
|
||||
[horizontal]
|
||||
Returns:;;
|
||||
* `static_cast<R>(invoke(std::forward<F>(f), std::forward<A>(a)...))`, when `R` is (possibly cv-qualified) `void`;
|
||||
* `invoke(std::forward<F>(f), std::forward<A>(a)...)`, implicitly converted to `R`, otherwise.
|
||||
Constraints:;; `is_invocable<F, A...>::value` must be `true` and, if `R` is not cv `void`, `std::is_convertible<invoke_result_t<F, A...>, R>::value` must be `true`.
|
||||
Remarks:;; The `noexcept` clause is `noexcept(noexcept(static_cast<R>(invoke(std::forward<F>(f), std::forward<A>(a)...))))`.
|
||||
|
||||
## is_invocable_r
|
||||
|
||||
```
|
||||
template<class R, class F, class... A> struct is_invocable: public /*...*/;
|
||||
```
|
||||
|
||||
The base class of `is_invocable_r<R, F, A...>` is `std::true_type` when `invoke_r<R>(std::declval<F>(), std::declval<A>()...)` is a valid expression, `std::false_type` otherwise.
|
||||
|
||||
## is_nothrow_invocable_r
|
||||
|
||||
```
|
||||
template<class R, class F, class... A> struct is_nothrow_invocable: public /*...*/;
|
||||
```
|
||||
|
||||
The base class of `is_nothrow_invocable<R, F, A...>` is `std::false_type` when `is_invocable_r<R, F, A...>::value` is `false`, `std::integral_constant<bool, noexcept(invoke_r<R>(std::declval<F>(), std::declval<A>()...))>` otherwise.
|
||||
|
||||
@@ -6,7 +6,7 @@ https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
[#latch]
|
||||
# <boost/compat/latch.hpp>
|
||||
:idprefix: latch_
|
||||
:idprefix: ref_latch_
|
||||
|
||||
## Description
|
||||
|
||||
|
||||
67
doc/compat/mem_fn.adoc
Normal file
67
doc/compat/mem_fn.adoc
Normal file
@@ -0,0 +1,67 @@
|
||||
////
|
||||
Copyright 2024 Peter Dimov
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
https://www.boost.org/LICENSE_1_0.txt
|
||||
////
|
||||
|
||||
[#mem_fn]
|
||||
# <boost/compat/mem_fn.hpp>
|
||||
:idprefix: ref_mem_fn_
|
||||
|
||||
## Description
|
||||
|
||||
The header `<boost/compat/mem_fn.hpp>` implements the {cpp}11 function
|
||||
`std::mem_fn`.
|
||||
|
||||
`mem_fn(pm)`, where `pm` is a pointer to member, returns a function object
|
||||
that can be used to invoke the member function, or obtain a reference to the
|
||||
data member, using a function call syntax.
|
||||
|
||||
Even though `std::mem_fn` is {cpp}11, later standards place stricter
|
||||
requirements on the returned function object (it needs to be SFINAE friendly
|
||||
and propagate `noexcept` correctly.) `boost::compat::mem_fn` implements
|
||||
these stricter requirements.
|
||||
|
||||
## Example
|
||||
|
||||
```
|
||||
struct X
|
||||
{
|
||||
void f(int a, int b) const noexcept;
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
auto fn = boost::compat::mem_fn(&X::f);
|
||||
|
||||
X x;
|
||||
fn(x, 1, 2); // calls x.f(1, 2)
|
||||
}
|
||||
```
|
||||
|
||||
## Synopsis
|
||||
|
||||
```
|
||||
namespace boost
|
||||
{
|
||||
namespace compat
|
||||
{
|
||||
|
||||
template<class M, class T> auto mem_fn(M T::* pm) noexcept;
|
||||
|
||||
} // namespace compat
|
||||
} // namespace boost
|
||||
```
|
||||
|
||||
## mem_fn
|
||||
|
||||
```
|
||||
template<class M, class T> auto mem_fn(M T::* pm) noexcept;
|
||||
```
|
||||
|
||||
[horizontal]
|
||||
Returns:;; A function object `fn` such that:
|
||||
* `fn(x, a...)` is equivalent to `(x.*pm)(a...)`, when `M` is a function type and the type of `X` is `T` or derived from `T`;
|
||||
* `fn(x, a...)` is equivalent to `((*x).*pm)(a...)`, when `M` is a function type and the type of `X` is not `T` or derived from `T`;
|
||||
* `fn(x)` is equivalent to `x.*pm`, when `M` is an object type and the type of `X` is `T` or derived from `T`;
|
||||
* `fn(x)` is equivalent to `(*x).*pm`, when `M` is an object type and the type of `X` is not `T` or derived from `T`.
|
||||
16
doc/compat/reference.adoc
Normal file
16
doc/compat/reference.adoc
Normal file
@@ -0,0 +1,16 @@
|
||||
////
|
||||
Copyright 2024 Peter Dimov
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
https://www.boost.org/LICENSE_1_0.txt
|
||||
////
|
||||
|
||||
include::bind_back.adoc[]
|
||||
include::bind_front.adoc[]
|
||||
include::function_ref.adoc[]
|
||||
include::integer_sequence.adoc[]
|
||||
include::invoke.adoc[]
|
||||
include::latch.adoc[]
|
||||
include::mem_fn.adoc[]
|
||||
include::shared_lock.adoc[]
|
||||
include::to_array.adoc[]
|
||||
include::type_traits.adoc[]
|
||||
@@ -6,7 +6,7 @@ https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
[#shared_lock]
|
||||
# <boost/compat/shared_lock.hpp>
|
||||
:idprefix: shared_lock_
|
||||
:idprefix: ref_shared_lock_
|
||||
|
||||
## Description
|
||||
|
||||
@@ -129,7 +129,7 @@ shared_lock( mutex_type& m, std::adopt_lock_t );
|
||||
[horizontal]
|
||||
Preconditions:;; `m` must be held by a previous call to `m.lock_shared()` or a
|
||||
successful call to `m.try_lock_shared()`.
|
||||
PostConditions:;; `mutex() == std::addressof(m)` and `owns_lock() == true`.
|
||||
Postconditions:;; `mutex() == std::addressof(m)` and `owns_lock() == true`.
|
||||
|
||||
### Copy Constructor
|
||||
|
||||
|
||||
72
doc/compat/to_array.adoc
Normal file
72
doc/compat/to_array.adoc
Normal file
@@ -0,0 +1,72 @@
|
||||
////
|
||||
Copyright 2024 Ruben Perez Hidalgo
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
https://www.boost.org/LICENSE_1_0.txt
|
||||
////
|
||||
|
||||
[#to_array]
|
||||
# <boost/compat/to_array.hpp>
|
||||
:idprefix: ref_to_array_
|
||||
|
||||
## Description
|
||||
|
||||
The header `<boost/compat/to_array.hpp>` implements, in a portable way, the C++20
|
||||
`std::to_array` function, present in the `<array>` header.
|
||||
|
||||
`to_array` creates a `std::array` from a single-dimensional C array,
|
||||
performing an element-wise copy or move.
|
||||
|
||||
## Example
|
||||
|
||||
```cpp
|
||||
int input [] = {1, 2, 3};
|
||||
std::array<int, 3> output = boost::compat::to_array(input);
|
||||
assert((
|
||||
output == std::array<int, 3>{{1, 2, 3}}
|
||||
));
|
||||
```
|
||||
|
||||
## Synopsis
|
||||
|
||||
```cpp
|
||||
namespace boost
|
||||
{
|
||||
namespace compat
|
||||
{
|
||||
|
||||
template <class T, std::size_t N>
|
||||
constexpr std::array<remove_cv_t<T>, N> to_array(T (&a)[N]);
|
||||
|
||||
template <class T, std::size_t N>
|
||||
constexpr std::array<remove_cv_t<T>, N> to_array(T (&&a)[N]);
|
||||
|
||||
} // namespace compat
|
||||
} // namespace boost
|
||||
```
|
||||
|
||||
## to_array
|
||||
|
||||
```cpp
|
||||
template <class T, std::size_t N>
|
||||
constexpr std::array<remove_cv_t<T>, N> to_array(T (&&a)[N]);
|
||||
```
|
||||
|
||||
[horizontal]
|
||||
Effects:;; Creates an array of `N` elements by copying elements in `a`.
|
||||
For every `i` in `0, ..., N-1`, copy-initializes the i-th element
|
||||
in the output array from `a[i]`.
|
||||
Type requirements:;; `std::is_constructible_v<remove_cv_t<T>, T&> && !std::is_array_v<T>`.
|
||||
Otherwise, the overload is ill-formed.
|
||||
|
||||
|
||||
```cpp
|
||||
template <class T, std::size_t N>
|
||||
constexpr std::array<remove_cvref_t<T>, N> to_array(T (&a)[N]);
|
||||
```
|
||||
|
||||
[horizontal]
|
||||
Effects:;; Creates an array of `N` elements by moving elements in `a`.
|
||||
For every `i` in `0, ..., N-1`, move-initializes the i-th element
|
||||
in the output array from `std::move(a[i])`.
|
||||
Type requirements:;; `std::is_constructible_v<remove_cv_t<T>, T&&> && !std::is_array_v<T>`.
|
||||
Otherwise, the overload is ill-formed.
|
||||
45
doc/compat/type_traits.adoc
Normal file
45
doc/compat/type_traits.adoc
Normal file
@@ -0,0 +1,45 @@
|
||||
////
|
||||
Copyright 2024 Peter Dimov
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
https://www.boost.org/LICENSE_1_0.txt
|
||||
////
|
||||
|
||||
[#type_traits]
|
||||
# <boost/compat/type_traits.hpp>
|
||||
:idprefix: ref_type_traits_
|
||||
|
||||
## Description
|
||||
|
||||
The header `<boost/compat/type_traits.hpp>` implements some of the
|
||||
post-{cpp}11 additions to the standard header `<type_traits>`.
|
||||
|
||||
## Synopsis
|
||||
|
||||
```
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace compat
|
||||
{
|
||||
|
||||
template<class T> using remove_const_t = typename std::remove_const<T>::type;
|
||||
|
||||
template<class T> using remove_cv_t = typename std::remove_cv<T>::type;
|
||||
|
||||
template<class T> using remove_reference_t = typename std::remove_reference<T>::type;
|
||||
|
||||
template<class T> using remove_cvref_t = remove_cv_t<remove_reference_t<T>>;
|
||||
|
||||
template<class T> using decay_t = typename std::decay<T>::type;
|
||||
|
||||
template<bool B, class T = void> using enable_if_t = typename std::enable_if<B, T>::type;
|
||||
|
||||
template<bool B, class T, class F> using conditional_t = typename std::conditional<B, T, F>::type;
|
||||
|
||||
template<class... T> using void_t = void;
|
||||
|
||||
|
||||
} // namespace compat
|
||||
} // namespace boost
|
||||
```
|
||||
72
include/boost/compat/bind_back.hpp
Normal file
72
include/boost/compat/bind_back.hpp
Normal file
@@ -0,0 +1,72 @@
|
||||
#ifndef BOOST_COMPAT_BIND_BACK_HPP_INCLUDED
|
||||
#define BOOST_COMPAT_BIND_BACK_HPP_INCLUDED
|
||||
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/compat/invoke.hpp>
|
||||
#include <boost/compat/type_traits.hpp>
|
||||
#include <boost/compat/integer_sequence.hpp>
|
||||
#include <boost/compat/detail/returns.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/config/workaround.hpp>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
namespace boost {
|
||||
namespace compat {
|
||||
|
||||
namespace detail {
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1910)
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4100) // 'a': unreferenced formal parameter
|
||||
#endif
|
||||
|
||||
template<class F, class A, class... B, std::size_t... I>
|
||||
static constexpr auto invoke_bind_back_( F&& f, A&& a, index_sequence<I...>, B&&... b )
|
||||
BOOST_COMPAT_RETURNS( compat::invoke( std::forward<F>(f), std::forward<B>(b)..., std::get<I>( std::forward<A>(a) )... ) )
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1910)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
template<class F, class... A> class bind_back_
|
||||
{
|
||||
private:
|
||||
|
||||
F f_;
|
||||
std::tuple<A...> a_;
|
||||
|
||||
public:
|
||||
|
||||
template<class F2, class... A2>
|
||||
constexpr bind_back_( F2&& f2, A2&&... a2 ): f_( std::forward<F2>(f2) ), a_( std::forward<A2>(a2)... ) {}
|
||||
|
||||
public:
|
||||
|
||||
template<class... B> BOOST_CXX14_CONSTEXPR auto operator()( B&&... b ) &
|
||||
BOOST_COMPAT_RETURNS( detail::invoke_bind_back_( f_, a_, make_index_sequence<sizeof...(A)>(), std::forward<B>(b)... ) )
|
||||
|
||||
template<class... B> constexpr auto operator()( B&&... b ) const &
|
||||
BOOST_COMPAT_RETURNS( detail::invoke_bind_back_( f_, a_, make_index_sequence<sizeof...(A)>(), std::forward<B>(b)... ) )
|
||||
|
||||
template<class... B> BOOST_CXX14_CONSTEXPR auto operator()( B&&... b ) &&
|
||||
BOOST_COMPAT_RETURNS( detail::invoke_bind_back_( std::move(f_), std::move(a_), make_index_sequence<sizeof...(A)>(), std::forward<B>(b)... ) )
|
||||
|
||||
template<class... B> constexpr auto operator()( B&&... b ) const &&
|
||||
BOOST_COMPAT_RETURNS( detail::invoke_bind_back_( std::move(f_), std::move(a_), make_index_sequence<sizeof...(A)>(), std::forward<B>(b)... ) )
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class F, class... A> constexpr auto bind_back( F&& f, A&&... a ) -> detail::bind_back_< decay_t<F>, decay_t<A>... >
|
||||
{
|
||||
return { std::forward<F>(f), std::forward<A>(a)... };
|
||||
}
|
||||
|
||||
} // namespace compat
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_COMPAT_BIND_BACK_HPP_INCLUDED
|
||||
72
include/boost/compat/bind_front.hpp
Normal file
72
include/boost/compat/bind_front.hpp
Normal file
@@ -0,0 +1,72 @@
|
||||
#ifndef BOOST_COMPAT_BIND_FRONT_HPP_INCLUDED
|
||||
#define BOOST_COMPAT_BIND_FRONT_HPP_INCLUDED
|
||||
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/compat/invoke.hpp>
|
||||
#include <boost/compat/type_traits.hpp>
|
||||
#include <boost/compat/integer_sequence.hpp>
|
||||
#include <boost/compat/detail/returns.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/config/workaround.hpp>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
namespace boost {
|
||||
namespace compat {
|
||||
|
||||
namespace detail {
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1910)
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4100) // 'a': unreferenced formal parameter
|
||||
#endif
|
||||
|
||||
template<class F, class A, class... B, std::size_t... I>
|
||||
static constexpr auto invoke_bind_front_( F&& f, A&& a, index_sequence<I...>, B&&... b )
|
||||
BOOST_COMPAT_RETURNS( compat::invoke( std::forward<F>(f), std::get<I>( std::forward<A>(a) )..., std::forward<B>(b)... ) )
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1910)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
template<class F, class... A> class bind_front_
|
||||
{
|
||||
private:
|
||||
|
||||
F f_;
|
||||
std::tuple<A...> a_;
|
||||
|
||||
public:
|
||||
|
||||
template<class F2, class... A2>
|
||||
constexpr bind_front_( F2&& f2, A2&&... a2 ): f_( std::forward<F2>(f2) ), a_( std::forward<A2>(a2)... ) {}
|
||||
|
||||
public:
|
||||
|
||||
template<class... B> BOOST_CXX14_CONSTEXPR auto operator()( B&&... b ) &
|
||||
BOOST_COMPAT_RETURNS( detail::invoke_bind_front_( f_, a_, make_index_sequence<sizeof...(A)>(), std::forward<B>(b)... ) )
|
||||
|
||||
template<class... B> constexpr auto operator()( B&&... b ) const &
|
||||
BOOST_COMPAT_RETURNS( detail::invoke_bind_front_( f_, a_, make_index_sequence<sizeof...(A)>(), std::forward<B>(b)... ) )
|
||||
|
||||
template<class... B> BOOST_CXX14_CONSTEXPR auto operator()( B&&... b ) &&
|
||||
BOOST_COMPAT_RETURNS( detail::invoke_bind_front_( std::move(f_), std::move(a_), make_index_sequence<sizeof...(A)>(), std::forward<B>(b)... ) )
|
||||
|
||||
template<class... B> constexpr auto operator()( B&&... b ) const &&
|
||||
BOOST_COMPAT_RETURNS( detail::invoke_bind_front_( std::move(f_), std::move(a_), make_index_sequence<sizeof...(A)>(), std::forward<B>(b)... ) )
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class F, class... A> constexpr auto bind_front( F&& f, A&&... a ) -> detail::bind_front_< decay_t<F>, decay_t<A>... >
|
||||
{
|
||||
return { std::forward<F>(f), std::forward<A>(a)... };
|
||||
}
|
||||
|
||||
} // namespace compat
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_COMPAT_BIND_FRONT_HPP_INCLUDED
|
||||
10
include/boost/compat/detail/returns.hpp
Normal file
10
include/boost/compat/detail/returns.hpp
Normal file
@@ -0,0 +1,10 @@
|
||||
#ifndef BOOST_COMPAT_DETAIL_RETURNS_HPP_INCLUDED
|
||||
#define BOOST_COMPAT_DETAIL_RETURNS_HPP_INCLUDED
|
||||
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#define BOOST_COMPAT_RETURNS(...) noexcept(noexcept(__VA_ARGS__)) -> decltype(__VA_ARGS__) { return __VA_ARGS__; }
|
||||
|
||||
#endif // BOOST_COMPAT_DETAIL_RETURNS_HPP_INCLUDED
|
||||
314
include/boost/compat/function_ref.hpp
Normal file
314
include/boost/compat/function_ref.hpp
Normal file
@@ -0,0 +1,314 @@
|
||||
#ifndef BOOST_COMPAT_FUNCTION_REF_HPP_INCLUDED
|
||||
#define BOOST_COMPAT_FUNCTION_REF_HPP_INCLUDED
|
||||
|
||||
// Copyright 2024 Christian Mazakas.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/compat/invoke.hpp>
|
||||
#include <boost/compat/type_traits.hpp>
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#if defined(__cpp_nontype_template_parameter_auto) && __cpp_nontype_template_parameter_auto >= 201606L
|
||||
#define BOOST_COMPAT_HAS_AUTO_NTTP
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace compat {
|
||||
|
||||
template <class... S>
|
||||
struct function_ref;
|
||||
|
||||
#if defined(BOOST_COMPAT_HAS_AUTO_NTTP)
|
||||
|
||||
template <auto V>
|
||||
struct nontype_t {
|
||||
explicit nontype_t() = default;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <bool NoEx>
|
||||
union thunk_storage {
|
||||
void* pobj_;
|
||||
void (*pfn_)() noexcept(NoEx);
|
||||
};
|
||||
|
||||
template <bool NoEx, class Fp, class R, class... Args>
|
||||
struct invoke_function_holder {
|
||||
static R invoke_function(thunk_storage<NoEx> s, Args&&... args) noexcept(NoEx) {
|
||||
auto f = reinterpret_cast<Fp>(s.pfn_);
|
||||
return compat::invoke_r<R>(f, std::forward<Args>(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
template <bool Const, bool NoEx, class F, class R, class... Args>
|
||||
struct invoke_object_holder {
|
||||
static R invoke_object(thunk_storage<NoEx> s, Args&&... args) noexcept(NoEx) {
|
||||
using T = remove_reference_t<F>;
|
||||
using cv_T = conditional_t<Const, add_const_t<T>, T>;
|
||||
return compat::invoke_r<R>(*static_cast<cv_T*>(s.pobj_), std::forward<Args>(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
#if defined(BOOST_COMPAT_HAS_AUTO_NTTP)
|
||||
|
||||
template <auto f, bool Const, bool NoEx, class R, class... Args>
|
||||
struct invoke_mem_fn_holder {
|
||||
static R invoke_mem_fn(thunk_storage<NoEx> /* s */, Args&&... args) noexcept(NoEx) {
|
||||
return compat::invoke_r<R>(f, std::forward<Args>(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
template <auto f, class U, bool Const, bool NoEx, class R, class... Args>
|
||||
struct invoke_target_mem_fn_holder {
|
||||
static R invoke_mem_fn(thunk_storage<NoEx> s, Args&&... args) noexcept(NoEx) {
|
||||
using T = remove_reference_t<U>;
|
||||
using cv_T = conditional_t<Const, add_const_t<T>, T>;
|
||||
return compat::invoke_r<R>(f, *static_cast<cv_T*>(s.pobj_), std::forward<Args>(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
template <auto f, class T, bool Const, bool NoEx, class R, class... Args>
|
||||
struct invoke_ptr_mem_fn_holder {
|
||||
static R invoke_mem_fn(thunk_storage<NoEx> s, Args&&... args) noexcept(NoEx) {
|
||||
using cv_T = conditional_t<Const, add_const_t<T>, T>;
|
||||
return compat::invoke_r<R>(f, static_cast<cv_T*>(s.pobj_), std::forward<Args>(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
template <bool Const, bool NoEx, class R, class... Args>
|
||||
struct function_ref_base {
|
||||
private:
|
||||
thunk_storage<NoEx> thunk_ = nullptr;
|
||||
R (*invoke_)(thunk_storage<NoEx>, Args&&...) noexcept(NoEx) = nullptr;
|
||||
|
||||
public:
|
||||
struct fp_tag {};
|
||||
struct obj_tag {};
|
||||
struct mem_fn_tag {};
|
||||
|
||||
template <class F>
|
||||
function_ref_base(fp_tag, F* fn) noexcept
|
||||
: thunk_{}, invoke_(&invoke_function_holder<NoEx, F*, R, Args...>::invoke_function) {
|
||||
thunk_.pfn_ = reinterpret_cast<decltype(thunk_.pfn_)>(fn);
|
||||
}
|
||||
|
||||
template <class F>
|
||||
function_ref_base(obj_tag, F&& fn) noexcept
|
||||
: thunk_{}, invoke_(&invoke_object_holder<Const, NoEx, F, R, Args...>::invoke_object) {
|
||||
thunk_.pobj_ = const_cast<void*>(static_cast<void const*>(std::addressof(fn)));
|
||||
}
|
||||
|
||||
#if defined(BOOST_COMPAT_HAS_AUTO_NTTP)
|
||||
|
||||
template <auto f, class F = decltype(f)>
|
||||
function_ref_base(mem_fn_tag, nontype_t<f>)
|
||||
: thunk_{}, invoke_(&invoke_mem_fn_holder<F{f}, Const, NoEx, R, Args...>::invoke_mem_fn) {
|
||||
thunk_.pobj_ = nullptr;
|
||||
}
|
||||
|
||||
template <auto f, class U, class F = decltype(f)>
|
||||
function_ref_base(mem_fn_tag, nontype_t<f>, U&& obj)
|
||||
: thunk_{}, invoke_(&invoke_target_mem_fn_holder<F{f}, U, Const, NoEx, R, Args...>::invoke_mem_fn) {
|
||||
thunk_.pobj_ = const_cast<void*>(static_cast<void const*>(std::addressof(obj)));
|
||||
}
|
||||
|
||||
template <auto f, class T, class F = decltype(f)>
|
||||
function_ref_base(mem_fn_tag, nontype_t<f>, T* obj)
|
||||
: thunk_{}, invoke_(&invoke_ptr_mem_fn_holder<F{f}, T, Const, NoEx, R, Args...>::invoke_mem_fn) {
|
||||
thunk_.pobj_ = const_cast<void*>(static_cast<void const*>(obj));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
function_ref_base(const function_ref_base&) noexcept = default;
|
||||
function_ref_base& operator=(const function_ref_base&) noexcept = default;
|
||||
|
||||
R operator()(Args&&... args) const noexcept(NoEx) { return this->invoke_(thunk_, std::forward<Args>(args)...); }
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <class R, class... Args>
|
||||
struct function_ref<R(Args...)> : public detail::function_ref_base<false, false, R, Args...> {
|
||||
private:
|
||||
using base_type = detail::function_ref_base<false, false, R, Args...>;
|
||||
using typename base_type::fp_tag;
|
||||
using typename base_type::mem_fn_tag;
|
||||
using typename base_type::obj_tag;
|
||||
|
||||
template <class... T>
|
||||
using is_invocable_using = boost::compat::is_invocable_r<R, T..., Args...>;
|
||||
|
||||
public:
|
||||
template <class F, enable_if_t<std::is_function<F>::value && is_invocable_using<F>::value, int> = 0>
|
||||
function_ref(F* fn) noexcept : base_type(fp_tag{}, fn) {}
|
||||
|
||||
template <class F, class T = remove_reference_t<F>,
|
||||
enable_if_t<!std::is_same<remove_cvref_t<F>, function_ref>::value && !std::is_member_pointer<T>::value &&
|
||||
is_invocable_using<T&>::value,
|
||||
int> = 0>
|
||||
function_ref(F&& fn) noexcept : base_type(obj_tag{}, fn) {}
|
||||
|
||||
#if defined(BOOST_COMPAT_HAS_AUTO_NTTP)
|
||||
|
||||
template <auto f, class F = decltype(f), enable_if_t<is_invocable_using<F>::value, int> = 0>
|
||||
function_ref(nontype_t<f> x) noexcept : base_type(mem_fn_tag{}, x) {}
|
||||
|
||||
template <auto f, class U, class T = remove_reference_t<U>, class F = decltype(f),
|
||||
enable_if_t<!std::is_rvalue_reference_v<U&&> && is_invocable_using<F, T&>::value, int> = 0>
|
||||
function_ref(nontype_t<f> x, U&& obj) noexcept : base_type(mem_fn_tag{}, x, std::forward<U>(obj)) {}
|
||||
|
||||
template <auto f, class T, class F = decltype(f), enable_if_t<is_invocable_using<F, T*>::value, int> = 0>
|
||||
function_ref(nontype_t<f> x, T* obj) noexcept : base_type(mem_fn_tag{}, x, obj) {}
|
||||
|
||||
#endif
|
||||
|
||||
function_ref(const function_ref&) noexcept = default;
|
||||
function_ref& operator=(const function_ref&) noexcept = default;
|
||||
|
||||
template <class T, enable_if_t<!std::is_same<T, function_ref>::value && !std::is_pointer<T>::value, int> = 0>
|
||||
function_ref& operator=(T) = delete;
|
||||
};
|
||||
|
||||
template <class R, class... Args>
|
||||
struct function_ref<R(Args...) const> : public detail::function_ref_base<true, false, R, Args...> {
|
||||
private:
|
||||
using base_type = detail::function_ref_base<true, false, R, Args...>;
|
||||
using typename base_type::fp_tag;
|
||||
using typename base_type::mem_fn_tag;
|
||||
using typename base_type::obj_tag;
|
||||
|
||||
template <class... T>
|
||||
using is_invocable_using = boost::compat::is_invocable_r<R, T..., Args...>;
|
||||
|
||||
public:
|
||||
template <class F, enable_if_t<std::is_function<F>::value && is_invocable_using<F>::value, int> = 0>
|
||||
function_ref(F* fn) noexcept : base_type(fp_tag{}, fn) {}
|
||||
|
||||
template <class F, class T = remove_reference_t<F>,
|
||||
enable_if_t<!std::is_same<remove_cvref_t<F>, function_ref>::value && !std::is_member_pointer<T>::value &&
|
||||
is_invocable_using<T const&>::value,
|
||||
int> = 0>
|
||||
function_ref(F&& fn) noexcept : base_type(obj_tag{}, fn) {}
|
||||
|
||||
#if defined(BOOST_COMPAT_HAS_AUTO_NTTP)
|
||||
|
||||
template <auto f, class F = decltype(f), enable_if_t<is_invocable_using<F>::value, int> = 0>
|
||||
function_ref(nontype_t<f> x) noexcept : base_type(mem_fn_tag{}, x) {}
|
||||
|
||||
template <auto f, class U, class T = remove_reference_t<U>, class F = decltype(f),
|
||||
enable_if_t<!std::is_rvalue_reference_v<U&&> && is_invocable_using<F, T const&>::value, int> = 0>
|
||||
function_ref(nontype_t<f> x, U&& obj) noexcept : base_type(mem_fn_tag{}, x, std::forward<U>(obj)) {}
|
||||
|
||||
template <auto f, class T, class F = decltype(f), enable_if_t<is_invocable_using<F, T const*>::value, int> = 0>
|
||||
function_ref(nontype_t<f> x, T const* obj) noexcept : base_type(mem_fn_tag{}, x, obj) {}
|
||||
|
||||
#endif
|
||||
|
||||
function_ref(const function_ref&) noexcept = default;
|
||||
function_ref& operator=(const function_ref&) noexcept = default;
|
||||
|
||||
template <class T, enable_if_t<!std::is_same<T, function_ref>::value && !std::is_pointer<T>::value, int> = 0>
|
||||
function_ref& operator=(T) = delete;
|
||||
};
|
||||
|
||||
#if defined(__cpp_noexcept_function_type)
|
||||
|
||||
template <class R, class... Args>
|
||||
struct function_ref<R(Args...) noexcept> : public detail::function_ref_base<false, true, R, Args...> {
|
||||
private:
|
||||
using base_type = detail::function_ref_base<false, true, R, Args...>;
|
||||
using typename base_type::fp_tag;
|
||||
using typename base_type::mem_fn_tag;
|
||||
using typename base_type::obj_tag;
|
||||
|
||||
template <class... T>
|
||||
using is_invocable_using = boost::compat::is_nothrow_invocable_r<R, T..., Args...>;
|
||||
|
||||
public:
|
||||
template <class F, enable_if_t<std::is_function<F>::value && is_invocable_using<F>::value, int> = 0>
|
||||
function_ref(F* fn) noexcept : base_type(fp_tag{}, fn) {}
|
||||
|
||||
template <class F, class T = remove_reference_t<F>,
|
||||
enable_if_t<!std::is_same<remove_cvref_t<F>, function_ref>::value && !std::is_member_pointer<T>::value &&
|
||||
is_invocable_using<T&>::value,
|
||||
int> = 0>
|
||||
function_ref(F&& fn) noexcept : base_type(obj_tag{}, fn) {}
|
||||
|
||||
#if defined(BOOST_COMPAT_HAS_AUTO_NTTP)
|
||||
|
||||
template <auto f, class F = decltype(f), enable_if_t<is_invocable_using<F>::value, int> = 0>
|
||||
function_ref(nontype_t<f> x) noexcept : base_type(mem_fn_tag{}, x) {}
|
||||
|
||||
template <auto f, class U, class T = remove_reference_t<U>, class F = decltype(f),
|
||||
enable_if_t<!std::is_rvalue_reference_v<U&&> && is_invocable_using<F, T&>::value, int> = 0>
|
||||
function_ref(nontype_t<f> x, U&& obj) noexcept : base_type(mem_fn_tag{}, x, std::forward<U>(obj)) {}
|
||||
|
||||
template <auto f, class T, class F = decltype(f), enable_if_t<is_invocable_using<F, T*>::value, int> = 0>
|
||||
function_ref(nontype_t<f> x, T* obj) noexcept : base_type(mem_fn_tag{}, x, obj) {}
|
||||
|
||||
#endif
|
||||
|
||||
function_ref(const function_ref&) noexcept = default;
|
||||
function_ref& operator=(const function_ref&) noexcept = default;
|
||||
|
||||
template <class T, enable_if_t<!std::is_same<T, function_ref>::value && !std::is_pointer<T>::value, int> = 0>
|
||||
function_ref& operator=(T) = delete;
|
||||
};
|
||||
|
||||
template <class R, class... Args>
|
||||
struct function_ref<R(Args...) const noexcept> : public detail::function_ref_base<true, true, R, Args...> {
|
||||
private:
|
||||
using base_type = detail::function_ref_base<true, true, R, Args...>;
|
||||
using typename base_type::fp_tag;
|
||||
using typename base_type::mem_fn_tag;
|
||||
using typename base_type::obj_tag;
|
||||
|
||||
template <class... T>
|
||||
using is_invocable_using = boost::compat::is_nothrow_invocable_r<R, T..., Args...>;
|
||||
|
||||
public:
|
||||
template <class F, enable_if_t<std::is_function<F>::value && is_invocable_using<F>::value, int> = 0>
|
||||
function_ref(F* fn) noexcept : base_type(fp_tag{}, fn) {}
|
||||
|
||||
template <class F, class T = remove_reference_t<F>,
|
||||
enable_if_t<!std::is_same<remove_cvref_t<F>, function_ref>::value && !std::is_member_pointer<T>::value &&
|
||||
is_invocable_using<T const&>::value,
|
||||
int> = 0>
|
||||
function_ref(F&& fn) noexcept : base_type(obj_tag{}, fn) {}
|
||||
|
||||
#if defined(BOOST_COMPAT_HAS_AUTO_NTTP)
|
||||
|
||||
template <auto f, class F = decltype(f), enable_if_t<is_invocable_using<F>::value, int> = 0>
|
||||
function_ref(nontype_t<f> x) noexcept : base_type(mem_fn_tag{}, x) {}
|
||||
|
||||
template <auto f, class U, class T = remove_reference_t<U>, class F = decltype(f),
|
||||
enable_if_t<!std::is_rvalue_reference_v<U&&> && is_invocable_using<F, T const&>::value, int> = 0>
|
||||
function_ref(nontype_t<f> x, U&& obj) noexcept : base_type(mem_fn_tag{}, x, std::forward<U>(obj)) {}
|
||||
|
||||
template <auto f, class T, class F = decltype(f), enable_if_t<is_invocable_using<F, T const*>::value, int> = 0>
|
||||
function_ref(nontype_t<f> x, T const* obj) noexcept : base_type(mem_fn_tag{}, x, obj) {}
|
||||
|
||||
#endif
|
||||
|
||||
function_ref(const function_ref&) noexcept = default;
|
||||
function_ref& operator=(const function_ref&) noexcept = default;
|
||||
|
||||
template <class T, enable_if_t<!std::is_same<T, function_ref>::value && !std::is_pointer<T>::value, int> = 0>
|
||||
function_ref& operator=(T) = delete;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace compat
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_COMPAT_FUNCTION_REF_HPP_INCLUDED
|
||||
120
include/boost/compat/integer_sequence.hpp
Normal file
120
include/boost/compat/integer_sequence.hpp
Normal file
@@ -0,0 +1,120 @@
|
||||
#ifndef BOOST_COMPAT_INTEGER_SEQUENCE_HPP_INCLUDED
|
||||
#define BOOST_COMPAT_INTEGER_SEQUENCE_HPP_INCLUDED
|
||||
|
||||
// Copyright 2015, 2017, 2019 Peter Dimov.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#if defined(_MSC_VER) || defined(__GNUC__)
|
||||
# pragma push_macro( "I" )
|
||||
# undef I
|
||||
#endif
|
||||
|
||||
#if defined(__has_builtin)
|
||||
# if __has_builtin(__make_integer_seq)
|
||||
# define BOOST_COMPAT_HAS_MAKE_INTEGER_SEQ
|
||||
# endif
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace compat
|
||||
{
|
||||
|
||||
// integer_sequence
|
||||
template<class T, T... I> struct integer_sequence
|
||||
{
|
||||
};
|
||||
|
||||
#if defined(BOOST_COMPAT_HAS_MAKE_INTEGER_SEQ)
|
||||
|
||||
template<class T, T N> using make_integer_sequence = __make_integer_seq<integer_sequence, T, N>;
|
||||
|
||||
#else
|
||||
|
||||
// detail::make_integer_sequence_impl
|
||||
namespace detail
|
||||
{
|
||||
|
||||
// iseq_if_c
|
||||
template<bool C, class T, class E> struct iseq_if_c_impl;
|
||||
|
||||
template<class T, class E> struct iseq_if_c_impl<true, T, E>
|
||||
{
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template<class T, class E> struct iseq_if_c_impl<false, T, E>
|
||||
{
|
||||
using type = E;
|
||||
};
|
||||
|
||||
template<bool C, class T, class E> using iseq_if_c = typename iseq_if_c_impl<C, T, E>::type;
|
||||
|
||||
// iseq_identity
|
||||
template<class T> struct iseq_identity
|
||||
{
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template<class S1, class S2> struct append_integer_sequence;
|
||||
|
||||
template<class T, T... I, T... J> struct append_integer_sequence<integer_sequence<T, I...>, integer_sequence<T, J...>>
|
||||
{
|
||||
using type = integer_sequence< T, I..., ( J + sizeof...(I) )... >;
|
||||
};
|
||||
|
||||
template<class T, T N> struct make_integer_sequence_impl;
|
||||
|
||||
template<class T, T N> struct make_integer_sequence_impl_
|
||||
{
|
||||
private:
|
||||
|
||||
static_assert( N >= 0, "make_integer_sequence<T, N>: N must not be negative" );
|
||||
|
||||
static T const M = N / 2;
|
||||
static T const R = N % 2;
|
||||
|
||||
using S1 = typename make_integer_sequence_impl<T, M>::type;
|
||||
using S2 = typename append_integer_sequence<S1, S1>::type;
|
||||
using S3 = typename make_integer_sequence_impl<T, R>::type;
|
||||
using S4 = typename append_integer_sequence<S2, S3>::type;
|
||||
|
||||
public:
|
||||
|
||||
using type = S4;
|
||||
};
|
||||
|
||||
template<class T, T N> struct make_integer_sequence_impl: iseq_if_c<N == 0, iseq_identity<integer_sequence<T>>, iseq_if_c<N == 1, iseq_identity<integer_sequence<T, 0>>, make_integer_sequence_impl_<T, N> > >
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// make_integer_sequence
|
||||
template<class T, T N> using make_integer_sequence = typename detail::make_integer_sequence_impl<T, N>::type;
|
||||
|
||||
#endif // defined(BOOST_COMPAT_HAS_MAKE_INTEGER_SEQ)
|
||||
|
||||
// index_sequence
|
||||
template<std::size_t... I> using index_sequence = integer_sequence<std::size_t, I...>;
|
||||
|
||||
// make_index_sequence
|
||||
template<std::size_t N> using make_index_sequence = make_integer_sequence<std::size_t, N>;
|
||||
|
||||
// index_sequence_for
|
||||
template<class... T> using index_sequence_for = make_integer_sequence<std::size_t, sizeof...(T)>;
|
||||
|
||||
} // namespace compat
|
||||
} // namespace boost
|
||||
|
||||
#if defined(_MSC_VER) || defined(__GNUC__)
|
||||
# pragma pop_macro( "I" )
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_COMPAT_INTEGER_SEQUENCE_HPP_INCLUDED
|
||||
119
include/boost/compat/invoke.hpp
Normal file
119
include/boost/compat/invoke.hpp
Normal file
@@ -0,0 +1,119 @@
|
||||
#ifndef BOOST_COMPAT_INVOKE_HPP_INCLUDED
|
||||
#define BOOST_COMPAT_INVOKE_HPP_INCLUDED
|
||||
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/compat/mem_fn.hpp>
|
||||
#include <boost/compat/type_traits.hpp>
|
||||
#include <boost/compat/detail/returns.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/config/workaround.hpp>
|
||||
#include <utility>
|
||||
|
||||
namespace boost {
|
||||
namespace compat {
|
||||
|
||||
// invoke
|
||||
|
||||
template<class F, class... A>
|
||||
constexpr auto invoke( F&& f, A&&... a )
|
||||
BOOST_COMPAT_RETURNS( std::forward<F>(f)(std::forward<A>(a)...) )
|
||||
|
||||
template<class M, class T, class... A>
|
||||
constexpr auto invoke( M T::* pm, A&&... a )
|
||||
BOOST_COMPAT_RETURNS( compat::mem_fn(pm)(std::forward<A>(a)...) )
|
||||
|
||||
// invoke_result_t
|
||||
|
||||
template<class F, class... A> using invoke_result_t = decltype( compat::invoke( std::declval<F>(), std::declval<A>()... ) );
|
||||
|
||||
// is_invocable
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<class, class F, class... A> struct is_invocable_: std::false_type {};
|
||||
template<class F, class... A> struct is_invocable_< void_t<invoke_result_t<F, A...>>, F, A... >: std::true_type {};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class F, class... A> struct is_invocable: detail::is_invocable_<void, F, A...> {};
|
||||
|
||||
// is_nothrow_invocable
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1910)
|
||||
|
||||
template<class F, class... A> struct is_nothrow_invocable: std::false_type {};
|
||||
|
||||
#else
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<class F, class... A> struct is_nothrow_invocable_
|
||||
{
|
||||
using type = std::integral_constant<bool, noexcept( compat::invoke( std::declval<F>(), std::declval<A>()... ) )>;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class F, class... A> struct is_nothrow_invocable: conditional_t< is_invocable<F, A...>::value, detail::is_nothrow_invocable_<F, A...>, std::false_type >::type {};
|
||||
|
||||
#endif
|
||||
|
||||
// invoke_r
|
||||
|
||||
template<class R, class F, class... A, class En = enable_if_t<
|
||||
std::is_void<R>::value && is_invocable<F, A...>::value >>
|
||||
constexpr R invoke_r( F&& f, A&&... a )
|
||||
noexcept( noexcept( static_cast<R>( compat::invoke( std::forward<F>(f), std::forward<A>(a)... ) ) ) )
|
||||
{
|
||||
return static_cast<R>( compat::invoke( std::forward<F>(f), std::forward<A>(a)... ) );
|
||||
}
|
||||
|
||||
template<class R, class F, class... A, class = void, class En = enable_if_t<
|
||||
!std::is_void<R>::value && std::is_convertible< invoke_result_t<F, A...>, R >::value >>
|
||||
constexpr R invoke_r( F&& f, A&&... a )
|
||||
noexcept( noexcept( static_cast<R>( compat::invoke( std::forward<F>(f), std::forward<A>(a)... ) ) ) )
|
||||
{
|
||||
return compat::invoke( std::forward<F>(f), std::forward<A>(a)... );
|
||||
}
|
||||
|
||||
// is_invocable_r
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<class R, class F, class... A> struct is_invocable_r_: std::is_convertible< invoke_result_t<F, A...>, R > {};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class R, class F, class... A> struct is_invocable_r:
|
||||
conditional_t< !is_invocable<F, A...>::value, std::false_type,
|
||||
conditional_t< std::is_void<R>::value, std::true_type,
|
||||
detail::is_invocable_r_<R, F, A...> >> {};
|
||||
|
||||
// is_nothrow_invocable_r
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1910)
|
||||
|
||||
template<class R, class F, class... A> struct is_nothrow_invocable_r: std::false_type {};
|
||||
|
||||
#else
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<class R, class F, class... A> struct is_nothrow_invocable_r_
|
||||
{
|
||||
using type = std::integral_constant<bool, noexcept( compat::invoke_r<R>( std::declval<F>(), std::declval<A>()... ) )>;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class R, class F, class... A> struct is_nothrow_invocable_r: conditional_t< is_invocable_r<R, F, A...>::value, detail::is_nothrow_invocable_r_<R, F, A...>, std::false_type >::type {};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace compat
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_COMPAT_INVOKE_HPP_INCLUDED
|
||||
@@ -1,11 +1,11 @@
|
||||
#ifndef BOOST_COMPAT_LATCH_HPP_INCLUDED
|
||||
#define BOOST_COMPAT_LATCH_HPP_INCLUDED
|
||||
|
||||
// Copyright 2023 Peter Dimov.
|
||||
// Copyright 2023 Christian Mazakas.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#ifndef BOOST_COMPAT_LATCH_HPP_INCLUDED
|
||||
#define BOOST_COMPAT_LATCH_HPP_INCLUDED
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <climits>
|
||||
|
||||
78
include/boost/compat/mem_fn.hpp
Normal file
78
include/boost/compat/mem_fn.hpp
Normal file
@@ -0,0 +1,78 @@
|
||||
#ifndef BOOST_COMPAT_MEM_FN_HPP_INCLUDED
|
||||
#define BOOST_COMPAT_MEM_FN_HPP_INCLUDED
|
||||
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/compat/type_traits.hpp>
|
||||
#include <boost/compat/detail/returns.hpp>
|
||||
#include <functional>
|
||||
|
||||
namespace boost {
|
||||
namespace compat {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<class T, class U, class Td = remove_cvref_t<T>, class Ud = remove_cvref_t<U>>
|
||||
struct is_same_or_base: std::integral_constant<bool, std::is_same<Td, Ud>::value || std::is_base_of<Td, Ud>::value>
|
||||
{
|
||||
};
|
||||
|
||||
template<class T> struct is_reference_wrapper_: std::false_type {};
|
||||
template<class T> struct is_reference_wrapper_< std::reference_wrapper<T> >: std::true_type {};
|
||||
|
||||
template<class T> struct is_reference_wrapper: is_reference_wrapper_< remove_cvref_t<T> > {};
|
||||
|
||||
template<class M, class T> struct _mfn
|
||||
{
|
||||
M T::* pm_;
|
||||
|
||||
template<class U, class... A, class En = enable_if_t<is_same_or_base<T, U>::value>>
|
||||
constexpr auto operator()( U&& u, A&&... a ) const
|
||||
BOOST_COMPAT_RETURNS( (std::forward<U>(u).*pm_)( std::forward<A>(a)... ) )
|
||||
|
||||
template<class U, class... A, class = void, class En = enable_if_t< !is_same_or_base<T, U>::value && is_reference_wrapper<U>::value>>
|
||||
constexpr auto operator()( U&& u, A&&... a ) const
|
||||
BOOST_COMPAT_RETURNS( (u.get().*pm_)( std::forward<A>(a)... ) )
|
||||
|
||||
template<class U, class... A, class = void, class = void, class En = enable_if_t< !is_same_or_base<T, U>::value && !is_reference_wrapper<U>::value>>
|
||||
constexpr auto operator()( U&& u, A&&... a ) const
|
||||
BOOST_COMPAT_RETURNS( ((*std::forward<U>(u)).*pm_)( std::forward<A>(a)... ) )
|
||||
};
|
||||
|
||||
template<class M, class T> struct _md
|
||||
{
|
||||
M T::* pm_;
|
||||
|
||||
template<class U, class En = enable_if_t<is_same_or_base<T, U>::value>>
|
||||
constexpr auto operator()( U&& u ) const
|
||||
BOOST_COMPAT_RETURNS( std::forward<U>(u).*pm_ )
|
||||
|
||||
template<class U, class = void, class En = enable_if_t< !is_same_or_base<T, U>::value && is_reference_wrapper<U>::value>>
|
||||
constexpr auto operator()( U&& u ) const
|
||||
BOOST_COMPAT_RETURNS( u.get().*pm_ )
|
||||
|
||||
template<class U, class = void, class = void, class En = enable_if_t< !is_same_or_base<T, U>::value && !is_reference_wrapper<U>::value>>
|
||||
constexpr auto operator()( U&& u ) const
|
||||
BOOST_COMPAT_RETURNS( (*std::forward<U>(u)).*pm_ )
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class M, class T, class En = enable_if_t< std::is_function<M>::value > >
|
||||
constexpr auto mem_fn( M T::* pm ) noexcept -> detail::_mfn<M, T>
|
||||
{
|
||||
return detail::_mfn<M, T>{ pm };
|
||||
}
|
||||
|
||||
template<class M, class T, class = void, class En = enable_if_t< !std::is_function<M>::value > >
|
||||
constexpr auto mem_fn( M T::* pm ) noexcept -> detail::_md<M, T>
|
||||
{
|
||||
return detail::_md<M, T>{ pm };
|
||||
}
|
||||
|
||||
} // namespace compat
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_COMPAT_MEM_FN_HPP_INCLUDED
|
||||
60
include/boost/compat/to_array.hpp
Normal file
60
include/boost/compat/to_array.hpp
Normal file
@@ -0,0 +1,60 @@
|
||||
#ifndef BOOST_COMPAT_TO_ARRAY_HPP_INCLUDED
|
||||
#define BOOST_COMPAT_TO_ARRAY_HPP_INCLUDED
|
||||
|
||||
// Copyright 2024 Ruben Perez Hidalgo
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/compat/integer_sequence.hpp>
|
||||
#include <boost/compat/type_traits.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace boost {
|
||||
namespace compat {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <class T, std::size_t N, std::size_t... I>
|
||||
constexpr std::array<remove_cv_t<T>, N> to_array_lvalue(T (&a)[N], index_sequence<I...>)
|
||||
{
|
||||
return {{a[I]...}};
|
||||
}
|
||||
|
||||
template <class T, std::size_t N, std::size_t... I>
|
||||
constexpr std::array<remove_cv_t<T>, N> to_array_rvalue(T (&&a)[N], index_sequence<I...>)
|
||||
{
|
||||
return {{std::move(a[I])...}};
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <class T, std::size_t N>
|
||||
constexpr std::array<remove_cv_t<T>, N> to_array(T (&a)[N])
|
||||
{
|
||||
static_assert(
|
||||
std::is_constructible<remove_cv_t<T>, T&>::value,
|
||||
"This overload requires the resulting element type to be constructible from T&"
|
||||
);
|
||||
static_assert(!std::is_array<T>::value, "to_array does not work for multi-dimensional C arrays");
|
||||
return detail::to_array_lvalue(a, make_index_sequence<N>{});
|
||||
}
|
||||
|
||||
template <class T, std::size_t N>
|
||||
constexpr std::array<remove_cv_t<T>, N> to_array(T (&&a)[N])
|
||||
{
|
||||
static_assert(
|
||||
std::is_constructible<remove_cv_t<T>, T&&>::value,
|
||||
"This overload requires the resulting element type to be constructible from T&&"
|
||||
);
|
||||
static_assert(!std::is_array<T>::value, "to_array does not work for multi-dimensional C arrays");
|
||||
return detail::to_array_rvalue(static_cast<T(&&)[N]>(a), make_index_sequence<N>{});
|
||||
}
|
||||
|
||||
} // namespace compat
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_COMPAT_TO_ARRAY_HPP_INCLUDED
|
||||
41
include/boost/compat/type_traits.hpp
Normal file
41
include/boost/compat/type_traits.hpp
Normal file
@@ -0,0 +1,41 @@
|
||||
#ifndef BOOST_COMPAT_TYPE_TRAITS_HPP_INCLUDED
|
||||
#define BOOST_COMPAT_TYPE_TRAITS_HPP_INCLUDED
|
||||
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Copyright 2024 Christian Mazakas
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost {
|
||||
namespace compat {
|
||||
|
||||
template<class T> using remove_const_t = typename std::remove_const<T>::type;
|
||||
template<class T> using remove_cv_t = typename std::remove_cv<T>::type;
|
||||
template<class T> using remove_reference_t = typename std::remove_reference<T>::type;
|
||||
template<class T> using remove_cvref_t = remove_cv_t< remove_reference_t<T> >;
|
||||
|
||||
template<class T> using decay_t = typename std::decay<T>::type;
|
||||
|
||||
template<bool B, class T = void> using enable_if_t = typename std::enable_if<B, T>::type;
|
||||
|
||||
template<bool B, class T, class F> using conditional_t = typename std::conditional<B, T, F>::type;
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<class...> struct make_void
|
||||
{
|
||||
using type = void;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class... T> using void_t = typename detail::make_void<T...>::type;
|
||||
|
||||
template<class T> using add_const_t = typename std::add_const<T>::type;
|
||||
|
||||
} // namespace compat
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_COMPAT_TYPE_TRAITS_HPP_INCLUDED
|
||||
@@ -2,7 +2,8 @@
|
||||
"key": "compat",
|
||||
"name": "Compat",
|
||||
"authors": [
|
||||
"Peter Dimov"
|
||||
"Peter Dimov",
|
||||
"Christian Mazakas"
|
||||
],
|
||||
"maintainers": [
|
||||
"Peter Dimov <pdimov -at- gmail.com>"
|
||||
|
||||
@@ -8,6 +8,7 @@ if(HAVE_BOOST_TEST)
|
||||
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
find_package(Threads REQUIRED)
|
||||
boost_test_jamfile(FILE Jamfile LINK_LIBRARIES Boost::compat Boost::core Threads::Threads)
|
||||
|
||||
boost_test_jamfile(FILE Jamfile LINK_LIBRARIES Boost::compat Boost::core Boost::mp11 Threads::Threads)
|
||||
|
||||
endif()
|
||||
|
||||
90
test/Jamfile
90
test/Jamfile
@@ -4,7 +4,8 @@
|
||||
# https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
import testing ;
|
||||
import ../../config/checks/config : requires ;
|
||||
import-search /boost/config/checks ;
|
||||
import config : requires ;
|
||||
|
||||
project
|
||||
: default-build
|
||||
@@ -20,10 +21,97 @@ project
|
||||
<toolset>msvc:<warnings-as-errors>on
|
||||
<toolset>gcc:<warnings-as-errors>on
|
||||
<toolset>clang:<warnings-as-errors>on
|
||||
|
||||
<library>/boost/core//boost_core
|
||||
<library>/boost/mp11//boost_mp11
|
||||
|
||||
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81601
|
||||
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91146
|
||||
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92397
|
||||
<toolset>gcc,<undefined-sanitizer>norecover:<cxxflags>"-Wno-array-bounds"
|
||||
<toolset>gcc,<address-sanitizer>norecover:<cxxflags>"-Wno-array-bounds"
|
||||
;
|
||||
|
||||
run quick.cpp ;
|
||||
|
||||
run latch_test.cpp ;
|
||||
|
||||
run shared_lock_test.cpp ;
|
||||
run shared_lock_test.cpp : : : <exception-handling>off : shared_lock_test_nx ;
|
||||
|
||||
run invoke_fn_test.cpp ;
|
||||
run invoke_obj_test.cpp ;
|
||||
run invoke_mfn_test.cpp ;
|
||||
run invoke_md_test.cpp ;
|
||||
|
||||
run mem_fn_mfn_test.cpp ;
|
||||
run mem_fn_md_test.cpp ;
|
||||
|
||||
run invoke_fn_noexcept_test.cpp ;
|
||||
run invoke_obj_noexcept_test.cpp ;
|
||||
run invoke_mfn_noexcept_test.cpp ;
|
||||
run invoke_md_noexcept_test.cpp ;
|
||||
|
||||
compile invoke_fn_constexpr_test.cpp ;
|
||||
compile invoke_obj_constexpr_test.cpp ;
|
||||
compile invoke_mfn_constexpr_test.cpp
|
||||
: <toolset>gcc-4.8:<build>no <toolset>gcc-4.9:<build>no ;
|
||||
compile invoke_md_constexpr_test.cpp
|
||||
: <toolset>gcc-4.8:<build>no <toolset>gcc-4.9:<build>no ;
|
||||
|
||||
run invoke_result_test.cpp ;
|
||||
run is_invocable_test.cpp ;
|
||||
run is_nothrow_invocable_test.cpp ;
|
||||
|
||||
run bind_front_fn_test.cpp ;
|
||||
run bind_front_obj_test.cpp ;
|
||||
run bind_front_mfn_test.cpp ;
|
||||
run bind_front_md_test.cpp ;
|
||||
|
||||
compile bind_front_fn_constexpr_test.cpp ;
|
||||
compile bind_front_obj_constexpr_test.cpp ;
|
||||
compile bind_front_mfn_constexpr_test.cpp ;
|
||||
compile bind_front_md_constexpr_test.cpp ;
|
||||
|
||||
run integer_sequence_test.cpp ;
|
||||
|
||||
run bind_back_fn_test.cpp ;
|
||||
run bind_back_obj_test.cpp ;
|
||||
run bind_back_mfn_test.cpp ;
|
||||
run bind_back_md_test.cpp ;
|
||||
|
||||
compile bind_back_fn_constexpr_test.cpp ;
|
||||
compile bind_back_obj_constexpr_test.cpp ;
|
||||
compile bind_back_mfn_constexpr_test.cpp ;
|
||||
compile bind_back_md_constexpr_test.cpp ;
|
||||
|
||||
run invoke_r_fn_test.cpp ;
|
||||
run invoke_r_obj_test.cpp ;
|
||||
run invoke_r_mfn_test.cpp ;
|
||||
run invoke_r_md_test.cpp ;
|
||||
|
||||
run invoke_r_fn_noexcept_test.cpp ;
|
||||
run invoke_r_obj_noexcept_test.cpp ;
|
||||
run invoke_r_mfn_noexcept_test.cpp ;
|
||||
run invoke_r_md_noexcept_test.cpp ;
|
||||
|
||||
compile invoke_r_fn_constexpr_test.cpp ;
|
||||
compile invoke_r_obj_constexpr_test.cpp ;
|
||||
compile invoke_r_mfn_constexpr_test.cpp
|
||||
: <toolset>gcc-4.8:<build>no <toolset>gcc-4.9:<build>no ;
|
||||
compile invoke_r_md_constexpr_test.cpp
|
||||
: <toolset>gcc-4.8:<build>no <toolset>gcc-4.9:<build>no ;
|
||||
|
||||
run is_invocable_r_test.cpp ;
|
||||
run is_nothrow_invocable_r_test.cpp ;
|
||||
|
||||
run function_ref_fn_test.cpp ;
|
||||
run function_ref_obj_test.cpp ;
|
||||
run function_ref_mfn_test.cpp ;
|
||||
|
||||
run function_ref_fn_noexcept_test.cpp ;
|
||||
run function_ref_mfn_noexcept_test.cpp ;
|
||||
run function_ref_obj_noexcept_test.cpp ;
|
||||
|
||||
run to_array_lvalue_test.cpp ;
|
||||
run to_array_rvalue_test.cpp ;
|
||||
|
||||
60
test/bind_back_fn_constexpr_test.cpp
Normal file
60
test/bind_back_fn_constexpr_test.cpp
Normal file
@@ -0,0 +1,60 @@
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ == 7
|
||||
# pragma GCC diagnostic ignored "-Wnoexcept-type"
|
||||
#endif
|
||||
|
||||
#include <boost/compat/bind_back.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/config/pragma_message.hpp>
|
||||
|
||||
#if defined(BOOST_NO_CXX14_CONSTEXPR)
|
||||
|
||||
BOOST_PRAGMA_MESSAGE( "Test skipped because BOOST_NO_CXX14_CONSTEXPR is defined" )
|
||||
int main() {}
|
||||
|
||||
#else
|
||||
|
||||
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
|
||||
#define BOOST_TEST_EQ(x, y) STATIC_ASSERT((x) == (y))
|
||||
|
||||
constexpr int f0()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
constexpr int f1( int x1 ) noexcept
|
||||
{
|
||||
return x1;
|
||||
}
|
||||
|
||||
constexpr int f2( int x1, int x2 )
|
||||
{
|
||||
return 10*x1+x2;
|
||||
}
|
||||
|
||||
constexpr int f3( int x1, int x2, int x3 ) noexcept
|
||||
{
|
||||
return 100*x1 + 10*x2 + x3;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( f0 )(), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( f1 )( 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( f2 )( 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( f3 )( 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( f1, 1 )(), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( f2, 1 )( 2 ), 21 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( f3, 1 )( 2, 3 ), 231 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( f2, 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( f3, 1, 2 )( 3 ), 312 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( f3, 1, 2, 3 )(), 123 );
|
||||
}
|
||||
|
||||
#endif
|
||||
57
test/bind_back_fn_test.cpp
Normal file
57
test/bind_back_fn_test.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ == 7
|
||||
# pragma GCC diagnostic ignored "-Wnoexcept-type"
|
||||
#endif
|
||||
|
||||
#include <boost/compat/bind_back.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <memory>
|
||||
|
||||
int f0()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int f1( int x1 ) noexcept
|
||||
{
|
||||
return x1;
|
||||
}
|
||||
|
||||
int f2( int x1, int x2 )
|
||||
{
|
||||
return 10*x1+x2;
|
||||
}
|
||||
|
||||
int f3( int x1, int x2, int x3 ) noexcept
|
||||
{
|
||||
return 100*x1 + 10*x2 + x3;
|
||||
}
|
||||
|
||||
int g( std::unique_ptr<int> p, std::unique_ptr<int> q )
|
||||
{
|
||||
return 10 * *p + *q;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( f0 )(), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( f1 )( 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( f2 )( 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( f3 )( 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( f1, 1 )(), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( f2, 1 )( 2 ), 21 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( f3, 1 )( 2, 3 ), 231 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( f2, 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( f3, 1, 2 )( 3 ), 312 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( f3, 1, 2, 3 )(), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( g, std::unique_ptr<int>( new int(1) ) )( std::unique_ptr<int>( new int(2) ) ), 21 );
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
58
test/bind_back_md_constexpr_test.cpp
Normal file
58
test/bind_back_md_constexpr_test.cpp
Normal file
@@ -0,0 +1,58 @@
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/compat/bind_back.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/config/workaround.hpp>
|
||||
#include <boost/config/pragma_message.hpp>
|
||||
|
||||
#if defined(BOOST_NO_CXX14_CONSTEXPR)
|
||||
|
||||
BOOST_PRAGMA_MESSAGE( "Test skipped because BOOST_NO_CXX14_CONSTEXPR is defined" )
|
||||
int main() {}
|
||||
|
||||
#else
|
||||
|
||||
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
|
||||
#define BOOST_TEST_EQ(x, y) STATIC_ASSERT((x) == (y))
|
||||
|
||||
struct X
|
||||
{
|
||||
int m = -1;
|
||||
};
|
||||
|
||||
struct Y: public X
|
||||
{
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::m, X() )(), -1 );
|
||||
}
|
||||
|
||||
{
|
||||
constexpr X x = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::m, x )(), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::m, &x )(), -1 );
|
||||
}
|
||||
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, >= 1920 && BOOST_MSVC < 1950)
|
||||
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::m, Y() )(), -1 );
|
||||
}
|
||||
|
||||
{
|
||||
constexpr Y y = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::m, y )(), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::m, &y )(), -1 );
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
101
test/bind_back_md_test.cpp
Normal file
101
test/bind_back_md_test.cpp
Normal file
@@ -0,0 +1,101 @@
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/compat/bind_back.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <functional>
|
||||
|
||||
struct X
|
||||
{
|
||||
int m = -1;
|
||||
};
|
||||
|
||||
struct Y: public virtual X
|
||||
{
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::m, X() )(), -1 );
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::m, Y() )(), -1 );
|
||||
}
|
||||
|
||||
{
|
||||
X x;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::m, x )(), -1 );
|
||||
}
|
||||
|
||||
{
|
||||
X x;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::m, &x )(), -1 );
|
||||
boost::compat::bind_back( &X::m, &x )() = +1;
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::m, &x )(), +1 );
|
||||
}
|
||||
|
||||
{
|
||||
X x;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::m, std::ref(x) )(), -1 );
|
||||
boost::compat::bind_back( &X::m, std::ref(x) )() = +1;
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::m, std::ref(x) )(), +1 );
|
||||
}
|
||||
|
||||
{
|
||||
X x;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::m, std::cref(x) )(), -1 );
|
||||
}
|
||||
|
||||
{
|
||||
Y y;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::m, y )(), -1 );
|
||||
}
|
||||
|
||||
{
|
||||
Y y;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::m, &y )(), -1 );
|
||||
boost::compat::bind_back( &X::m, &y )() = +1;
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::m, &y )(), +1 );
|
||||
}
|
||||
|
||||
{
|
||||
Y y;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::m, std::ref(y) )(), -1 );
|
||||
boost::compat::bind_back( &X::m, std::ref(y) )() = +1;
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::m, std::ref(y) )(), +1 );
|
||||
}
|
||||
|
||||
{
|
||||
Y y;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::m, std::cref(y) )(), -1 );
|
||||
}
|
||||
|
||||
{
|
||||
X const x = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::m, x )(), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::m, &x )(), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::m, std::ref(x) )(), -1 );
|
||||
}
|
||||
|
||||
{
|
||||
Y const y = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::m, y )(), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::m, &y )(), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::m, std::ref(y) )(), -1 );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
137
test/bind_back_mfn_constexpr_test.cpp
Normal file
137
test/bind_back_mfn_constexpr_test.cpp
Normal file
@@ -0,0 +1,137 @@
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ == 7
|
||||
# pragma GCC diagnostic ignored "-Wnoexcept-type"
|
||||
#endif
|
||||
|
||||
#include <boost/compat/bind_back.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/config/pragma_message.hpp>
|
||||
|
||||
#if defined(BOOST_NO_CXX14_CONSTEXPR)
|
||||
|
||||
BOOST_PRAGMA_MESSAGE( "Test skipped because BOOST_NO_CXX14_CONSTEXPR is defined" )
|
||||
int main() {}
|
||||
|
||||
#else
|
||||
|
||||
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
|
||||
#define BOOST_TEST_EQ(x, y) STATIC_ASSERT((x) == (y))
|
||||
|
||||
struct X
|
||||
{
|
||||
constexpr int f0()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
constexpr int f1( int x1 ) noexcept
|
||||
{
|
||||
return x1;
|
||||
}
|
||||
|
||||
constexpr int f2( int x1, int x2 ) const
|
||||
{
|
||||
return 10*x1+x2;
|
||||
}
|
||||
|
||||
constexpr int f3( int x1, int x2, int x3 ) const noexcept
|
||||
{
|
||||
return 100*x1 + 10*x2 + x3;
|
||||
}
|
||||
};
|
||||
|
||||
struct Y: public X
|
||||
{
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f0 )( X() ), -1 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f1 )( X(), 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2 )( X(), 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3 )( X(), 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f1, X(), 1 )(), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, X(), 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, X(), 1, 2, 3 )(), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f1, 1 )( X() ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, 1, 2 )( X() ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, 1, 2, 3 )( X() ), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f0 )( Y() ), -1 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f1 )( Y(), 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2 )( Y(), 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3 )( Y(), 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f1, Y(), 1 )(), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, Y(), 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, Y(), 1, 2, 3 )(), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f1, 1 )( Y() ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, 1, 2 )( Y() ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, 1, 2, 3 )( Y() ), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
constexpr X x = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2 )( x, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3 )( x, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, x, 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, x, 1, 2, 3 )(), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, 1, 2 )( x ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, 1, 2, 3 )( x ), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
constexpr Y x = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2 )( x, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3 )( x, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, x, 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, x, 1, 2, 3 )(), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, 1, 2 )( x ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, 1, 2, 3 )( x ), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
constexpr X x = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2 )( &x, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3 )( &x, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, &x, 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, &x, 1, 2, 3 )(), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, 1, 2 )( &x ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, 1, 2, 3 )( &x ), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
constexpr Y x = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2 )( &x, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3 )( &x, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, &x, 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, &x, 1, 2, 3 )(), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, 1, 2 )( &x ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, 1, 2, 3 )( &x ), 123 );
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
308
test/bind_back_mfn_test.cpp
Normal file
308
test/bind_back_mfn_test.cpp
Normal file
@@ -0,0 +1,308 @@
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ == 7
|
||||
# pragma GCC diagnostic ignored "-Wnoexcept-type"
|
||||
#endif
|
||||
|
||||
#include <boost/compat/bind_back.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
struct X
|
||||
{
|
||||
int f0()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int f1( int x1 ) noexcept
|
||||
{
|
||||
return x1;
|
||||
}
|
||||
|
||||
int f2( int x1, int x2 ) const
|
||||
{
|
||||
return 10*x1+x2;
|
||||
}
|
||||
|
||||
int f3( int x1, int x2, int x3 ) const noexcept
|
||||
{
|
||||
return 100*x1 + 10*x2 + x3;
|
||||
}
|
||||
};
|
||||
|
||||
struct Y: public virtual X
|
||||
{
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f0 )( X() ), -1 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f1 )( X(), 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2 )( X(), 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3 )( X(), 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f1, X(), 1 )(), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, X(), 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, X(), 1, 2, 3 )(), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f1, 1 )( X() ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, 1, 2 )( X() ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, 1, 2, 3 )( X() ), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f0 )( Y() ), -1 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f1 )( Y(), 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2 )( Y(), 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3 )( Y(), 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f1, Y(), 1 )(), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, Y(), 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, Y(), 1, 2, 3 )(), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f1, 1 )( Y() ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, 1, 2 )( Y() ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, 1, 2, 3 )( Y() ), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
X x;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f0 )( x ), -1 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f1 )( x, 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2 )( x, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3 )( x, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f1, x, 1 )(), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, x, 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, x, 1, 2, 3 )(), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f1, 1 )( x ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, 1, 2 )( x ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, 1, 2, 3 )( x ), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
Y x;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f0 )( x ), -1 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f1 )( x, 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2 )( x, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3 )( x, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f1, x, 1 )(), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, x, 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, x, 1, 2, 3 )(), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f1, 1 )( x ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, 1, 2 )( x ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, 1, 2, 3 )( x ), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
X x;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f0 )( &x ), -1 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f1 )( &x, 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2 )( &x, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3 )( &x, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f1, &x, 1 )(), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, &x, 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, &x, 1, 2, 3 )(), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f1, 1 )( &x ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, 1, 2 )( &x ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, 1, 2, 3 )( &x ), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
Y x;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f0 )( &x ), -1 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f1 )( &x, 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2 )( &x, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3 )( &x, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f1, &x, 1 )(), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, &x, 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, &x, 1, 2, 3 )(), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f1, 1 )( &x ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, 1, 2 )( &x ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, 1, 2, 3 )( &x ), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
X x;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f0 )( std::ref(x) ), -1 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f1 )( std::ref(x), 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2 )( std::ref(x), 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3 )( std::ref(x), 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f1, std::ref(x), 1 )(), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, std::ref(x), 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, std::ref(x), 1, 2, 3 )(), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f1, 1 )( std::ref(x) ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, 1, 2 )( std::ref(x) ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, 1, 2, 3 )( std::ref(x) ), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
Y x;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f0 )( std::ref(x) ), -1 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f1 )( std::ref(x), 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2 )( std::ref(x), 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3 )( std::ref(x), 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f1, std::ref(x), 1 )(), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, std::ref(x), 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, std::ref(x), 1, 2, 3 )(), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f1, 1 )( std::ref(x) ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, 1, 2 )( std::ref(x) ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, 1, 2, 3 )( std::ref(x) ), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
X x;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2 )( std::cref(x), 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3 )( std::cref(x), 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, std::cref(x), 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, std::cref(x), 1, 2, 3 )(), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, 1, 2 )( std::cref(x) ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, 1, 2, 3 )( std::cref(x) ), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
Y x;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2 )( std::cref(x), 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3 )( std::cref(x), 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, std::cref(x), 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, std::cref(x), 1, 2, 3 )(), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, 1, 2 )( std::cref(x) ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, 1, 2, 3 )( std::cref(x) ), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
X const x = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2 )( x, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3 )( x, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, x, 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, x, 1, 2, 3 )(), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, 1, 2 )( x ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, 1, 2, 3 )( x ), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
Y const x = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2 )( x, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3 )( x, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, x, 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, x, 1, 2, 3 )(), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, 1, 2 )( x ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, 1, 2, 3 )( x ), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
X const x = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2 )( &x, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3 )( &x, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, &x, 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, &x, 1, 2, 3 )(), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, 1, 2 )( &x ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, 1, 2, 3 )( &x ), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
Y const x = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2 )( &x, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3 )( &x, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, &x, 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, &x, 1, 2, 3 )(), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, 1, 2 )( &x ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, 1, 2, 3 )( &x ), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
X const x = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2 )( std::ref(x), 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3 )( std::ref(x), 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, std::ref(x), 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, std::ref(x), 1, 2, 3 )(), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, 1, 2 )( std::ref(x) ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, 1, 2, 3 )( std::ref(x) ), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
Y const x = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2 )( std::ref(x), 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3 )( std::ref(x), 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, std::ref(x), 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, std::ref(x), 1, 2, 3 )(), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, 1, 2 )( std::ref(x) ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, 1, 2, 3 )( std::ref(x) ), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
std::unique_ptr<X> px( new X );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, 1, 2, 3 )( std::move(px) ), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
std::unique_ptr<Y> px( new Y );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, 1, 2, 3 )( std::move(px) ), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
std::unique_ptr<X> px( new X );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, std::move(px), 1, 2, 3 )(), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
std::unique_ptr<Y> px( new Y );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, std::move(px), 1, 2, 3 )(), 123 );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
96
test/bind_back_obj_constexpr_test.cpp
Normal file
96
test/bind_back_obj_constexpr_test.cpp
Normal file
@@ -0,0 +1,96 @@
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/compat/bind_back.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/config/pragma_message.hpp>
|
||||
|
||||
#if defined(BOOST_NO_CXX14_CONSTEXPR)
|
||||
|
||||
BOOST_PRAGMA_MESSAGE( "Test skipped because BOOST_NO_CXX14_CONSTEXPR is defined" )
|
||||
int main() {}
|
||||
|
||||
#else
|
||||
|
||||
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
|
||||
#define BOOST_TEST_EQ(x, y) STATIC_ASSERT((x) == (y))
|
||||
|
||||
struct F1
|
||||
{
|
||||
constexpr int operator()()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
constexpr int operator()( int x1 ) noexcept
|
||||
{
|
||||
return x1;
|
||||
}
|
||||
|
||||
constexpr int operator()( int x1, int x2 ) const
|
||||
{
|
||||
return 10*x1+x2;
|
||||
}
|
||||
|
||||
constexpr int operator()( int x1, int x2, int x3 ) const noexcept
|
||||
{
|
||||
return 100*x1 + 10*x2 + x3;
|
||||
}
|
||||
};
|
||||
|
||||
struct F2
|
||||
{
|
||||
constexpr int operator()( int x1, int x2 ) &
|
||||
{
|
||||
return 100*x1 + 10*x2 + 1;
|
||||
}
|
||||
|
||||
constexpr int operator()( int x1, int x2 ) const &
|
||||
{
|
||||
return 100*x1 + 10*x2 + 2;
|
||||
}
|
||||
constexpr int operator()( int x1, int x2 ) &&
|
||||
{
|
||||
return 100*x1 + 10*x2 + 3;
|
||||
}
|
||||
constexpr int operator()( int x1, int x2 ) const &&
|
||||
{
|
||||
return 100*x1 + 10*x2 + 4;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( F1() )(), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( F1() )( 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( F1() )( 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( F1() )( 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( F1(), 1 )(), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( F1(), 1 )( 2 ), 21 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( F1(), 1 )( 2, 3 ), 231 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( F1(), 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( F1(), 1, 2 )( 3 ), 312 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( F1(), 1, 2, 3 )(), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( F2(), 9 )( 8 ), 893 );
|
||||
}
|
||||
|
||||
{
|
||||
constexpr auto fn = boost::compat::bind_back( F2(), 9 );
|
||||
BOOST_TEST_EQ( fn( 8 ), 892 );
|
||||
}
|
||||
|
||||
{
|
||||
constexpr auto fn = boost::compat::bind_back( F2(), 9 );
|
||||
BOOST_TEST_EQ( std::move( fn )( 8 ), 894 );
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
101
test/bind_back_obj_test.cpp
Normal file
101
test/bind_back_obj_test.cpp
Normal file
@@ -0,0 +1,101 @@
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/compat/bind_back.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/config/workaround.hpp>
|
||||
|
||||
struct F1
|
||||
{
|
||||
int operator()()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int operator()( int x1 ) noexcept
|
||||
{
|
||||
return x1;
|
||||
}
|
||||
|
||||
int operator()( int x1, int x2 ) const
|
||||
{
|
||||
return 10*x1+x2;
|
||||
}
|
||||
|
||||
int operator()( int x1, int x2, int x3 ) const noexcept
|
||||
{
|
||||
return 100*x1 + 10*x2 + x3;
|
||||
}
|
||||
};
|
||||
|
||||
struct F2
|
||||
{
|
||||
int operator()( int x1, int x2 ) &
|
||||
{
|
||||
return 100*x1 + 10*x2 + 1;
|
||||
}
|
||||
|
||||
int operator()( int x1, int x2 ) const &
|
||||
{
|
||||
return 100*x1 + 10*x2 + 2;
|
||||
}
|
||||
int operator()( int x1, int x2 ) &&
|
||||
{
|
||||
return 100*x1 + 10*x2 + 3;
|
||||
}
|
||||
int operator()( int x1, int x2 ) const &&
|
||||
{
|
||||
return 100*x1 + 10*x2 + 4;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( F1() )(), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( F1() )( 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( F1() )( 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( F1() )( 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( F1(), 1 )(), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( F1(), 1 )( 2 ), 21 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( F1(), 1 )( 2, 3 ), 231 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( F1(), 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( F1(), 1, 2 )( 3 ), 312 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( F1(), 1, 2, 3 )(), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::bind_back( F2(), 9 )( 8 ), 893 );
|
||||
}
|
||||
|
||||
{
|
||||
auto fn = boost::compat::bind_back( F2(), 9 );
|
||||
BOOST_TEST_EQ( fn( 8 ), 891 );
|
||||
}
|
||||
|
||||
{
|
||||
auto const fn = boost::compat::bind_back( F2(), 9 );
|
||||
BOOST_TEST_EQ( fn( 8 ), 892 );
|
||||
}
|
||||
|
||||
{
|
||||
auto fn = boost::compat::bind_back( F2(), 9 );
|
||||
BOOST_TEST_EQ( std::move( fn )( 8 ), 893 );
|
||||
}
|
||||
|
||||
#if !BOOST_WORKAROUND(BOOST_GCC, < 40900)
|
||||
|
||||
{
|
||||
auto const fn = boost::compat::bind_back( F2(), 9 );
|
||||
BOOST_TEST_EQ( std::move( fn )( 8 ), 894 );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
60
test/bind_front_fn_constexpr_test.cpp
Normal file
60
test/bind_front_fn_constexpr_test.cpp
Normal file
@@ -0,0 +1,60 @@
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ == 7
|
||||
# pragma GCC diagnostic ignored "-Wnoexcept-type"
|
||||
#endif
|
||||
|
||||
#include <boost/compat/bind_front.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/config/pragma_message.hpp>
|
||||
|
||||
#if defined(BOOST_NO_CXX14_CONSTEXPR)
|
||||
|
||||
BOOST_PRAGMA_MESSAGE( "Test skipped because BOOST_NO_CXX14_CONSTEXPR is defined" )
|
||||
int main() {}
|
||||
|
||||
#else
|
||||
|
||||
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
|
||||
#define BOOST_TEST_EQ(x, y) STATIC_ASSERT((x) == (y))
|
||||
|
||||
constexpr int f0()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
constexpr int f1( int x1 ) noexcept
|
||||
{
|
||||
return x1;
|
||||
}
|
||||
|
||||
constexpr int f2( int x1, int x2 )
|
||||
{
|
||||
return 10*x1+x2;
|
||||
}
|
||||
|
||||
constexpr int f3( int x1, int x2, int x3 ) noexcept
|
||||
{
|
||||
return 100*x1 + 10*x2 + x3;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( f0 )(), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( f1 )( 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( f2 )( 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( f3 )( 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( f1, 1 )(), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( f2, 1 )( 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( f3, 1 )( 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( f2, 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( f3, 1, 2 )( 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( f3, 1, 2, 3 )(), 123 );
|
||||
}
|
||||
|
||||
#endif
|
||||
57
test/bind_front_fn_test.cpp
Normal file
57
test/bind_front_fn_test.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ == 7
|
||||
# pragma GCC diagnostic ignored "-Wnoexcept-type"
|
||||
#endif
|
||||
|
||||
#include <boost/compat/bind_front.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <memory>
|
||||
|
||||
int f0()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int f1( int x1 ) noexcept
|
||||
{
|
||||
return x1;
|
||||
}
|
||||
|
||||
int f2( int x1, int x2 )
|
||||
{
|
||||
return 10*x1+x2;
|
||||
}
|
||||
|
||||
int f3( int x1, int x2, int x3 ) noexcept
|
||||
{
|
||||
return 100*x1 + 10*x2 + x3;
|
||||
}
|
||||
|
||||
int g( std::unique_ptr<int> p, std::unique_ptr<int> q )
|
||||
{
|
||||
return 10 * *p + *q;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( f0 )(), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( f1 )( 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( f2 )( 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( f3 )( 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( f1, 1 )(), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( f2, 1 )( 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( f3, 1 )( 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( f2, 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( f3, 1, 2 )( 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( f3, 1, 2, 3 )(), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( g, std::unique_ptr<int>( new int(1) ) )( std::unique_ptr<int>( new int(2) ) ), 12 );
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
58
test/bind_front_md_constexpr_test.cpp
Normal file
58
test/bind_front_md_constexpr_test.cpp
Normal file
@@ -0,0 +1,58 @@
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/compat/bind_front.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/config/workaround.hpp>
|
||||
#include <boost/config/pragma_message.hpp>
|
||||
|
||||
#if defined(BOOST_NO_CXX14_CONSTEXPR)
|
||||
|
||||
BOOST_PRAGMA_MESSAGE( "Test skipped because BOOST_NO_CXX14_CONSTEXPR is defined" )
|
||||
int main() {}
|
||||
|
||||
#else
|
||||
|
||||
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
|
||||
#define BOOST_TEST_EQ(x, y) STATIC_ASSERT((x) == (y))
|
||||
|
||||
struct X
|
||||
{
|
||||
int m = -1;
|
||||
};
|
||||
|
||||
struct Y: public X
|
||||
{
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::m, X() )(), -1 );
|
||||
}
|
||||
|
||||
{
|
||||
constexpr X x = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::m, x )(), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::m, &x )(), -1 );
|
||||
}
|
||||
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, >= 1920 && BOOST_MSVC < 1950)
|
||||
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::m, Y() )(), -1 );
|
||||
}
|
||||
|
||||
{
|
||||
constexpr Y y = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::m, y )(), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::m, &y )(), -1 );
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
101
test/bind_front_md_test.cpp
Normal file
101
test/bind_front_md_test.cpp
Normal file
@@ -0,0 +1,101 @@
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/compat/bind_front.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <functional>
|
||||
|
||||
struct X
|
||||
{
|
||||
int m = -1;
|
||||
};
|
||||
|
||||
struct Y: public virtual X
|
||||
{
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::m, X() )(), -1 );
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::m, Y() )(), -1 );
|
||||
}
|
||||
|
||||
{
|
||||
X x;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::m, x )(), -1 );
|
||||
}
|
||||
|
||||
{
|
||||
X x;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::m, &x )(), -1 );
|
||||
boost::compat::bind_front( &X::m, &x )() = +1;
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::m, &x )(), +1 );
|
||||
}
|
||||
|
||||
{
|
||||
X x;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::m, std::ref(x) )(), -1 );
|
||||
boost::compat::bind_front( &X::m, std::ref(x) )() = +1;
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::m, std::ref(x) )(), +1 );
|
||||
}
|
||||
|
||||
{
|
||||
X x;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::m, std::cref(x) )(), -1 );
|
||||
}
|
||||
|
||||
{
|
||||
Y y;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::m, y )(), -1 );
|
||||
}
|
||||
|
||||
{
|
||||
Y y;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::m, &y )(), -1 );
|
||||
boost::compat::bind_front( &X::m, &y )() = +1;
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::m, &y )(), +1 );
|
||||
}
|
||||
|
||||
{
|
||||
Y y;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::m, std::ref(y) )(), -1 );
|
||||
boost::compat::bind_front( &X::m, std::ref(y) )() = +1;
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::m, std::ref(y) )(), +1 );
|
||||
}
|
||||
|
||||
{
|
||||
Y y;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::m, std::cref(y) )(), -1 );
|
||||
}
|
||||
|
||||
{
|
||||
X const x = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::m, x )(), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::m, &x )(), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::m, std::ref(x) )(), -1 );
|
||||
}
|
||||
|
||||
{
|
||||
Y const y = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::m, y )(), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::m, &y )(), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::m, std::ref(y) )(), -1 );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
167
test/bind_front_mfn_constexpr_test.cpp
Normal file
167
test/bind_front_mfn_constexpr_test.cpp
Normal file
@@ -0,0 +1,167 @@
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ == 7
|
||||
# pragma GCC diagnostic ignored "-Wnoexcept-type"
|
||||
#endif
|
||||
|
||||
#include <boost/compat/bind_front.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/config/pragma_message.hpp>
|
||||
|
||||
#if defined(BOOST_NO_CXX14_CONSTEXPR)
|
||||
|
||||
BOOST_PRAGMA_MESSAGE( "Test skipped because BOOST_NO_CXX14_CONSTEXPR is defined" )
|
||||
int main() {}
|
||||
|
||||
#else
|
||||
|
||||
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
|
||||
#define BOOST_TEST_EQ(x, y) STATIC_ASSERT((x) == (y))
|
||||
|
||||
struct X
|
||||
{
|
||||
constexpr int f0()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
constexpr int f1( int x1 ) noexcept
|
||||
{
|
||||
return x1;
|
||||
}
|
||||
|
||||
constexpr int f2( int x1, int x2 ) const
|
||||
{
|
||||
return 10*x1+x2;
|
||||
}
|
||||
|
||||
constexpr int f3( int x1, int x2, int x3 ) const noexcept
|
||||
{
|
||||
return 100*x1 + 10*x2 + x3;
|
||||
}
|
||||
};
|
||||
|
||||
struct Y: public X
|
||||
{
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f0 )( X() ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f1 )( X(), 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2 )( X(), 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3 )( X(), 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f0, X() )(), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f1, X() )( 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, X() )( 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, X() )( 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f1, X(), 1 )(), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, X(), 1 )( 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, X(), 1 )( 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, X(), 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, X(), 1, 2 )( 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, X(), 1, 2, 3 )(), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f0, Y() )(), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f1, Y() )( 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, Y() )( 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, Y() )( 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f0, Y() )(), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f1, Y() )( 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, Y() )( 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, Y() )( 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f1, Y(), 1 )(), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, Y(), 1 )( 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, Y(), 1 )( 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, Y(), 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, Y(), 1, 2 )( 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, Y(), 1, 2, 3 )(), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
constexpr X x = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2 )( x, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3 )( x, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, x )( 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, x )( 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, x, 1 )( 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, x, 1 )( 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, x, 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, x, 1, 2 )( 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, x, 1, 2, 3 )(), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
constexpr X x = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2 )( &x, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3 )( &x, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, &x )( 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, &x )( 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, &x, 1 )( 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, &x, 1 )( 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, &x, 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, &x, 1, 2 )( 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, &x, 1, 2, 3 )(), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
constexpr Y x = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2 )( x, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3 )( x, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, x )( 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, x )( 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, x, 1 )( 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, x, 1 )( 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, x, 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, x, 1, 2 )( 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, x, 1, 2, 3 )(), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
constexpr Y x = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2 )( &x, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3 )( &x, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, &x )( 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, &x )( 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, &x, 1 )( 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, &x, 1 )( 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, &x, 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, &x, 1, 2 )( 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, &x, 1, 2, 3 )(), 123 );
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
378
test/bind_front_mfn_test.cpp
Normal file
378
test/bind_front_mfn_test.cpp
Normal file
@@ -0,0 +1,378 @@
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ == 7
|
||||
# pragma GCC diagnostic ignored "-Wnoexcept-type"
|
||||
#endif
|
||||
|
||||
#include <boost/compat/bind_front.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
struct X
|
||||
{
|
||||
int f0()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int f1( int x1 ) noexcept
|
||||
{
|
||||
return x1;
|
||||
}
|
||||
|
||||
int f2( int x1, int x2 ) const
|
||||
{
|
||||
return 10*x1+x2;
|
||||
}
|
||||
|
||||
int f3( int x1, int x2, int x3 ) const noexcept
|
||||
{
|
||||
return 100*x1 + 10*x2 + x3;
|
||||
}
|
||||
};
|
||||
|
||||
struct Y: public virtual X
|
||||
{
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f0 )( X() ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f1 )( X(), 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2 )( X(), 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3 )( X(), 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f0, X() )(), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f1, X() )( 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, X() )( 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, X() )( 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f1, X(), 1 )(), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, X(), 1 )( 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, X(), 1 )( 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, X(), 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, X(), 1, 2 )( 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, X(), 1, 2, 3 )(), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f0, Y() )(), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f1, Y() )( 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, Y() )( 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, Y() )( 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f0, Y() )(), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f1, Y() )( 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, Y() )( 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, Y() )( 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f1, Y(), 1 )(), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, Y(), 1 )( 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, Y(), 1 )( 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, Y(), 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, Y(), 1, 2 )( 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, Y(), 1, 2, 3 )(), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
X x;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f0 )( x ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f1 )( x, 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2 )( x, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3 )( x, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f0, x )(), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f1, x )( 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, x )( 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, x )( 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f1, x, 1 )(), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, x, 1 )( 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, x, 1 )( 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, x, 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, x, 1, 2 )( 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, x, 1, 2, 3 )(), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
X x;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f0 )( &x ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f1 )( &x, 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2 )( &x, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3 )( &x, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f0, &x )(), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f1, &x )( 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, &x )( 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, &x )( 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f1, &x, 1 )(), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, &x, 1 )( 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, &x, 1 )( 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, &x, 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, &x, 1, 2 )( 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, &x, 1, 2, 3 )(), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
X x;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f0 )( std::ref(x) ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f1 )( std::ref(x), 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2 )( std::ref(x), 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3 )( std::ref(x), 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f0, std::ref(x) )(), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f1, std::ref(x) )( 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, std::ref(x) )( 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, std::ref(x) )( 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f1, std::ref(x), 1 )(), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, std::ref(x), 1 )( 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, std::ref(x), 1 )( 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, std::ref(x), 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, std::ref(x), 1, 2 )( 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, std::ref(x), 1, 2, 3 )(), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
X x;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2 )( std::cref(x), 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3 )( std::cref(x), 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, std::cref(x) )( 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, std::cref(x) )( 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, std::cref(x), 1 )( 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, std::cref(x), 1 )( 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, std::cref(x), 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, std::cref(x), 1, 2 )( 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, std::cref(x), 1, 2, 3 )(), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
Y x;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f0 )( x ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f1 )( x, 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2 )( x, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3 )( x, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f0, x )(), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f1, x )( 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, x )( 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, x )( 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f1, x, 1 )(), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, x, 1 )( 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, x, 1 )( 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, x, 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, x, 1, 2 )( 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, x, 1, 2, 3 )(), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
Y x;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f0 )( &x ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f1 )( &x, 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2 )( &x, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3 )( &x, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f0, &x )(), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f1, &x )( 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, &x )( 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, &x )( 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f1, &x, 1 )(), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, &x, 1 )( 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, &x, 1 )( 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, &x, 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, &x, 1, 2 )( 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, &x, 1, 2, 3 )(), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
Y x;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f0 )( std::ref(x) ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f1 )( std::ref(x), 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2 )( std::ref(x), 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3 )( std::ref(x), 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f0, std::ref(x) )(), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f1, std::ref(x) )( 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, std::ref(x) )( 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, std::ref(x) )( 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f1, std::ref(x), 1 )(), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, std::ref(x), 1 )( 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, std::ref(x), 1 )( 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, std::ref(x), 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, std::ref(x), 1, 2 )( 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, std::ref(x), 1, 2, 3 )(), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
Y x;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2 )( std::cref(x), 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3 )( std::cref(x), 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, std::cref(x) )( 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, std::cref(x) )( 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, std::cref(x), 1 )( 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, std::cref(x), 1 )( 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, std::cref(x), 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, std::cref(x), 1, 2 )( 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, std::cref(x), 1, 2, 3 )(), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
X const x = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2 )( x, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3 )( x, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, x )( 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, x )( 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, x, 1 )( 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, x, 1 )( 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, x, 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, x, 1, 2 )( 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, x, 1, 2, 3 )(), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
X const x = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2 )( &x, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3 )( &x, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, &x )( 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, &x )( 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, &x, 1 )( 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, &x, 1 )( 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, &x, 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, &x, 1, 2 )( 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, &x, 1, 2, 3 )(), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
X const x = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2 )( std::ref(x), 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3 )( std::ref(x), 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, std::ref(x) )( 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, std::ref(x) )( 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, std::ref(x), 1 )( 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, std::ref(x), 1 )( 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, std::ref(x), 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, std::ref(x), 1, 2 )( 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, std::ref(x), 1, 2, 3 )(), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
Y const x = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2 )( x, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3 )( x, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, x )( 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, x )( 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, x, 1 )( 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, x, 1 )( 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, x, 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, x, 1, 2 )( 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, x, 1, 2, 3 )(), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
Y const x = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2 )( &x, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3 )( &x, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, &x )( 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, &x )( 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, &x, 1 )( 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, &x, 1 )( 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, &x, 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, &x, 1, 2 )( 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, &x, 1, 2, 3 )(), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
Y const x = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2 )( std::ref(x), 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3 )( std::ref(x), 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, std::ref(x) )( 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, std::ref(x) )( 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, std::ref(x), 1 )( 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, std::ref(x), 1 )( 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f2, std::ref(x), 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, std::ref(x), 1, 2 )( 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, std::ref(x), 1, 2, 3 )(), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
std::unique_ptr<X> px( new X );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, std::move(px), 1 )( 2, 3 ), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
std::unique_ptr<Y> px( new Y );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( &X::f3, std::move(px), 1 )( 2, 3 ), 123 );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
96
test/bind_front_obj_constexpr_test.cpp
Normal file
96
test/bind_front_obj_constexpr_test.cpp
Normal file
@@ -0,0 +1,96 @@
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/compat/bind_front.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/config/pragma_message.hpp>
|
||||
|
||||
#if defined(BOOST_NO_CXX14_CONSTEXPR)
|
||||
|
||||
BOOST_PRAGMA_MESSAGE( "Test skipped because BOOST_NO_CXX14_CONSTEXPR is defined" )
|
||||
int main() {}
|
||||
|
||||
#else
|
||||
|
||||
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
|
||||
#define BOOST_TEST_EQ(x, y) STATIC_ASSERT((x) == (y))
|
||||
|
||||
struct F1
|
||||
{
|
||||
constexpr int operator()()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
constexpr int operator()( int x1 ) noexcept
|
||||
{
|
||||
return x1;
|
||||
}
|
||||
|
||||
constexpr int operator()( int x1, int x2 ) const
|
||||
{
|
||||
return 10*x1+x2;
|
||||
}
|
||||
|
||||
constexpr int operator()( int x1, int x2, int x3 ) const noexcept
|
||||
{
|
||||
return 100*x1 + 10*x2 + x3;
|
||||
}
|
||||
};
|
||||
|
||||
struct F2
|
||||
{
|
||||
constexpr int operator()( int x1, int x2 ) &
|
||||
{
|
||||
return 100*x1 + 10*x2 + 1;
|
||||
}
|
||||
|
||||
constexpr int operator()( int x1, int x2 ) const &
|
||||
{
|
||||
return 100*x1 + 10*x2 + 2;
|
||||
}
|
||||
constexpr int operator()( int x1, int x2 ) &&
|
||||
{
|
||||
return 100*x1 + 10*x2 + 3;
|
||||
}
|
||||
constexpr int operator()( int x1, int x2 ) const &&
|
||||
{
|
||||
return 100*x1 + 10*x2 + 4;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( F1() )(), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( F1() )( 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( F1() )( 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( F1() )( 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( F1(), 1 )(), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( F1(), 1 )( 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( F1(), 1 )( 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( F1(), 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( F1(), 1, 2 )( 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( F1(), 1, 2, 3 )(), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( F2(), 9 )( 8 ), 983 );
|
||||
}
|
||||
|
||||
{
|
||||
constexpr auto fn = boost::compat::bind_front( F2(), 9 );
|
||||
BOOST_TEST_EQ( fn( 8 ), 982 );
|
||||
}
|
||||
|
||||
{
|
||||
constexpr auto fn = boost::compat::bind_front( F2(), 9 );
|
||||
BOOST_TEST_EQ( std::move( fn )( 8 ), 984 );
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
101
test/bind_front_obj_test.cpp
Normal file
101
test/bind_front_obj_test.cpp
Normal file
@@ -0,0 +1,101 @@
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/compat/bind_front.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/config/workaround.hpp>
|
||||
|
||||
struct F1
|
||||
{
|
||||
int operator()()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int operator()( int x1 ) noexcept
|
||||
{
|
||||
return x1;
|
||||
}
|
||||
|
||||
int operator()( int x1, int x2 ) const
|
||||
{
|
||||
return 10*x1+x2;
|
||||
}
|
||||
|
||||
int operator()( int x1, int x2, int x3 ) const noexcept
|
||||
{
|
||||
return 100*x1 + 10*x2 + x3;
|
||||
}
|
||||
};
|
||||
|
||||
struct F2
|
||||
{
|
||||
int operator()( int x1, int x2 ) &
|
||||
{
|
||||
return 100*x1 + 10*x2 + 1;
|
||||
}
|
||||
|
||||
int operator()( int x1, int x2 ) const &
|
||||
{
|
||||
return 100*x1 + 10*x2 + 2;
|
||||
}
|
||||
int operator()( int x1, int x2 ) &&
|
||||
{
|
||||
return 100*x1 + 10*x2 + 3;
|
||||
}
|
||||
int operator()( int x1, int x2 ) const &&
|
||||
{
|
||||
return 100*x1 + 10*x2 + 4;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( F1() )(), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( F1() )( 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( F1() )( 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( F1() )( 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( F1(), 1 )(), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( F1(), 1 )( 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( F1(), 1 )( 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( F1(), 1, 2 )(), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( F1(), 1, 2 )( 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( F1(), 1, 2, 3 )(), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::bind_front( F2(), 9 )( 8 ), 983 );
|
||||
}
|
||||
|
||||
{
|
||||
auto fn = boost::compat::bind_front( F2(), 9 );
|
||||
BOOST_TEST_EQ( fn( 8 ), 981 );
|
||||
}
|
||||
|
||||
{
|
||||
auto const fn = boost::compat::bind_front( F2(), 9 );
|
||||
BOOST_TEST_EQ( fn( 8 ), 982 );
|
||||
}
|
||||
|
||||
{
|
||||
auto fn = boost::compat::bind_front( F2(), 9 );
|
||||
BOOST_TEST_EQ( std::move( fn )( 8 ), 983 );
|
||||
}
|
||||
|
||||
#if !BOOST_WORKAROUND(BOOST_GCC, < 40900)
|
||||
|
||||
{
|
||||
auto const fn = boost::compat::bind_front( F2(), 9 );
|
||||
BOOST_TEST_EQ( std::move( fn )( 8 ), 984 );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
@@ -14,4 +14,4 @@ target_link_libraries(quick Boost::compat)
|
||||
enable_testing()
|
||||
add_test(quick quick)
|
||||
|
||||
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -C $<CONFIG>)
|
||||
add_custom_target(check VERBATIM COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -C $<CONFIG>)
|
||||
|
||||
@@ -18,4 +18,4 @@ target_link_libraries(quick Boost::compat)
|
||||
enable_testing()
|
||||
add_test(quick quick)
|
||||
|
||||
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -C $<CONFIG>)
|
||||
add_custom_target(check VERBATIM COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -C $<CONFIG>)
|
||||
|
||||
165
test/function_ref_fn_noexcept_test.cpp
Normal file
165
test/function_ref_fn_noexcept_test.cpp
Normal file
@@ -0,0 +1,165 @@
|
||||
// Copyright 2024 Christian Mazakas
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/config/pragma_message.hpp>
|
||||
|
||||
#if !defined(__cpp_noexcept_function_type)
|
||||
|
||||
BOOST_PRAGMA_MESSAGE("Test skipped, __cpp_noexcept_function_type is not defined")
|
||||
int main() {}
|
||||
|
||||
#else
|
||||
|
||||
#include <boost/compat/function_ref.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/core/lightweight_test_trait.hpp>
|
||||
|
||||
int f0() { return -1; }
|
||||
|
||||
int f1(int x1) noexcept { return x1; }
|
||||
int g1(int x1) noexcept { return x1 * 2; }
|
||||
|
||||
int f2(int x1, int x2) { return 10 * x1 + x2; }
|
||||
|
||||
int f3(int x1, int x2, int x3) noexcept { return 100 * x1 + 10 * x2 + x3; }
|
||||
|
||||
int g(std::unique_ptr<int> p, std::unique_ptr<int> q) { return 10 * *p + *q; }
|
||||
|
||||
struct X {
|
||||
int v = 0;
|
||||
|
||||
X() = default;
|
||||
X(int v_) noexcept : v{v_} {}
|
||||
};
|
||||
|
||||
struct Y {
|
||||
int v = 0;
|
||||
|
||||
Y() = default;
|
||||
explicit Y(int v_) : v{v_} {}
|
||||
};
|
||||
|
||||
struct Z {
|
||||
int v = 0;
|
||||
|
||||
Z() = default;
|
||||
Z(int v_) : v{v_} {}
|
||||
};
|
||||
|
||||
namespace compat = boost::compat;
|
||||
|
||||
int main() {
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_trivially_copyable<compat::function_ref<int() noexcept>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_trivially_copyable<compat::function_ref<int() const noexcept>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_trivially_copyable<compat::function_ref<int(int) noexcept>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_trivially_copyable<compat::function_ref<int(int) const noexcept>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_trivially_copyable<compat::function_ref<int(int, int) noexcept>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_trivially_copyable<compat::function_ref<int(int, int) const noexcept>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_trivially_copyable<compat::function_ref<int(int, int, int) noexcept>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_trivially_copyable<compat::function_ref<int(int, int, int) const noexcept>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_trivially_copyable<compat::function_ref<X(int, int, int) noexcept>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_trivially_copyable<compat::function_ref<X(int, int, int) const noexcept>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_trivially_copyable<compat::function_ref<void(int, int, int) noexcept>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_trivially_copyable<compat::function_ref<void(int, int, int) const noexcept>>));
|
||||
|
||||
struct W {
|
||||
int w_;
|
||||
};
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_assignable<compat::function_ref<int() noexcept>, W>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_assignable<compat::function_ref<int() const noexcept>, W>));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_assignable<compat::function_ref<int() noexcept>, compat::function_ref<int()>>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_assignable<compat::function_ref<int()>, compat::function_ref<int() noexcept>>));
|
||||
BOOST_TEST_TRAIT_FALSE(
|
||||
(std::is_assignable<compat::function_ref<int() const noexcept>, compat::function_ref<int() const>>));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(
|
||||
(std::is_assignable<compat::function_ref<int() noexcept>, compat::function_ref<int(int) noexcept>>));
|
||||
BOOST_TEST_TRAIT_FALSE(
|
||||
(std::is_assignable<compat::function_ref<int(int) noexcept>, compat::function_ref<int() noexcept>>));
|
||||
|
||||
// f0
|
||||
{
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<int() noexcept>, decltype(f0)>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<int() const noexcept>, decltype(f0)>));
|
||||
}
|
||||
|
||||
// f1
|
||||
{
|
||||
compat::function_ref<int(int) noexcept> fv1(f1);
|
||||
BOOST_TEST_EQ(fv1(1), 1);
|
||||
|
||||
compat::function_ref<int(int) const noexcept> fv2(f1);
|
||||
BOOST_TEST_EQ(fv2(1), 1);
|
||||
}
|
||||
|
||||
// f2
|
||||
{
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<int(int, int) noexcept>, decltype(f2)>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<int(int, int) const noexcept>, decltype(f2)>));
|
||||
}
|
||||
|
||||
// f3
|
||||
{
|
||||
compat::function_ref<int(int, int, int) noexcept> fv1(f3);
|
||||
BOOST_TEST_EQ(fv1(1, 2, 3), 123);
|
||||
|
||||
compat::function_ref<int(int, int, int) const noexcept> fv2(f3);
|
||||
BOOST_TEST_EQ(fv2(1, 2, 3), 123);
|
||||
}
|
||||
|
||||
// g
|
||||
{
|
||||
BOOST_TEST_TRAIT_FALSE(
|
||||
(std::is_constructible<compat::function_ref<int(std::unique_ptr<int>, std::unique_ptr<int>) noexcept>,
|
||||
decltype(g)>));
|
||||
BOOST_TEST_TRAIT_FALSE(
|
||||
(std::is_constructible<compat::function_ref<int(std::unique_ptr<int>, std::unique_ptr<int>) const noexcept>,
|
||||
decltype(g)>));
|
||||
}
|
||||
|
||||
// invoke_r
|
||||
{
|
||||
compat::function_ref<X(int, int, int) noexcept> fv1(f3);
|
||||
BOOST_TEST_EQ(fv1(1, 2, 3).v, 123);
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<Y(int, int, int) noexcept>, decltype(f3)>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<Z(int, int, int) noexcept>, decltype(f3)>));
|
||||
|
||||
compat::function_ref<X(int, int, int) const noexcept> fv2(f3);
|
||||
BOOST_TEST_EQ(fv2(1, 2, 3).v, 123);
|
||||
BOOST_TEST_TRAIT_FALSE(
|
||||
(std::is_constructible<compat::function_ref<Y(int, int, int) const noexcept>, decltype(f3)>));
|
||||
BOOST_TEST_TRAIT_FALSE(
|
||||
(std::is_constructible<compat::function_ref<Z(int, int, int) const noexcept>, decltype(f3)>));
|
||||
|
||||
compat::function_ref<void(int, int, int) noexcept> fv3(f3);
|
||||
fv3(1, 2, 3);
|
||||
|
||||
compat::function_ref<void(int, int, int) const noexcept> fv4(f3);
|
||||
fv4(1, 2, 3);
|
||||
}
|
||||
|
||||
// copy construct, copy assign
|
||||
{
|
||||
compat::function_ref<int(int) noexcept> fv(f1);
|
||||
compat::function_ref<int(int) noexcept> fv2(fv);
|
||||
BOOST_TEST_EQ(fv(42), fv2(42));
|
||||
|
||||
fv2 = g1;
|
||||
BOOST_TEST_EQ(fv2(12), 24);
|
||||
|
||||
compat::function_ref<int(int) const noexcept> cfv(f1);
|
||||
compat::function_ref<int(int) const noexcept> cfv2(cfv);
|
||||
BOOST_TEST_EQ(cfv(42), cfv2(42));
|
||||
|
||||
cfv2 = g1;
|
||||
BOOST_TEST_EQ(cfv2(24), 48);
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
#endif
|
||||
183
test/function_ref_fn_test.cpp
Normal file
183
test/function_ref_fn_test.cpp
Normal file
@@ -0,0 +1,183 @@
|
||||
// Copyright 2024 Christian Mazakas
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ == 7
|
||||
#pragma GCC diagnostic ignored "-Wnoexcept-type"
|
||||
#endif
|
||||
|
||||
#include <boost/compat/function_ref.hpp>
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/config/pragma_message.hpp>
|
||||
#include <boost/config/workaround.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/core/lightweight_test_trait.hpp>
|
||||
|
||||
int f0() { return -1; }
|
||||
int g0() { return 7331; }
|
||||
|
||||
int f1(int x1) noexcept { return x1; }
|
||||
|
||||
int f2(int x1, int x2) { return 10 * x1 + x2; }
|
||||
|
||||
int f3(int x1, int x2, int x3) noexcept { return 100 * x1 + 10 * x2 + x3; }
|
||||
|
||||
int g(std::unique_ptr<int> p, std::unique_ptr<int> q) { return 10 * *p + *q; }
|
||||
|
||||
struct X {
|
||||
int v = 0;
|
||||
|
||||
X() = default;
|
||||
X(int v_) noexcept : v{v_} {}
|
||||
};
|
||||
|
||||
struct Y {
|
||||
int v = 0;
|
||||
|
||||
Y() = default;
|
||||
explicit Y(int v_) : v{v_} {}
|
||||
};
|
||||
|
||||
struct Z {
|
||||
int v = 0;
|
||||
|
||||
Z() = default;
|
||||
Z(int v_) : v{v_} {}
|
||||
};
|
||||
|
||||
namespace compat = boost::compat;
|
||||
|
||||
int main() {
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS)
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_trivially_copyable<compat::function_ref<int()>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_trivially_copyable<compat::function_ref<int() const>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_trivially_copyable<compat::function_ref<int(int)>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_trivially_copyable<compat::function_ref<int(int) const>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_trivially_copyable<compat::function_ref<int(int, int)>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_trivially_copyable<compat::function_ref<int(int, int) const>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_trivially_copyable<compat::function_ref<int(int, int, int)>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_trivially_copyable<compat::function_ref<int(int, int, int) const>>));
|
||||
BOOST_TEST_TRAIT_TRUE(
|
||||
(std::is_trivially_copyable<compat::function_ref<int(std::unique_ptr<int>, std::unique_ptr<int>)>>));
|
||||
BOOST_TEST_TRAIT_TRUE(
|
||||
(std::is_trivially_copyable<compat::function_ref<int(std::unique_ptr<int>, std::unique_ptr<int>) const>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_trivially_copyable<compat::function_ref<X(int, int, int)>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_trivially_copyable<compat::function_ref<X(int, int, int) const>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_trivially_copyable<compat::function_ref<void(int, int, int)>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_trivially_copyable<compat::function_ref<void(int, int, int) const>>));
|
||||
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1910)
|
||||
struct W {
|
||||
int w_;
|
||||
};
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_assignable<compat::function_ref<int()>, W>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_assignable<compat::function_ref<int() const>, W>));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_assignable<compat::function_ref<int()>, compat::function_ref<int() const>>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_assignable<compat::function_ref<int() const>, compat::function_ref<int()>>));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_assignable<compat::function_ref<int()>, compat::function_ref<int(int)>>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_assignable<compat::function_ref<int(int)>, compat::function_ref<int()>>));
|
||||
#endif
|
||||
|
||||
#else
|
||||
BOOST_PRAGMA_MESSAGE("<type_traits> is incomplete, skipping is_trivially_copyable checks")
|
||||
#endif
|
||||
|
||||
// f0
|
||||
{
|
||||
compat::function_ref<int()> fv1(f0);
|
||||
BOOST_TEST_EQ(fv1(), -1);
|
||||
|
||||
compat::function_ref<int() const> fv2(f0);
|
||||
BOOST_TEST_EQ(fv2(), -1);
|
||||
}
|
||||
|
||||
// f1
|
||||
{
|
||||
compat::function_ref<int(int)> fv1(f1);
|
||||
BOOST_TEST_EQ(fv1(1), 1);
|
||||
|
||||
compat::function_ref<int(int) const> fv2(f1);
|
||||
BOOST_TEST_EQ(fv2(1), 1);
|
||||
}
|
||||
|
||||
// f2
|
||||
{
|
||||
compat::function_ref<int(int, int)> fv1(f2);
|
||||
BOOST_TEST_EQ(fv1(1, 2), 12);
|
||||
|
||||
compat::function_ref<int(int, int) const> fv2(f2);
|
||||
BOOST_TEST_EQ(fv2(1, 2), 12);
|
||||
}
|
||||
|
||||
// f3
|
||||
{
|
||||
compat::function_ref<int(int, int, int)> fv1(f3);
|
||||
BOOST_TEST_EQ(fv1(1, 2, 3), 123);
|
||||
|
||||
compat::function_ref<int(int, int, int) const> fv2(f3);
|
||||
BOOST_TEST_EQ(fv2(1, 2, 3), 123);
|
||||
}
|
||||
|
||||
// g
|
||||
{
|
||||
using S1 = int(std::unique_ptr<int>, std::unique_ptr<int>);
|
||||
using S2 = int(std::unique_ptr<int>, std::unique_ptr<int>) const;
|
||||
|
||||
compat::function_ref<S1> fv1(g);
|
||||
{
|
||||
auto p = std::unique_ptr<int>(new int{1});
|
||||
auto q = std::unique_ptr<int>(new int{2});
|
||||
BOOST_TEST_EQ(fv1(std::move(p), std::move(q)), 12);
|
||||
}
|
||||
|
||||
compat::function_ref<S2> fv2(g);
|
||||
{
|
||||
auto p = std::unique_ptr<int>(new int{130});
|
||||
auto q = std::unique_ptr<int>(new int{37});
|
||||
BOOST_TEST_EQ(fv1(std::move(p), std::move(q)), 1337);
|
||||
}
|
||||
}
|
||||
|
||||
// invoke_r
|
||||
{
|
||||
compat::function_ref<X(int, int, int)> fv1(f3);
|
||||
BOOST_TEST_EQ(fv1(1, 2, 3).v, 123);
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<Y(int, int, int)>, decltype(f3)>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_constructible<compat::function_ref<Z(int, int, int)>, decltype(f3)>));
|
||||
|
||||
compat::function_ref<X(int, int, int) const> fv2(f3);
|
||||
BOOST_TEST_EQ(fv2(1, 2, 3).v, 123);
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<Y(int, int, int) const>, decltype(f3)>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_constructible<compat::function_ref<Z(int, int, int) const>, decltype(f3)>));
|
||||
|
||||
compat::function_ref<void(int, int, int)> fv3(f3);
|
||||
fv3(1, 2, 3);
|
||||
|
||||
compat::function_ref<void(int, int, int) const> fv4(f3);
|
||||
fv4(1, 2, 3);
|
||||
}
|
||||
|
||||
// copy construct, copy assign
|
||||
{
|
||||
compat::function_ref<int()> fv(f0);
|
||||
compat::function_ref<int()> fv2(fv);
|
||||
BOOST_TEST_EQ(fv(), fv2());
|
||||
|
||||
fv2 = g0;
|
||||
BOOST_TEST_EQ(fv2(), 7331);
|
||||
|
||||
compat::function_ref<int() const> cfv(f0);
|
||||
compat::function_ref<int() const> cfv2(cfv);
|
||||
BOOST_TEST_EQ(cfv(), cfv2());
|
||||
|
||||
cfv2 = g0;
|
||||
BOOST_TEST_EQ(cfv2(), 7331);
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
164
test/function_ref_mfn_noexcept_test.cpp
Normal file
164
test/function_ref_mfn_noexcept_test.cpp
Normal file
@@ -0,0 +1,164 @@
|
||||
// Copyright 2024 Christian Mazakas
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ == 7
|
||||
#pragma GCC diagnostic ignored "-Wnoexcept-type"
|
||||
#endif
|
||||
|
||||
#include <boost/compat/function_ref.hpp>
|
||||
|
||||
#if !defined(BOOST_COMPAT_HAS_AUTO_NTTP)
|
||||
#include <boost/config/pragma_message.hpp>
|
||||
BOOST_PRAGMA_MESSAGE("no support for placeholder NTTPs detected, skipping this test")
|
||||
int main() {}
|
||||
#else
|
||||
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/core/lightweight_test_trait.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
|
||||
struct F1 {
|
||||
std::unique_ptr<int> p_;
|
||||
|
||||
F1() : p_(new int(1)) {}
|
||||
|
||||
int m1() { return *p_ + -1; }
|
||||
int m2(int x1) noexcept { return 10 * *p_ + x1; }
|
||||
int m3(int x1, int x2) const { return 100 * *p_ + 10 * x1 + x2; }
|
||||
int m4(int x1, int x2, int x3) const noexcept { return 1000 * *p_ + 100 * x1 + 10 * x2 + x3; }
|
||||
};
|
||||
|
||||
namespace compat = boost::compat;
|
||||
|
||||
int main() {
|
||||
{
|
||||
BOOST_TEST_TRAIT_FALSE(
|
||||
(std::is_constructible<compat::function_ref<int(F1&) noexcept>, compat::nontype_t<&F1::m1>>));
|
||||
BOOST_TEST_TRAIT_TRUE(
|
||||
(std::is_constructible<compat::function_ref<int(F1&, int) noexcept>, compat::nontype_t<&F1::m2>>));
|
||||
BOOST_TEST_TRAIT_FALSE(
|
||||
(std::is_constructible<compat::function_ref<int(F1&, int, int) noexcept>, compat::nontype_t<&F1::m3>>));
|
||||
BOOST_TEST_TRAIT_TRUE(
|
||||
(std::is_constructible<compat::function_ref<int(F1&, int, int, int) noexcept>, compat::nontype_t<&F1::m4>>));
|
||||
}
|
||||
|
||||
{
|
||||
F1 f1;
|
||||
|
||||
compat::function_ref<int(F1&, int) noexcept> fn2(compat::nontype_t<&F1::m2>{});
|
||||
BOOST_TEST_EQ(fn2(f1, 2), 12);
|
||||
|
||||
compat::function_ref<int(F1&, int, int, int) noexcept> fn4(compat::nontype_t<&F1::m4>{});
|
||||
BOOST_TEST_EQ(fn4(f1, 2, 3, 4), 1234);
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST_TRAIT_FALSE(
|
||||
(std::is_constructible<compat::function_ref<int(F1&) const noexcept>, compat::nontype_t<&F1::m1>>));
|
||||
BOOST_TEST_TRAIT_FALSE(
|
||||
(std::is_constructible<compat::function_ref<int(F1&, int, int) const noexcept>, compat::nontype_t<&F1::m3>>));
|
||||
|
||||
F1 f1;
|
||||
|
||||
compat::function_ref<int(F1&, int) const noexcept> fn2(compat::nontype_t<&F1::m2>{});
|
||||
BOOST_TEST_EQ(fn2(f1, 2), 12);
|
||||
|
||||
compat::function_ref<int(F1&, int, int, int) const noexcept> fn4(compat::nontype_t<&F1::m4>{});
|
||||
BOOST_TEST_EQ(fn4(f1, 2, 3, 4), 1234);
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST_TRAIT_FALSE(
|
||||
(std::is_constructible<compat::function_ref<int(F1 const&) noexcept>, compat::nontype_t<&F1::m1>>));
|
||||
BOOST_TEST_TRAIT_FALSE(
|
||||
(std::is_constructible<compat::function_ref<int(F1 const&, int) noexcept>, compat::nontype_t<&F1::m2>>));
|
||||
BOOST_TEST_TRAIT_FALSE(
|
||||
(std::is_constructible<compat::function_ref<int(F1 const&, int, int) noexcept>, compat::nontype_t<&F1::m3>>));
|
||||
|
||||
F1 f1;
|
||||
|
||||
compat::function_ref<int(F1 const&, int, int, int) noexcept> fn4(compat::nontype_t<&F1::m4>{});
|
||||
BOOST_TEST_EQ(fn4(f1, 2, 3, 4), 1234);
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST_TRAIT_FALSE(
|
||||
(std::is_constructible<compat::function_ref<int() noexcept>, compat::nontype_t<&F1::m1>, F1&>));
|
||||
BOOST_TEST_TRAIT_TRUE(
|
||||
(std::is_constructible<compat::function_ref<int(int) noexcept>, compat::nontype_t<&F1::m2>, F1&>));
|
||||
BOOST_TEST_TRAIT_FALSE(
|
||||
(std::is_constructible<compat::function_ref<int(int, int) noexcept>, compat::nontype_t<&F1::m3>, F1&>));
|
||||
BOOST_TEST_TRAIT_TRUE(
|
||||
(std::is_constructible<compat::function_ref<int(int, int, int) noexcept>, compat::nontype_t<&F1::m4>, F1&>));
|
||||
|
||||
F1 f1;
|
||||
|
||||
compat::function_ref<int(int) noexcept> fn2(compat::nontype_t<&F1::m2>{}, f1);
|
||||
BOOST_TEST_EQ(fn2(2), 12);
|
||||
|
||||
compat::function_ref<int(int, int, int) noexcept> fn4(compat::nontype_t<&F1::m4>{}, f1);
|
||||
BOOST_TEST_EQ(fn4(2, 3, 4), 1234);
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST_TRAIT_FALSE(
|
||||
(std::is_constructible<compat::function_ref<int() const noexcept>, compat::nontype_t<&F1::m1>, F1 const&>));
|
||||
BOOST_TEST_TRAIT_FALSE(
|
||||
(std::is_constructible<compat::function_ref<int(int) const noexcept>, compat::nontype_t<&F1::m2>, F1 const&>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<int(int, int) const noexcept>,
|
||||
compat::nontype_t<&F1::m3>, F1 const&>));
|
||||
|
||||
F1 f1;
|
||||
|
||||
compat::function_ref<int(int, int, int) const noexcept> fn4(compat::nontype_t<&F1::m4>{}, f1);
|
||||
BOOST_TEST_EQ(fn4(2, 3, 4), 1234);
|
||||
|
||||
auto const& f1_2 = f1;
|
||||
compat::function_ref<int(int, int, int) const noexcept> fn4_2(compat::nontype_t<&F1::m4>{}, f1_2);
|
||||
BOOST_TEST_EQ(fn4_2(2, 3, 4), 1234);
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST_TRAIT_FALSE(
|
||||
(std::is_constructible<compat::function_ref<int() noexcept>, compat::nontype_t<&F1::m1>, F1*>));
|
||||
BOOST_TEST_TRAIT_TRUE(
|
||||
(std::is_constructible<compat::function_ref<int(int) noexcept>, compat::nontype_t<&F1::m2>, F1*>));
|
||||
BOOST_TEST_TRAIT_FALSE(
|
||||
(std::is_constructible<compat::function_ref<int(int, int) noexcept>, compat::nontype_t<&F1::m3>, F1*>));
|
||||
BOOST_TEST_TRAIT_TRUE(
|
||||
(std::is_constructible<compat::function_ref<int(int, int, int) noexcept>, compat::nontype_t<&F1::m4>, F1*>));
|
||||
|
||||
F1 f1;
|
||||
|
||||
compat::function_ref<int(int) noexcept> fn2(compat::nontype_t<&F1::m2>{}, &f1);
|
||||
BOOST_TEST_EQ(fn2(2), 12);
|
||||
|
||||
compat::function_ref<int(int, int, int) noexcept> fn4(compat::nontype_t<&F1::m4>{}, &f1);
|
||||
BOOST_TEST_EQ(fn4(2, 3, 4), 1234);
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST_TRAIT_FALSE(
|
||||
(std::is_constructible<compat::function_ref<int() const noexcept>, compat::nontype_t<&F1::m1>, F1 const*>));
|
||||
BOOST_TEST_TRAIT_FALSE(
|
||||
(std::is_constructible<compat::function_ref<int(int) const noexcept>, compat::nontype_t<&F1::m2>, F1 const*>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<int(int, int) const noexcept>,
|
||||
compat::nontype_t<&F1::m3>, F1 const*>));
|
||||
|
||||
F1 const f1;
|
||||
|
||||
compat::function_ref<int(int, int, int) const noexcept> fn4(compat::nontype_t<&F1::m4>{}, &f1);
|
||||
BOOST_TEST_EQ(fn4(2, 3, 4), 1234);
|
||||
|
||||
auto const& f1_2 = f1;
|
||||
compat::function_ref<int(int, int, int) const noexcept> fn4_2(compat::nontype_t<&F1::m4>{}, &f1_2);
|
||||
BOOST_TEST_EQ(fn4_2(2, 3, 4), 1234);
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
#endif
|
||||
176
test/function_ref_mfn_test.cpp
Normal file
176
test/function_ref_mfn_test.cpp
Normal file
@@ -0,0 +1,176 @@
|
||||
// Copyright 2024 Christian Mazakas
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ == 7
|
||||
#pragma GCC diagnostic ignored "-Wnoexcept-type"
|
||||
#endif
|
||||
|
||||
#include <boost/compat/function_ref.hpp>
|
||||
|
||||
#if !defined(BOOST_COMPAT_HAS_AUTO_NTTP)
|
||||
#include <boost/config/pragma_message.hpp>
|
||||
BOOST_PRAGMA_MESSAGE("no support for placeholder NTTPs detected, skipping this test")
|
||||
int main() {}
|
||||
#else
|
||||
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/core/lightweight_test_trait.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
|
||||
struct F1 {
|
||||
std::unique_ptr<int> p_;
|
||||
int q_ = 1337;
|
||||
|
||||
F1() : p_(new int(1)) {}
|
||||
|
||||
int m1() { return *p_ + -1; }
|
||||
int m2(int x1) noexcept { return 10 * *p_ + x1; }
|
||||
int m3(int x1, int x2) const { return 100 * *p_ + 10 * x1 + x2; }
|
||||
int m4(int x1, int x2, int x3) const noexcept { return 1000 * *p_ + 100 * x1 + 10 * x2 + x3; }
|
||||
};
|
||||
|
||||
namespace compat = boost::compat;
|
||||
|
||||
int main() {
|
||||
{
|
||||
F1 f1;
|
||||
|
||||
compat::function_ref<int(F1&)> fn1(compat::nontype_t<&F1::m1>{});
|
||||
BOOST_TEST_EQ(fn1(f1), 0);
|
||||
|
||||
compat::function_ref<int(F1&, int)> fn2(compat::nontype_t<&F1::m2>{});
|
||||
BOOST_TEST_EQ(fn2(f1, 2), 12);
|
||||
|
||||
compat::function_ref<int(F1&, int, int)> fn3(compat::nontype_t<&F1::m3>{});
|
||||
BOOST_TEST_EQ(fn3(f1, 2, 3), 123);
|
||||
|
||||
compat::function_ref<int(F1&, int, int, int)> fn4(compat::nontype_t<&F1::m4>{});
|
||||
BOOST_TEST_EQ(fn4(f1, 2, 3, 4), 1234);
|
||||
|
||||
compat::function_ref<int(F1&)> a1(compat::nontype_t<&F1::q_>{});
|
||||
BOOST_TEST_EQ(a1(f1), 1337);
|
||||
}
|
||||
|
||||
{
|
||||
F1 f1;
|
||||
|
||||
compat::function_ref<int(F1&) const> fn1(compat::nontype_t<&F1::m1>{});
|
||||
BOOST_TEST_EQ(fn1(f1), 0);
|
||||
|
||||
compat::function_ref<int(F1&, int) const> fn2(compat::nontype_t<&F1::m2>{});
|
||||
BOOST_TEST_EQ(fn2(f1, 2), 12);
|
||||
|
||||
compat::function_ref<int(F1&, int, int) const> fn3(compat::nontype_t<&F1::m3>{});
|
||||
BOOST_TEST_EQ(fn3(f1, 2, 3), 123);
|
||||
|
||||
compat::function_ref<int(F1&, int, int, int) const> fn4(compat::nontype_t<&F1::m4>{});
|
||||
BOOST_TEST_EQ(fn4(f1, 2, 3, 4), 1234);
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<int(F1 const&)>, compat::nontype_t<&F1::m1>>));
|
||||
BOOST_TEST_TRAIT_FALSE(
|
||||
(std::is_constructible<compat::function_ref<int(F1 const&, int)>, compat::nontype_t<&F1::m2>>));
|
||||
|
||||
F1 f1;
|
||||
|
||||
compat::function_ref<int(F1 const&, int, int) const> fn3(compat::nontype_t<&F1::m3>{});
|
||||
BOOST_TEST_EQ(fn3(f1, 2, 3), 123);
|
||||
|
||||
compat::function_ref<int(F1 const&, int, int, int) const> fn4(compat::nontype_t<&F1::m4>{});
|
||||
BOOST_TEST_EQ(fn4(f1, 2, 3, 4), 1234);
|
||||
|
||||
auto const& f2 = f1;
|
||||
|
||||
compat::function_ref<int(F1 const&, int, int) const> fn23(compat::nontype_t<&F1::m3>{});
|
||||
BOOST_TEST_EQ(fn3(f2, 2, 3), 123);
|
||||
|
||||
compat::function_ref<int(F1 const&, int, int, int) const> fn24(compat::nontype_t<&F1::m4>{});
|
||||
BOOST_TEST_EQ(fn4(f2, 2, 3, 4), 1234);
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_constructible<compat::function_ref<int(int)>, compat::nontype_t<&F1::m2>, F1&>));
|
||||
BOOST_TEST_TRAIT_FALSE(
|
||||
(std::is_constructible<compat::function_ref<int(int)>, compat::nontype_t<&F1::m2>, F1 const&>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<int(int)>, compat::nontype_t<&F1::m2>, F1&&>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<int(int)>, compat::nontype_t<&F1::m2>, F1>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE(
|
||||
(std::is_constructible<compat::function_ref<int(int, int) const>, compat::nontype_t<&F1::m3>, F1&>));
|
||||
BOOST_TEST_TRAIT_TRUE(
|
||||
(std::is_constructible<compat::function_ref<int(int, int) const>, compat::nontype_t<&F1::m3>, F1 const&>));
|
||||
BOOST_TEST_TRAIT_FALSE(
|
||||
(std::is_constructible<compat::function_ref<int(int, int) const>, compat::nontype_t<&F1::m3>, F1&&>));
|
||||
BOOST_TEST_TRAIT_FALSE(
|
||||
(std::is_constructible<compat::function_ref<int(int, int) const>, compat::nontype_t<&F1::m3>, F1>));
|
||||
}
|
||||
|
||||
{
|
||||
F1 f1;
|
||||
|
||||
compat::function_ref<int()> fn1(compat::nontype_t<&F1::m1>{}, f1);
|
||||
BOOST_TEST_EQ(fn1(), 0);
|
||||
|
||||
compat::function_ref<int(int)> fn2(compat::nontype_t<&F1::m2>{}, f1);
|
||||
BOOST_TEST_EQ(fn2(2), 12);
|
||||
|
||||
compat::function_ref<int(int, int)> fn3(compat::nontype_t<&F1::m3>{}, f1);
|
||||
BOOST_TEST_EQ(fn3(2, 3), 123);
|
||||
|
||||
compat::function_ref<int(int, int, int)> fn4(compat::nontype_t<&F1::m4>{}, f1);
|
||||
BOOST_TEST_EQ(fn4(2, 3, 4), 1234);
|
||||
}
|
||||
|
||||
{
|
||||
F1 const f1;
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<int() const>, compat::nontype_t<&F1::m1>, F1&>));
|
||||
BOOST_TEST_TRAIT_FALSE(
|
||||
(std::is_constructible<compat::function_ref<int(int) const>, compat::nontype_t<&F1::m2>, F1&>));
|
||||
|
||||
compat::function_ref<int(int, int) const> fn3(compat::nontype_t<&F1::m3>{}, f1);
|
||||
BOOST_TEST_EQ(fn3(2, 3), 123);
|
||||
|
||||
compat::function_ref<int(int, int, int) const> fn4(compat::nontype_t<&F1::m4>{}, f1);
|
||||
BOOST_TEST_EQ(fn4(2, 3, 4), 1234);
|
||||
}
|
||||
|
||||
{
|
||||
F1 f1;
|
||||
|
||||
compat::function_ref<int()> fn1(compat::nontype_t<&F1::m1>{}, &f1);
|
||||
BOOST_TEST_EQ(fn1(), 0);
|
||||
|
||||
compat::function_ref<int(int)> fn2(compat::nontype_t<&F1::m2>{}, &f1);
|
||||
BOOST_TEST_EQ(fn2(2), 12);
|
||||
|
||||
compat::function_ref<int(int, int)> fn3(compat::nontype_t<&F1::m3>{}, &f1);
|
||||
BOOST_TEST_EQ(fn3(2, 3), 123);
|
||||
|
||||
compat::function_ref<int(int, int, int)> fn4(compat::nontype_t<&F1::m4>{}, &f1);
|
||||
BOOST_TEST_EQ(fn4(2, 3, 4), 1234);
|
||||
}
|
||||
|
||||
{
|
||||
F1 const f1;
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(
|
||||
(std::is_constructible<compat::function_ref<int() const>, compat::nontype_t<&F1::m1>, F1 const*>));
|
||||
BOOST_TEST_TRAIT_FALSE(
|
||||
(std::is_constructible<compat::function_ref<int(int) const>, compat::nontype_t<&F1::m2>, F1 const*>));
|
||||
|
||||
compat::function_ref<int(int, int) const> fn3(compat::nontype_t<&F1::m3>{}, &f1);
|
||||
BOOST_TEST_EQ(fn3(2, 3), 123);
|
||||
|
||||
compat::function_ref<int(int, int, int) const> fn4(compat::nontype_t<&F1::m4>{}, &f1);
|
||||
BOOST_TEST_EQ(fn4(2, 3, 4), 1234);
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
#endif
|
||||
228
test/function_ref_obj_noexcept_test.cpp
Normal file
228
test/function_ref_obj_noexcept_test.cpp
Normal file
@@ -0,0 +1,228 @@
|
||||
// Copyright 2024 Christian Mazakas
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/config/pragma_message.hpp>
|
||||
|
||||
#if !defined(__cpp_noexcept_function_type)
|
||||
|
||||
BOOST_PRAGMA_MESSAGE("Test skipped, __cpp_noexcept_function_type is not defined")
|
||||
int main() {}
|
||||
|
||||
#else
|
||||
|
||||
#include <boost/compat/function_ref.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/core/lightweight_test_trait.hpp>
|
||||
|
||||
struct F1 {
|
||||
int operator()() { return -1; }
|
||||
|
||||
int operator()(int x1) noexcept { return x1; }
|
||||
|
||||
int operator()(int x1, int x2) const { return 10 * x1 + x2; }
|
||||
|
||||
int operator()(int x1, int x2, int x3) const noexcept { return 100 * x1 + 10 * x2 + x3; }
|
||||
};
|
||||
|
||||
struct F2 {
|
||||
int operator()(int x1, int x2) & { return 100 * x1 + 10 * x2 + 1; }
|
||||
int operator()(int x1, int x2) const& { return 100 * x1 + 10 * x2 + 2; }
|
||||
int operator()(int x1, int x2) && { return 100 * x1 + 10 * x2 + 3; }
|
||||
int operator()(int x1, int x2) const&& { return 100 * x1 + 10 * x2 + 4; }
|
||||
};
|
||||
|
||||
struct X {
|
||||
int v = 0;
|
||||
|
||||
X() = default;
|
||||
X(int v_) noexcept : v{v_} {}
|
||||
};
|
||||
|
||||
struct Y {
|
||||
int v = 0;
|
||||
|
||||
Y() = default;
|
||||
explicit Y(int v_) : v{v_} {}
|
||||
};
|
||||
|
||||
struct Z {
|
||||
int v = 0;
|
||||
|
||||
Z() = default;
|
||||
Z(int v_) : v{v_} {}
|
||||
};
|
||||
|
||||
namespace compat = boost::compat;
|
||||
|
||||
int main() {
|
||||
{
|
||||
F1 f1;
|
||||
{
|
||||
using S1 = int() noexcept;
|
||||
using S2 = int(int) noexcept;
|
||||
using S3 = int(int, int) noexcept;
|
||||
using S4 = int(int, int, int) noexcept;
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S1>, F1>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S1>, F1&>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S1>, F1&&>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S1>, F1 const>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S1>, F1 const&>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S1>, F1 const&&>));
|
||||
|
||||
compat::function_ref<S2> fv2(f1);
|
||||
|
||||
BOOST_TEST_EQ(fv2(1), 1);
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S2>, F1 const>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S2>, F1 const&>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S2>, F1 const&&>));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S3>, F1>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S3>, F1&>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S3>, F1&&>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S3>, F1 const>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S3>, F1 const&>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S3>, F1 const&&>));
|
||||
|
||||
compat::function_ref<S4> fv4(f1);
|
||||
|
||||
BOOST_TEST_EQ(fv4(1, 2, 3), 123);
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_constructible<compat::function_ref<S4>, F1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_constructible<compat::function_ref<S4>, F1&>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_constructible<compat::function_ref<S4>, F1&&>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_constructible<compat::function_ref<S4>, F1 const>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_constructible<compat::function_ref<S4>, F1 const&>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_constructible<compat::function_ref<S4>, F1 const&&>));
|
||||
}
|
||||
{
|
||||
using S1 = int() const noexcept;
|
||||
using S2 = int(int) const noexcept;
|
||||
using S3 = int(int, int) const noexcept;
|
||||
using S4 = int(int, int, int) const noexcept;
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S1>, F1>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S1>, F1&>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S1>, F1&&>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S1>, F1 const>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S1>, F1 const&>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S1>, F1 const&&>));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S2>, F1>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S2>, F1&>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S2>, F1&&>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S2>, F1 const>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S2>, F1 const&>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S2>, F1 const&&>));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S3>, F1>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S3>, F1&>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S3>, F1&&>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S3>, F1 const>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S3>, F1 const&>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S3>, F1 const&&>));
|
||||
|
||||
compat::function_ref<S4> fv4(f1);
|
||||
|
||||
BOOST_TEST_EQ(fv4(1, 2, 3), 123);
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_constructible<compat::function_ref<S4>, F1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_constructible<compat::function_ref<S4>, F1&>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_constructible<compat::function_ref<S4>, F1&&>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_constructible<compat::function_ref<S4>, F1 const>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_constructible<compat::function_ref<S4>, F1 const&>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_constructible<compat::function_ref<S4>, F1 const&&>));
|
||||
}
|
||||
|
||||
{
|
||||
using S2 = int(int) noexcept;
|
||||
using S4 = int(int, int, int) noexcept;
|
||||
|
||||
auto& fref = f1;
|
||||
|
||||
compat::function_ref<S2> fv2(fref);
|
||||
BOOST_TEST_EQ(fv2(1), 1);
|
||||
|
||||
auto const& cfref = f1;
|
||||
compat::function_ref<S4> fv4(cfref);
|
||||
BOOST_TEST_EQ(fv4(1, 2, 3), 123);
|
||||
}
|
||||
|
||||
{
|
||||
using S4 = int(int, int, int) const noexcept;
|
||||
|
||||
auto const& cfref = f1;
|
||||
compat::function_ref<S4> fv4(cfref);
|
||||
BOOST_TEST_EQ(fv4(1, 2, 3), 123);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
using S1 = int(int, int) noexcept;
|
||||
using S2 = int(int, int) const noexcept;
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S1>, F2>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S1>, F2&>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S1>, F2&&>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S1>, F2 const>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S1>, F2 const&>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S1>, F2 const&&>));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S2>, F2>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S2>, F2&>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S2>, F2&&>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S2>, F2 const>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S2>, F2 const&>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S2>, F2 const&&>));
|
||||
}
|
||||
|
||||
// invoke_r
|
||||
{
|
||||
F1 f;
|
||||
|
||||
compat::function_ref<X(int, int, int) noexcept> fv1(f);
|
||||
BOOST_TEST_EQ(fv1(1, 2, 3).v, 123);
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<Y(int, int, int) noexcept>, F1>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<Z(int, int, int) noexcept>, F1>));
|
||||
|
||||
compat::function_ref<X(int, int, int) const noexcept> fv2(f);
|
||||
BOOST_TEST_EQ(fv2(1, 2, 3).v, 123);
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<Y(int, int, int) const noexcept>, F1>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<Z(int, int, int) const noexcept>, F1>));
|
||||
|
||||
compat::function_ref<void(int, int, int) noexcept> fv3(f);
|
||||
fv3(1, 2, 3);
|
||||
|
||||
compat::function_ref<void(int, int, int) const noexcept> fv4(f);
|
||||
fv4(1, 2, 3);
|
||||
}
|
||||
|
||||
// copy construct, copy assign
|
||||
{
|
||||
F1 f;
|
||||
|
||||
auto id = [](int x) noexcept { return x + 7331; };
|
||||
|
||||
compat::function_ref<int(int) noexcept> fv(f);
|
||||
compat::function_ref<int(int) noexcept> fv2(fv);
|
||||
BOOST_TEST_EQ(fv(12), fv2(12));
|
||||
|
||||
fv2 = compat::function_ref<int(int) noexcept>(id);
|
||||
BOOST_TEST_EQ(fv2(1), 7332);
|
||||
|
||||
auto add = [](int x, int y, int z) noexcept { return x + y + z; };
|
||||
compat::function_ref<int(int, int, int) const noexcept> cfv(f);
|
||||
compat::function_ref<int(int, int, int) const noexcept> cfv2(cfv);
|
||||
BOOST_TEST_EQ(cfv(1, 2, 3), cfv2(1, 2, 3));
|
||||
|
||||
cfv2 = compat::function_ref<int(int, int, int) const noexcept>(add);
|
||||
BOOST_TEST_EQ(cfv2(1, 2, 3), 6);
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
#endif
|
||||
260
test/function_ref_obj_test.cpp
Normal file
260
test/function_ref_obj_test.cpp
Normal file
@@ -0,0 +1,260 @@
|
||||
// Copyright 2024 Christian Mazakas
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/compat/function_ref.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/core/lightweight_test_trait.hpp>
|
||||
|
||||
struct F1 {
|
||||
int operator()() { return -1; }
|
||||
|
||||
int operator()(int x1) noexcept { return x1; }
|
||||
|
||||
int operator()(int x1, int x2) const { return 10 * x1 + x2; }
|
||||
|
||||
int operator()(int x1, int x2, int x3) const noexcept { return 100 * x1 + 10 * x2 + x3; }
|
||||
};
|
||||
|
||||
struct F2 {
|
||||
int operator()(int x1, int x2) & { return 100 * x1 + 10 * x2 + 1; }
|
||||
int operator()(int x1, int x2) const& { return 100 * x1 + 10 * x2 + 2; }
|
||||
int operator()(int x1, int x2) && { return 100 * x1 + 10 * x2 + 3; }
|
||||
int operator()(int x1, int x2) const&& { return 100 * x1 + 10 * x2 + 4; }
|
||||
};
|
||||
|
||||
struct X {
|
||||
int v = 0;
|
||||
|
||||
X() = default;
|
||||
X(int v_) noexcept : v{v_} {}
|
||||
};
|
||||
|
||||
struct Y {
|
||||
int v = 0;
|
||||
|
||||
Y() = default;
|
||||
explicit Y(int v_) : v{v_} {}
|
||||
};
|
||||
|
||||
struct Z {
|
||||
int v = 0;
|
||||
|
||||
Z() = default;
|
||||
Z(int v_) : v{v_} {}
|
||||
};
|
||||
|
||||
namespace compat = boost::compat;
|
||||
|
||||
int main() {
|
||||
{
|
||||
F1 f;
|
||||
{
|
||||
using S1 = int();
|
||||
using S2 = int(int);
|
||||
using S3 = int(int, int);
|
||||
using S4 = int(int, int, int);
|
||||
|
||||
compat::function_ref<S1> fv1(f);
|
||||
|
||||
BOOST_TEST_EQ(fv1(), -1);
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S1>, F1 const>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S1>, F1 const&>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S1>, F1 const&&>));
|
||||
|
||||
compat::function_ref<S2> fv2(f);
|
||||
|
||||
BOOST_TEST_EQ(fv2(1), 1);
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S2>, F1 const>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S2>, F1 const&>));
|
||||
|
||||
compat::function_ref<S3> fv3(f);
|
||||
|
||||
BOOST_TEST_EQ(fv3(1, 2), 12);
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_constructible<compat::function_ref<S3>, F1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_constructible<compat::function_ref<S3>, F1&>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_constructible<compat::function_ref<S3>, F1&&>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_constructible<compat::function_ref<S3>, F1 const>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_constructible<compat::function_ref<S3>, F1 const&>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_constructible<compat::function_ref<S3>, F1 const&&>));
|
||||
|
||||
compat::function_ref<S4> fv4(f);
|
||||
|
||||
BOOST_TEST_EQ(fv4(1, 2, 3), 123);
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_constructible<compat::function_ref<S4>, F1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_constructible<compat::function_ref<S4>, F1&>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_constructible<compat::function_ref<S4>, F1&&>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_constructible<compat::function_ref<S4>, F1 const>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_constructible<compat::function_ref<S4>, F1 const&>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_constructible<compat::function_ref<S4>, F1 const&&>));
|
||||
}
|
||||
|
||||
{
|
||||
using S1 = int() const;
|
||||
using S2 = int(int) const;
|
||||
using S3 = int(int, int) const;
|
||||
using S4 = int(int, int, int) const;
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S1>, F1>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S1>, F1&>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S1>, F1&&>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S1>, F1 const>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S1>, F1 const&>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S1>, F1 const&&>));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S2>, F1>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S2>, F1&>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S2>, F1&&>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S2>, F1 const>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S2>, F1 const&>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<S2>, F1 const&&>));
|
||||
|
||||
compat::function_ref<S3> fv3(f);
|
||||
|
||||
BOOST_TEST_EQ(fv3(1, 2), 12);
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_constructible<compat::function_ref<S3>, F1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_constructible<compat::function_ref<S3>, F1&>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_constructible<compat::function_ref<S3>, F1&&>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_constructible<compat::function_ref<S3>, F1 const>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_constructible<compat::function_ref<S3>, F1 const&>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_constructible<compat::function_ref<S3>, F1 const&&>));
|
||||
|
||||
compat::function_ref<S4> fv4(f);
|
||||
|
||||
BOOST_TEST_EQ(fv4(1, 2, 3), 123);
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_constructible<compat::function_ref<S4>, F1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_constructible<compat::function_ref<S4>, F1&>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_constructible<compat::function_ref<S4>, F1&&>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_constructible<compat::function_ref<S4>, F1 const>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_constructible<compat::function_ref<S4>, F1 const&>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_constructible<compat::function_ref<S4>, F1 const&&>));
|
||||
}
|
||||
|
||||
{
|
||||
using S1 = int();
|
||||
using S2 = int(int);
|
||||
|
||||
auto& fref = f;
|
||||
|
||||
compat::function_ref<S1> fv1(fref);
|
||||
BOOST_TEST_EQ(fv1(), -1);
|
||||
|
||||
compat::function_ref<S2> fv2(fref);
|
||||
BOOST_TEST_EQ(fv2(1), 1);
|
||||
}
|
||||
|
||||
{
|
||||
using S1 = int();
|
||||
using S2 = int(int);
|
||||
|
||||
compat::function_ref<S1> fv1(std::move(f));
|
||||
BOOST_TEST_EQ(fv1(), -1);
|
||||
|
||||
compat::function_ref<S2> fv2(std::move(f));
|
||||
BOOST_TEST_EQ(fv2(1), 1);
|
||||
}
|
||||
|
||||
{
|
||||
using S3 = int(int, int) const;
|
||||
using S4 = int(int, int, int) const;
|
||||
|
||||
auto const& fref = f;
|
||||
|
||||
compat::function_ref<S3> fv3(fref);
|
||||
BOOST_TEST_EQ(fv3(1, 2), 12);
|
||||
|
||||
compat::function_ref<S4> fv4(fref);
|
||||
BOOST_TEST_EQ(fv4(1, 2, 3), 123);
|
||||
}
|
||||
|
||||
{
|
||||
using S3 = int(int, int) const;
|
||||
using S4 = int(int, int, int) const;
|
||||
|
||||
auto const&& fref = std::move(f);
|
||||
|
||||
compat::function_ref<S3> fv3(fref);
|
||||
BOOST_TEST_EQ(fv3(1, 2), 12);
|
||||
|
||||
compat::function_ref<S4> fv4(fref);
|
||||
BOOST_TEST_EQ(fv4(1, 2, 3), 123);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
F2 g;
|
||||
{
|
||||
compat::function_ref<int(int, int)> fv1(g);
|
||||
BOOST_TEST_EQ(fv1(3, 2), 321);
|
||||
|
||||
auto& gref = g;
|
||||
compat::function_ref<int(int, int)> rfv1(gref);
|
||||
BOOST_TEST_EQ(rfv1(3, 2), 321);
|
||||
|
||||
compat::function_ref<int(int, int)> fv2(std::move(g));
|
||||
BOOST_TEST_EQ(fv2(3, 2), 321);
|
||||
|
||||
compat::function_ref<int(int, int) const> fv3(g);
|
||||
BOOST_TEST_EQ(fv3(3, 2), 322);
|
||||
|
||||
auto const& gcref = g;
|
||||
compat::function_ref<int(int, int) const> crfv3(gcref);
|
||||
BOOST_TEST_EQ(fv3(3, 2), 322);
|
||||
|
||||
compat::function_ref<int(int, int) const> fv4(std::move(g));
|
||||
BOOST_TEST_EQ(fv4(3, 2), 322);
|
||||
}
|
||||
}
|
||||
|
||||
// invoke_r
|
||||
{
|
||||
F1 f;
|
||||
|
||||
compat::function_ref<X(int, int, int)> fv1(f);
|
||||
BOOST_TEST_EQ(fv1(1, 2, 3).v, 123);
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<Y(int, int, int)>, F1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_constructible<compat::function_ref<Z(int, int, int)>, F1>));
|
||||
|
||||
compat::function_ref<X(int, int, int) const> fv2(f);
|
||||
BOOST_TEST_EQ(fv2(1, 2, 3).v, 123);
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<compat::function_ref<Y(int, int, int) const>, F1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_constructible<compat::function_ref<Z(int, int, int) const>, F1>));
|
||||
|
||||
compat::function_ref<void(int, int, int)> fv3(f);
|
||||
fv3(1, 2, 3);
|
||||
|
||||
compat::function_ref<void(int, int, int) const> fv4(f);
|
||||
fv4(1, 2, 3);
|
||||
}
|
||||
|
||||
// copy construct, copy assign
|
||||
{
|
||||
F1 f;
|
||||
|
||||
auto id = [] { return 7331; };
|
||||
|
||||
compat::function_ref<int()> fv(f);
|
||||
compat::function_ref<int()> fv2(fv);
|
||||
BOOST_TEST_EQ(fv(), fv2());
|
||||
|
||||
fv2 = compat::function_ref<int()>(id);
|
||||
BOOST_TEST_EQ(fv2(), 7331);
|
||||
|
||||
auto add = [](int x, int y) { return x + y; };
|
||||
compat::function_ref<int(int, int) const> cfv(f);
|
||||
compat::function_ref<int(int, int) const> cfv2(cfv);
|
||||
BOOST_TEST_EQ(cfv(1, 2), cfv2(1, 2));
|
||||
|
||||
cfv2 = compat::function_ref<int(int, int) const>(add);
|
||||
BOOST_TEST_EQ(cfv2(1, 2), 3);
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
55
test/integer_sequence_test.cpp
Normal file
55
test/integer_sequence_test.cpp
Normal file
@@ -0,0 +1,55 @@
|
||||
// Copyright 2015 Peter Dimov.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/compat/integer_sequence.hpp>
|
||||
#include <boost/core/lightweight_test_trait.hpp>
|
||||
#include <type_traits>
|
||||
#include <cstddef>
|
||||
|
||||
int main()
|
||||
{
|
||||
using boost::compat::integer_sequence;
|
||||
using boost::compat::make_integer_sequence;
|
||||
using boost::compat::index_sequence;
|
||||
using boost::compat::make_index_sequence;
|
||||
using boost::compat::index_sequence_for;
|
||||
|
||||
BOOST_TEST_TRAIT_SAME(make_integer_sequence<int, 0>, integer_sequence<int>);
|
||||
BOOST_TEST_TRAIT_SAME(make_integer_sequence<int, 1>, integer_sequence<int, 0>);
|
||||
BOOST_TEST_TRAIT_SAME(make_integer_sequence<int, 2>, integer_sequence<int, 0, 1>);
|
||||
BOOST_TEST_TRAIT_SAME(make_integer_sequence<int, 3>, integer_sequence<int, 0, 1, 2>);
|
||||
BOOST_TEST_TRAIT_SAME(make_integer_sequence<int, 4>, integer_sequence<int, 0, 1, 2, 3>);
|
||||
|
||||
BOOST_TEST_TRAIT_SAME(make_integer_sequence<char, 0>, integer_sequence<char>);
|
||||
BOOST_TEST_TRAIT_SAME(make_integer_sequence<char, 1>, integer_sequence<char, 0>);
|
||||
BOOST_TEST_TRAIT_SAME(make_integer_sequence<char, 2>, integer_sequence<char, 0, 1>);
|
||||
BOOST_TEST_TRAIT_SAME(make_integer_sequence<char, 3>, integer_sequence<char, 0, 1, 2>);
|
||||
BOOST_TEST_TRAIT_SAME(make_integer_sequence<char, 4>, integer_sequence<char, 0, 1, 2, 3>);
|
||||
|
||||
BOOST_TEST_TRAIT_SAME(make_integer_sequence<std::size_t, 0>, integer_sequence<std::size_t>);
|
||||
BOOST_TEST_TRAIT_SAME(make_integer_sequence<std::size_t, 1>, integer_sequence<std::size_t, 0>);
|
||||
BOOST_TEST_TRAIT_SAME(make_integer_sequence<std::size_t, 2>, integer_sequence<std::size_t, 0, 1>);
|
||||
BOOST_TEST_TRAIT_SAME(make_integer_sequence<std::size_t, 3>, integer_sequence<std::size_t, 0, 1, 2>);
|
||||
BOOST_TEST_TRAIT_SAME(make_integer_sequence<std::size_t, 4>, integer_sequence<std::size_t, 0, 1, 2, 3>);
|
||||
|
||||
BOOST_TEST_TRAIT_SAME(make_index_sequence<0>, integer_sequence<std::size_t>);
|
||||
BOOST_TEST_TRAIT_SAME(make_index_sequence<1>, integer_sequence<std::size_t, 0>);
|
||||
BOOST_TEST_TRAIT_SAME(make_index_sequence<2>, integer_sequence<std::size_t, 0, 1>);
|
||||
BOOST_TEST_TRAIT_SAME(make_index_sequence<3>, integer_sequence<std::size_t, 0, 1, 2>);
|
||||
BOOST_TEST_TRAIT_SAME(make_index_sequence<4>, integer_sequence<std::size_t, 0, 1, 2, 3>);
|
||||
|
||||
BOOST_TEST_TRAIT_SAME(make_index_sequence<0>, index_sequence<>);
|
||||
BOOST_TEST_TRAIT_SAME(make_index_sequence<1>, index_sequence<0>);
|
||||
BOOST_TEST_TRAIT_SAME(make_index_sequence<2>, index_sequence<0, 1>);
|
||||
BOOST_TEST_TRAIT_SAME(make_index_sequence<3>, index_sequence<0, 1, 2>);
|
||||
BOOST_TEST_TRAIT_SAME(make_index_sequence<4>, index_sequence<0, 1, 2, 3>);
|
||||
|
||||
BOOST_TEST_TRAIT_SAME(index_sequence_for<>, index_sequence<>);
|
||||
BOOST_TEST_TRAIT_SAME(index_sequence_for<void>, index_sequence<0>);
|
||||
BOOST_TEST_TRAIT_SAME(index_sequence_for<void, void>, index_sequence<0, 1>);
|
||||
BOOST_TEST_TRAIT_SAME(index_sequence_for<void, void, void>, index_sequence<0, 1, 2>);
|
||||
BOOST_TEST_TRAIT_SAME(index_sequence_for<void, void, void, void>, index_sequence<0, 1, 2, 3>);
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
40
test/invoke_fn_constexpr_test.cpp
Normal file
40
test/invoke_fn_constexpr_test.cpp
Normal file
@@ -0,0 +1,40 @@
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ == 7
|
||||
# pragma GCC diagnostic ignored "-Wnoexcept-type"
|
||||
#endif
|
||||
|
||||
#include <boost/compat/invoke.hpp>
|
||||
|
||||
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
|
||||
#define BOOST_TEST_EQ(x, y) STATIC_ASSERT((x) == (y))
|
||||
|
||||
constexpr int f0()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
constexpr int f1( int x1 ) noexcept
|
||||
{
|
||||
return x1;
|
||||
}
|
||||
|
||||
constexpr int f2( int x1, int x2 )
|
||||
{
|
||||
return 10*x1+x2;
|
||||
}
|
||||
|
||||
constexpr int f3( int x1, int x2, int x3 ) noexcept
|
||||
{
|
||||
return 100*x1 + 10*x2 + x3;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::invoke( f0 ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( f1, 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( f2, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( f3, 1, 2, 3 ), 123 );
|
||||
}
|
||||
47
test/invoke_fn_noexcept_test.cpp
Normal file
47
test/invoke_fn_noexcept_test.cpp
Normal file
@@ -0,0 +1,47 @@
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/config/pragma_message.hpp>
|
||||
|
||||
#if !defined(__cpp_noexcept_function_type)
|
||||
|
||||
BOOST_PRAGMA_MESSAGE( "Test skipped, __cpp_noexcept_function_type is not defined" )
|
||||
int main() {}
|
||||
|
||||
#else
|
||||
|
||||
#include <boost/compat/invoke.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
int f0()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int f1( int x1 ) noexcept
|
||||
{
|
||||
return x1;
|
||||
}
|
||||
|
||||
int f2( int x1, int x2 )
|
||||
{
|
||||
return 10*x1+x2;
|
||||
}
|
||||
|
||||
int f3( int x1, int x2, int x3 ) noexcept
|
||||
{
|
||||
return 100*x1 + 10*x2 + x3;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( f0 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( f1, 1 ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( f2, 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( f3, 1, 2, 3 ) ), true );
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
#endif
|
||||
40
test/invoke_fn_test.cpp
Normal file
40
test/invoke_fn_test.cpp
Normal file
@@ -0,0 +1,40 @@
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ == 7
|
||||
# pragma GCC diagnostic ignored "-Wnoexcept-type"
|
||||
#endif
|
||||
|
||||
#include <boost/compat/invoke.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
int f0()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int f1( int x1 ) noexcept
|
||||
{
|
||||
return x1;
|
||||
}
|
||||
|
||||
int f2( int x1, int x2 )
|
||||
{
|
||||
return 10*x1+x2;
|
||||
}
|
||||
|
||||
int f3( int x1, int x2, int x3 ) noexcept
|
||||
{
|
||||
return 100*x1 + 10*x2 + x3;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::invoke( f0 ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( f1, 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( f2, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( f3, 1, 2, 3 ), 123 );
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
42
test/invoke_md_constexpr_test.cpp
Normal file
42
test/invoke_md_constexpr_test.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/compat/invoke.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/config/workaround.hpp>
|
||||
|
||||
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
|
||||
#define BOOST_TEST_EQ(x, y) STATIC_ASSERT((x) == (y))
|
||||
|
||||
struct X
|
||||
{
|
||||
int m = -1;
|
||||
};
|
||||
|
||||
struct Y: public X
|
||||
{
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::m, X() ), -1 );
|
||||
|
||||
constexpr X x = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::m, x ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::m, &x ), -1 );
|
||||
}
|
||||
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, >= 1920 && BOOST_MSVC < 1950)
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::m, Y() ), -1 );
|
||||
|
||||
constexpr Y y = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::m, y ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::m, &y ), -1 );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
60
test/invoke_md_noexcept_test.cpp
Normal file
60
test/invoke_md_noexcept_test.cpp
Normal file
@@ -0,0 +1,60 @@
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/compat/invoke.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <functional>
|
||||
|
||||
struct X
|
||||
{
|
||||
int m = -1;
|
||||
};
|
||||
|
||||
struct Y: public virtual X
|
||||
{
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::m, X() ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::m, Y() ) ), true );
|
||||
}
|
||||
|
||||
{
|
||||
X x;
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::m, x ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::m, &x ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::m, std::ref(x) ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::m, std::cref(x) ) ), true );
|
||||
}
|
||||
|
||||
{
|
||||
Y y;
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::m, y ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::m, &y ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::m, std::ref(y) ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::m, std::cref(y) ) ), true );
|
||||
}
|
||||
|
||||
{
|
||||
X const x = {};
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::m, x ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::m, &x ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::m, std::ref(x) ) ), true );
|
||||
}
|
||||
|
||||
{
|
||||
Y const y = {};
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::m, y ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::m, &y ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::m, std::ref(y) ) ), true );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
105
test/invoke_md_test.cpp
Normal file
105
test/invoke_md_test.cpp
Normal file
@@ -0,0 +1,105 @@
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/compat/invoke.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <functional>
|
||||
|
||||
struct X
|
||||
{
|
||||
int m = -1;
|
||||
};
|
||||
|
||||
struct Y: public virtual X
|
||||
{
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::m, X() ), -1 );
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::m, Y() ), -1 );
|
||||
}
|
||||
|
||||
{
|
||||
X x;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::m, x ), -1 );
|
||||
boost::compat::invoke( &X::m, x ) = +1;
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::m, x ), +1 );
|
||||
}
|
||||
|
||||
{
|
||||
X x;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::m, &x ), -1 );
|
||||
boost::compat::invoke( &X::m, &x ) = +1;
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::m, &x ), +1 );
|
||||
}
|
||||
|
||||
{
|
||||
X x;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::m, std::ref(x) ), -1 );
|
||||
boost::compat::invoke( &X::m, std::ref(x) ) = +1;
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::m, std::ref(x) ), +1 );
|
||||
}
|
||||
|
||||
{
|
||||
X x;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::m, std::cref(x) ), -1 );
|
||||
}
|
||||
|
||||
{
|
||||
Y y;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::m, y ), -1 );
|
||||
boost::compat::invoke( &X::m, y ) = +1;
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::m, y ), +1 );
|
||||
}
|
||||
|
||||
{
|
||||
Y y;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::m, &y ), -1 );
|
||||
boost::compat::invoke( &X::m, &y ) = +1;
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::m, &y ), +1 );
|
||||
}
|
||||
|
||||
{
|
||||
Y y;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::m, std::ref(y) ), -1 );
|
||||
boost::compat::invoke( &X::m, std::ref(y) ) = +1;
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::m, std::ref(y) ), +1 );
|
||||
}
|
||||
|
||||
{
|
||||
Y y;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::m, std::cref(y) ), -1 );
|
||||
}
|
||||
|
||||
{
|
||||
X const x = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::m, x ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::m, &x ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::m, std::ref(x) ), -1 );
|
||||
}
|
||||
|
||||
{
|
||||
Y const y = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::m, y ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::m, &y ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::m, std::ref(y) ), -1 );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
88
test/invoke_mfn_constexpr_test.cpp
Normal file
88
test/invoke_mfn_constexpr_test.cpp
Normal file
@@ -0,0 +1,88 @@
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ == 7
|
||||
# pragma GCC diagnostic ignored "-Wnoexcept-type"
|
||||
#endif
|
||||
|
||||
#include <boost/compat/invoke.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/config/workaround.hpp>
|
||||
|
||||
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
|
||||
#define BOOST_TEST_EQ(x, y) STATIC_ASSERT((x) == (y))
|
||||
|
||||
struct X
|
||||
{
|
||||
constexpr int f0() const
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
constexpr int f1( int x1 ) const noexcept
|
||||
{
|
||||
return x1;
|
||||
}
|
||||
|
||||
constexpr int f2( int x1, int x2 ) const
|
||||
{
|
||||
return 10*x1+x2;
|
||||
}
|
||||
|
||||
constexpr int f3( int x1, int x2, int x3 ) const noexcept
|
||||
{
|
||||
return 100*x1 + 10*x2 + x3;
|
||||
}
|
||||
};
|
||||
|
||||
struct Y: public X
|
||||
{
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f0, X() ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f1, X(), 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f2, X(), 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f3, X(), 1, 2, 3 ), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f0, Y() ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f1, Y(), 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f2, Y(), 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f3, Y(), 1, 2, 3 ), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
constexpr X x = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f0, x ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f1, x, 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f2, x, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f3, x, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f0, &x ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f1, &x, 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f2, &x, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f3, &x, 1, 2, 3 ), 123 );
|
||||
}
|
||||
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1910)
|
||||
{
|
||||
constexpr Y y = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f0, y ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f1, y, 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f2, y, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f3, y, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f0, &y ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f1, &y, 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f2, &y, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f3, &y, 1, 2, 3 ), 123 );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
134
test/invoke_mfn_noexcept_test.cpp
Normal file
134
test/invoke_mfn_noexcept_test.cpp
Normal file
@@ -0,0 +1,134 @@
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/config/pragma_message.hpp>
|
||||
|
||||
#if !defined(__cpp_noexcept_function_type)
|
||||
|
||||
BOOST_PRAGMA_MESSAGE( "Test skipped, __cpp_noexcept_function_type is not defined" )
|
||||
int main() {}
|
||||
|
||||
#else
|
||||
|
||||
#include <boost/compat/invoke.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <functional>
|
||||
|
||||
struct X
|
||||
{
|
||||
int f0()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int f1( int x1 ) noexcept
|
||||
{
|
||||
return x1;
|
||||
}
|
||||
|
||||
int f2( int x1, int x2 ) const
|
||||
{
|
||||
return 10*x1+x2;
|
||||
}
|
||||
|
||||
int f3( int x1, int x2, int x3 ) const noexcept
|
||||
{
|
||||
return 100*x1 + 10*x2 + x3;
|
||||
}
|
||||
};
|
||||
|
||||
struct Y: public virtual X
|
||||
{
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::f0, X() ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::f1, X(), 1 ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::f2, X(), 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::f3, X(), 1, 2, 3 ) ), true );
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::f0, Y() ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::f1, Y(), 1 ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::f2, Y(), 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::f3, Y(), 1, 2, 3 ) ), true );
|
||||
}
|
||||
|
||||
{
|
||||
X x;
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::f0, x ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::f1, x, 1 ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::f2, x, 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::f3, x, 1, 2, 3 ) ), true );
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::f0, &x ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::f1, &x, 1 ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::f2, &x, 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::f3, &x, 1, 2, 3 ) ), true );
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::f0, std::ref(x) ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::f1, std::ref(x), 1 ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::f2, std::ref(x), 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::f3, std::ref(x), 1, 2, 3 ) ), true );
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::f2, std::cref(x), 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::f3, std::cref(x), 1, 2, 3 ) ), true );
|
||||
}
|
||||
|
||||
{
|
||||
Y y;
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::f0, y ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::f1, y, 1 ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::f2, y, 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::f3, y, 1, 2, 3 ) ), true );
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::f0, &y ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::f1, &y, 1 ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::f2, &y, 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::f3, &y, 1, 2, 3 ) ), true );
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::f0, std::ref(y) ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::f1, std::ref(y), 1 ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::f2, std::ref(y), 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::f3, std::ref(y), 1, 2, 3 ) ), true );
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::f2, std::cref(y), 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::f3, std::cref(y), 1, 2, 3 ) ), true );
|
||||
}
|
||||
|
||||
{
|
||||
X const x = {};
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::f2, x, 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::f3, x, 1, 2, 3 ) ), true );
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::f2, &x, 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::f3, &x, 1, 2, 3 ) ), true );
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::f2, std::ref(x), 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::f3, std::ref(x), 1, 2, 3 ) ), true );
|
||||
}
|
||||
|
||||
{
|
||||
Y const y = {};
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::f2, y, 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::f3, y, 1, 2, 3 ) ), true );
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::f2, &y, 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::f3, &y, 1, 2, 3 ) ), true );
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::f2, std::ref(y), 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( &X::f3, std::ref(y), 1, 2, 3 ) ), true );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
#endif
|
||||
127
test/invoke_mfn_test.cpp
Normal file
127
test/invoke_mfn_test.cpp
Normal file
@@ -0,0 +1,127 @@
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ == 7
|
||||
# pragma GCC diagnostic ignored "-Wnoexcept-type"
|
||||
#endif
|
||||
|
||||
#include <boost/compat/invoke.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <functional>
|
||||
|
||||
struct X
|
||||
{
|
||||
int f0()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int f1( int x1 ) noexcept
|
||||
{
|
||||
return x1;
|
||||
}
|
||||
|
||||
int f2( int x1, int x2 ) const
|
||||
{
|
||||
return 10*x1+x2;
|
||||
}
|
||||
|
||||
int f3( int x1, int x2, int x3 ) const noexcept
|
||||
{
|
||||
return 100*x1 + 10*x2 + x3;
|
||||
}
|
||||
};
|
||||
|
||||
struct Y: public virtual X
|
||||
{
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f0, X() ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f1, X(), 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f2, X(), 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f3, X(), 1, 2, 3 ), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f0, Y() ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f1, Y(), 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f2, Y(), 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f3, Y(), 1, 2, 3 ), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
X x;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f0, x ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f1, x, 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f2, x, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f3, x, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f0, &x ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f1, &x, 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f2, &x, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f3, &x, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f0, std::ref(x) ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f1, std::ref(x), 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f2, std::ref(x), 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f3, std::ref(x), 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f2, std::cref(x), 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f3, std::cref(x), 1, 2, 3 ), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
Y y;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f0, y ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f1, y, 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f2, y, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f3, y, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f0, &y ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f1, &y, 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f2, &y, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f3, &y, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f0, std::ref(y) ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f1, std::ref(y), 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f2, std::ref(y), 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f3, std::ref(y), 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f2, std::cref(y), 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f3, std::cref(y), 1, 2, 3 ), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
X const x = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f2, x, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f3, x, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f2, &x, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f3, &x, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f2, std::ref(x), 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f3, std::ref(x), 1, 2, 3 ), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
Y const y = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f2, y, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f3, y, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f2, &y, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f3, &y, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f2, std::ref(y), 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( &X::f3, std::ref(y), 1, 2, 3 ), 123 );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
50
test/invoke_obj_constexpr_test.cpp
Normal file
50
test/invoke_obj_constexpr_test.cpp
Normal file
@@ -0,0 +1,50 @@
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/compat/invoke.hpp>
|
||||
|
||||
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
|
||||
#define BOOST_TEST_EQ(x, y) STATIC_ASSERT((x) == (y))
|
||||
|
||||
struct F
|
||||
{
|
||||
constexpr int operator()() const
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
constexpr int operator()( int x1 ) const noexcept
|
||||
{
|
||||
return x1;
|
||||
}
|
||||
|
||||
constexpr int operator()( int x1, int x2 ) const
|
||||
{
|
||||
return 10*x1+x2;
|
||||
}
|
||||
|
||||
constexpr int operator()( int x1, int x2, int x3 ) const noexcept
|
||||
{
|
||||
return 100*x1 + 10*x2 + x3;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::invoke( F() ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( F(), 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( F(), 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( F(), 1, 2, 3 ), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
constexpr F f = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke( f ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( f, 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( f, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( f, 1, 2, 3 ), 123 );
|
||||
}
|
||||
}
|
||||
57
test/invoke_obj_noexcept_test.cpp
Normal file
57
test/invoke_obj_noexcept_test.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/compat/invoke.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
struct F
|
||||
{
|
||||
int operator()()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int operator()( int x1 ) noexcept
|
||||
{
|
||||
return x1;
|
||||
}
|
||||
|
||||
int operator()( int x1, int x2 ) const
|
||||
{
|
||||
return 10*x1+x2;
|
||||
}
|
||||
|
||||
int operator()( int x1, int x2, int x3 ) const noexcept
|
||||
{
|
||||
return 100*x1 + 10*x2 + x3;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( F() ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( F(), 1 ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( F(), 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( F(), 1, 2, 3 ) ), true );
|
||||
}
|
||||
|
||||
{
|
||||
F f = {};
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( f ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( f, 1 ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( f, 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( f, 1, 2, 3 ) ), true );
|
||||
}
|
||||
|
||||
{
|
||||
F const f = {};
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( f, 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke( f, 1, 2, 3 ) ), true );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
57
test/invoke_obj_test.cpp
Normal file
57
test/invoke_obj_test.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/compat/invoke.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
struct F
|
||||
{
|
||||
int operator()()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int operator()( int x1 ) noexcept
|
||||
{
|
||||
return x1;
|
||||
}
|
||||
|
||||
int operator()( int x1, int x2 ) const
|
||||
{
|
||||
return 10*x1+x2;
|
||||
}
|
||||
|
||||
int operator()( int x1, int x2, int x3 ) const noexcept
|
||||
{
|
||||
return 100*x1 + 10*x2 + x3;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::invoke( F() ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( F(), 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( F(), 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( F(), 1, 2, 3 ), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
F f;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke( f ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( f, 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( f, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( f, 1, 2, 3 ), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
F const f = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke( f, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke( f, 1, 2, 3 ), 123 );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
50
test/invoke_r_fn_constexpr_test.cpp
Normal file
50
test/invoke_r_fn_constexpr_test.cpp
Normal file
@@ -0,0 +1,50 @@
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ == 7
|
||||
# pragma GCC diagnostic ignored "-Wnoexcept-type"
|
||||
#endif
|
||||
|
||||
#include <boost/compat/invoke.hpp>
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#define STATIC_ASSERT(...) static_assert((__VA_ARGS__), #__VA_ARGS__)
|
||||
#define BOOST_TEST_EQ(x, y) STATIC_ASSERT((x) == (y))
|
||||
|
||||
constexpr int f0()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
constexpr int f1( int x1 ) noexcept
|
||||
{
|
||||
return x1;
|
||||
}
|
||||
|
||||
constexpr int f2( int x1, int x2 )
|
||||
{
|
||||
return 10*x1+x2;
|
||||
}
|
||||
|
||||
constexpr int f3( int x1, int x2, int x3 ) noexcept
|
||||
{
|
||||
return 100*x1 + 10*x2 + x3;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( f0 ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( f1, 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( f2, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( f3, 1, 2, 3 ), 123 );
|
||||
|
||||
#if !defined(BOOST_NO_CXX14_CONSTEXPR)
|
||||
|
||||
STATIC_ASSERT( boost::compat::invoke_r<void>( f0 ), true );
|
||||
STATIC_ASSERT( boost::compat::invoke_r<void>( f1, 1 ), true );
|
||||
STATIC_ASSERT( boost::compat::invoke_r<void>( f2, 1, 2 ), true );
|
||||
STATIC_ASSERT( boost::compat::invoke_r<void>( f3, 1, 2, 3 ), true );
|
||||
|
||||
#endif
|
||||
}
|
||||
52
test/invoke_r_fn_noexcept_test.cpp
Normal file
52
test/invoke_r_fn_noexcept_test.cpp
Normal file
@@ -0,0 +1,52 @@
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/config/pragma_message.hpp>
|
||||
|
||||
#if !defined(__cpp_noexcept_function_type)
|
||||
|
||||
BOOST_PRAGMA_MESSAGE( "Test skipped, __cpp_noexcept_function_type is not defined" )
|
||||
int main() {}
|
||||
|
||||
#else
|
||||
|
||||
#include <boost/compat/invoke.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
int f0()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int f1( int x1 ) noexcept
|
||||
{
|
||||
return x1;
|
||||
}
|
||||
|
||||
int f2( int x1, int x2 )
|
||||
{
|
||||
return 10*x1+x2;
|
||||
}
|
||||
|
||||
int f3( int x1, int x2, int x3 ) noexcept
|
||||
{
|
||||
return 100*x1 + 10*x2 + x3;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( f0 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( f1, 1 ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( f2, 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( f3, 1, 2, 3 ) ), true );
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( f0 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( f1, 1 ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( f2, 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( f3, 1, 2, 3 ) ), true );
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
#endif
|
||||
45
test/invoke_r_fn_test.cpp
Normal file
45
test/invoke_r_fn_test.cpp
Normal file
@@ -0,0 +1,45 @@
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ == 7
|
||||
# pragma GCC diagnostic ignored "-Wnoexcept-type"
|
||||
#endif
|
||||
|
||||
#include <boost/compat/invoke.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
int f0()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int f1( int x1 ) noexcept
|
||||
{
|
||||
return x1;
|
||||
}
|
||||
|
||||
int f2( int x1, int x2 )
|
||||
{
|
||||
return 10*x1+x2;
|
||||
}
|
||||
|
||||
int f3( int x1, int x2, int x3 ) noexcept
|
||||
{
|
||||
return 100*x1 + 10*x2 + x3;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( f0 ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( f1, 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( f2, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( f3, 1, 2, 3 ), 123 );
|
||||
|
||||
boost::compat::invoke_r<void>( f0 );
|
||||
boost::compat::invoke_r<void>( f1, 1 );
|
||||
boost::compat::invoke_r<void>( f2, 1, 2 );
|
||||
boost::compat::invoke_r<void>( f3, 1, 2, 3 );
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
56
test/invoke_r_md_constexpr_test.cpp
Normal file
56
test/invoke_r_md_constexpr_test.cpp
Normal file
@@ -0,0 +1,56 @@
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/compat/invoke.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/config/workaround.hpp>
|
||||
|
||||
#define STATIC_ASSERT(...) static_assert((__VA_ARGS__), #__VA_ARGS__)
|
||||
#define BOOST_TEST_EQ(x, y) STATIC_ASSERT((x) == (y))
|
||||
|
||||
struct X
|
||||
{
|
||||
int m = -1;
|
||||
};
|
||||
|
||||
struct Y: public X
|
||||
{
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
constexpr X x = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::m, X() ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::m, x ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::m, &x ), -1 );
|
||||
|
||||
#if !defined(BOOST_NO_CXX14_CONSTEXPR)
|
||||
|
||||
STATIC_ASSERT( boost::compat::invoke_r<void>( &X::m, X() ), true );
|
||||
STATIC_ASSERT( boost::compat::invoke_r<void>( &X::m, x ), true );
|
||||
STATIC_ASSERT( boost::compat::invoke_r<void>( &X::m, &x ), true );
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, >= 1920 && BOOST_MSVC < 1950)
|
||||
{
|
||||
constexpr Y y = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::m, Y() ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::m, y ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::m, &y ), -1 );
|
||||
|
||||
#if !defined(BOOST_NO_CXX14_CONSTEXPR)
|
||||
|
||||
STATIC_ASSERT( boost::compat::invoke_r<void>( &X::m, Y() ), true );
|
||||
STATIC_ASSERT( boost::compat::invoke_r<void>( &X::m, y ), true );
|
||||
STATIC_ASSERT( boost::compat::invoke_r<void>( &X::m, &y ), true );
|
||||
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
99
test/invoke_r_md_noexcept_test.cpp
Normal file
99
test/invoke_r_md_noexcept_test.cpp
Normal file
@@ -0,0 +1,99 @@
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/compat/invoke.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <functional>
|
||||
|
||||
struct X
|
||||
{
|
||||
int m = -1;
|
||||
};
|
||||
|
||||
struct Y: public virtual X
|
||||
{
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::m, X() ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::m, Y() ) ), true );
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::m, X() ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::m, Y() ) ), true );
|
||||
}
|
||||
|
||||
{
|
||||
X x;
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::m, x ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::m, &x ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::m, std::ref(x) ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::m, std::cref(x) ) ), true );
|
||||
}
|
||||
|
||||
{
|
||||
X x;
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::m, x ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::m, &x ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::m, std::ref(x) ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::m, std::cref(x) ) ), true );
|
||||
}
|
||||
|
||||
{
|
||||
Y y;
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::m, y ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::m, &y ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::m, std::ref(y) ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::m, std::cref(y) ) ), true );
|
||||
}
|
||||
|
||||
{
|
||||
Y y;
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::m, y ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::m, &y ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::m, std::ref(y) ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::m, std::cref(y) ) ), true );
|
||||
}
|
||||
|
||||
{
|
||||
X const x = {};
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::m, x ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::m, &x ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::m, std::ref(x) ) ), true );
|
||||
}
|
||||
|
||||
{
|
||||
X const x = {};
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::m, x ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::m, &x ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::m, std::ref(x) ) ), true );
|
||||
}
|
||||
|
||||
{
|
||||
Y const y = {};
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::m, y ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::m, &y ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::m, std::ref(y) ) ), true );
|
||||
}
|
||||
|
||||
{
|
||||
Y const y = {};
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::m, y ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::m, &y ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::m, std::ref(y) ) ), true );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
131
test/invoke_r_md_test.cpp
Normal file
131
test/invoke_r_md_test.cpp
Normal file
@@ -0,0 +1,131 @@
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/compat/invoke.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <functional>
|
||||
|
||||
struct X
|
||||
{
|
||||
int m = -1;
|
||||
};
|
||||
|
||||
struct Y: public virtual X
|
||||
{
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::m, X() ), -1 );
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::m, Y() ), -1 );
|
||||
}
|
||||
|
||||
{
|
||||
X x;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<int const&>( &X::m, x ), -1 );
|
||||
boost::compat::invoke_r<int&>( &X::m, x ) = +1;
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::m, x ), +1 );
|
||||
boost::compat::invoke_r<void>( &X::m, x );
|
||||
}
|
||||
|
||||
{
|
||||
X x;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<int const&>( &X::m, &x ), -1 );
|
||||
boost::compat::invoke_r<int&>( &X::m, &x ) = +1;
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::m, &x ), +1 );
|
||||
boost::compat::invoke_r<void>( &X::m, &x );
|
||||
}
|
||||
|
||||
{
|
||||
X x;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<int const&>( &X::m, std::ref(x) ), -1 );
|
||||
boost::compat::invoke_r<int&>( &X::m, std::ref(x) ) = +1;
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::m, std::ref(x) ), +1 );
|
||||
boost::compat::invoke_r<void>( &X::m, std::ref(x) );
|
||||
}
|
||||
|
||||
{
|
||||
X x;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<int const&>( &X::m, std::cref(x) ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::m, std::cref(x) ), -1 );
|
||||
boost::compat::invoke_r<void>( &X::m, std::cref(x) );
|
||||
}
|
||||
|
||||
{
|
||||
Y y;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<int const&>( &X::m, y ), -1 );
|
||||
boost::compat::invoke_r<int&>( &X::m, y ) = +1;
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::m, y ), +1 );
|
||||
boost::compat::invoke_r<void>( &X::m, y );
|
||||
}
|
||||
|
||||
{
|
||||
Y y;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<int const&>( &X::m, &y ), -1 );
|
||||
boost::compat::invoke_r<int&>( &X::m, &y ) = +1;
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::m, &y ), +1 );
|
||||
boost::compat::invoke_r<void>( &X::m, &y );
|
||||
}
|
||||
|
||||
{
|
||||
Y y;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<int const&>( &X::m, std::ref(y) ), -1 );
|
||||
boost::compat::invoke_r<int&>( &X::m, std::ref(y) ) = +1;
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::m, std::ref(y) ), +1 );
|
||||
boost::compat::invoke_r<void>( &X::m, std::ref(y) );
|
||||
}
|
||||
|
||||
{
|
||||
Y y;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<int const&>( &X::m, std::cref(y) ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::m, std::cref(y) ), -1 );
|
||||
boost::compat::invoke_r<void>( &X::m, std::cref(y) );
|
||||
}
|
||||
|
||||
{
|
||||
X const x = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<int const&>( &X::m, x ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::m, x ), -1 );
|
||||
boost::compat::invoke_r<void>( &X::m, x );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<int const&>( &X::m, &x ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::m, &x ), -1 );
|
||||
boost::compat::invoke_r<void>( &X::m, &x );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<int const&>( &X::m, std::ref(x) ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::m, std::ref(x) ), -1 );
|
||||
boost::compat::invoke_r<void>( &X::m, std::ref(x) );
|
||||
}
|
||||
|
||||
{
|
||||
Y const y = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<int const&>( &X::m, y ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::m, y ), -1 );
|
||||
boost::compat::invoke_r<void>( &X::m, y );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<int const&>( &X::m, &y ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::m, &y ), -1 );
|
||||
boost::compat::invoke_r<void>( &X::m, &y );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<int const&>( &X::m, std::ref(y) ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::m, std::ref(y) ), -1 );
|
||||
boost::compat::invoke_r<void>( &X::m, std::ref(y) );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
134
test/invoke_r_mfn_constexpr_test.cpp
Normal file
134
test/invoke_r_mfn_constexpr_test.cpp
Normal file
@@ -0,0 +1,134 @@
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ == 7
|
||||
# pragma GCC diagnostic ignored "-Wnoexcept-type"
|
||||
#endif
|
||||
|
||||
#include <boost/compat/invoke.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/config/workaround.hpp>
|
||||
|
||||
#define STATIC_ASSERT(...) static_assert((__VA_ARGS__), #__VA_ARGS__)
|
||||
#define BOOST_TEST_EQ(x, y) STATIC_ASSERT((x) == (y))
|
||||
|
||||
struct X
|
||||
{
|
||||
constexpr int f0() const
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
constexpr int f1( int x1 ) const noexcept
|
||||
{
|
||||
return x1;
|
||||
}
|
||||
|
||||
constexpr int f2( int x1, int x2 ) const
|
||||
{
|
||||
return 10*x1+x2;
|
||||
}
|
||||
|
||||
constexpr int f3( int x1, int x2, int x3 ) const noexcept
|
||||
{
|
||||
return 100*x1 + 10*x2 + x3;
|
||||
}
|
||||
};
|
||||
|
||||
struct Y: public X
|
||||
{
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f0, X() ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f1, X(), 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f2, X(), 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f3, X(), 1, 2, 3 ), 123 );
|
||||
|
||||
#if !defined(BOOST_NO_CXX14_CONSTEXPR)
|
||||
|
||||
STATIC_ASSERT( boost::compat::invoke_r<void>( &X::f0, X() ), true );
|
||||
STATIC_ASSERT( boost::compat::invoke_r<void>( &X::f1, X(), 1 ), true );
|
||||
STATIC_ASSERT( boost::compat::invoke_r<void>( &X::f2, X(), 1, 2 ), true );
|
||||
STATIC_ASSERT( boost::compat::invoke_r<void>( &X::f3, X(), 1, 2, 3 ), true );
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f0, Y() ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f1, Y(), 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f2, Y(), 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f3, Y(), 1, 2, 3 ), 123 );
|
||||
|
||||
#if !defined(BOOST_NO_CXX14_CONSTEXPR)
|
||||
|
||||
STATIC_ASSERT( boost::compat::invoke_r<void>( &X::f0, Y() ), true );
|
||||
STATIC_ASSERT( boost::compat::invoke_r<void>( &X::f1, Y(), 1 ), true );
|
||||
STATIC_ASSERT( boost::compat::invoke_r<void>( &X::f2, Y(), 1, 2 ), true );
|
||||
STATIC_ASSERT( boost::compat::invoke_r<void>( &X::f3, Y(), 1, 2, 3 ), true );
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
{
|
||||
constexpr X x = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f0, x ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f1, x, 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f2, x, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f3, x, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f0, &x ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f1, &x, 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f2, &x, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f3, &x, 1, 2, 3 ), 123 );
|
||||
|
||||
#if !defined(BOOST_NO_CXX14_CONSTEXPR)
|
||||
|
||||
STATIC_ASSERT( boost::compat::invoke_r<void>( &X::f0, x ), true );
|
||||
STATIC_ASSERT( boost::compat::invoke_r<void>( &X::f1, x, 1 ), true );
|
||||
STATIC_ASSERT( boost::compat::invoke_r<void>( &X::f2, x, 1, 2 ), true );
|
||||
STATIC_ASSERT( boost::compat::invoke_r<void>( &X::f3, x, 1, 2, 3 ), true );
|
||||
|
||||
STATIC_ASSERT( boost::compat::invoke_r<void>( &X::f0, &x ), true );
|
||||
STATIC_ASSERT( boost::compat::invoke_r<void>( &X::f1, &x, 1 ), true );
|
||||
STATIC_ASSERT( boost::compat::invoke_r<void>( &X::f2, &x, 1, 2 ), true );
|
||||
STATIC_ASSERT( boost::compat::invoke_r<void>( &X::f3, &x, 1, 2, 3 ), true );
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1910)
|
||||
{
|
||||
constexpr Y y = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f0, y ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f1, y, 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f2, y, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f3, y, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f0, &y ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f1, &y, 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f2, &y, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f3, &y, 1, 2, 3 ), 123 );
|
||||
|
||||
#if !defined(BOOST_NO_CXX14_CONSTEXPR)
|
||||
|
||||
STATIC_ASSERT( boost::compat::invoke_r<void>( &X::f0, y ), true );
|
||||
STATIC_ASSERT( boost::compat::invoke_r<void>( &X::f1, y, 1 ), true );
|
||||
STATIC_ASSERT( boost::compat::invoke_r<void>( &X::f2, y, 1, 2 ), true );
|
||||
STATIC_ASSERT( boost::compat::invoke_r<void>( &X::f3, y, 1, 2, 3 ), true );
|
||||
|
||||
STATIC_ASSERT( boost::compat::invoke_r<void>( &X::f0, &y ), true );
|
||||
STATIC_ASSERT( boost::compat::invoke_r<void>( &X::f1, &y, 1 ), true );
|
||||
STATIC_ASSERT( boost::compat::invoke_r<void>( &X::f2, &y, 1, 2 ), true );
|
||||
STATIC_ASSERT( boost::compat::invoke_r<void>( &X::f3, &y, 1, 2, 3 ), true );
|
||||
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
214
test/invoke_r_mfn_noexcept_test.cpp
Normal file
214
test/invoke_r_mfn_noexcept_test.cpp
Normal file
@@ -0,0 +1,214 @@
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/config/pragma_message.hpp>
|
||||
|
||||
#if !defined(__cpp_noexcept_function_type)
|
||||
|
||||
BOOST_PRAGMA_MESSAGE( "Test skipped, __cpp_noexcept_function_type is not defined" )
|
||||
int main() {}
|
||||
|
||||
#else
|
||||
|
||||
#include <boost/compat/invoke.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <functional>
|
||||
|
||||
struct X
|
||||
{
|
||||
int f0()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int f1( int x1 ) noexcept
|
||||
{
|
||||
return x1;
|
||||
}
|
||||
|
||||
int f2( int x1, int x2 ) const
|
||||
{
|
||||
return 10*x1+x2;
|
||||
}
|
||||
|
||||
int f3( int x1, int x2, int x3 ) const noexcept
|
||||
{
|
||||
return 100*x1 + 10*x2 + x3;
|
||||
}
|
||||
};
|
||||
|
||||
struct Y: public virtual X
|
||||
{
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::f0, X() ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::f1, X(), 1 ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::f2, X(), 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::f3, X(), 1, 2, 3 ) ), true );
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::f0, X() ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::f1, X(), 1 ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::f2, X(), 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::f3, X(), 1, 2, 3 ) ), true );
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::f0, Y() ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::f1, Y(), 1 ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::f2, Y(), 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::f3, Y(), 1, 2, 3 ) ), true );
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::f0, Y() ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::f1, Y(), 1 ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::f2, Y(), 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::f3, Y(), 1, 2, 3 ) ), true );
|
||||
}
|
||||
|
||||
{
|
||||
X x;
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::f0, x ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::f1, x, 1 ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::f2, x, 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::f3, x, 1, 2, 3 ) ), true );
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::f0, &x ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::f1, &x, 1 ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::f2, &x, 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::f3, &x, 1, 2, 3 ) ), true );
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::f0, std::ref(x) ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::f1, std::ref(x), 1 ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::f2, std::ref(x), 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::f3, std::ref(x), 1, 2, 3 ) ), true );
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::f2, std::cref(x), 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::f3, std::cref(x), 1, 2, 3 ) ), true );
|
||||
}
|
||||
|
||||
{
|
||||
X x;
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::f0, x ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::f1, x, 1 ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::f2, x, 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::f3, x, 1, 2, 3 ) ), true );
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::f0, &x ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::f1, &x, 1 ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::f2, &x, 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::f3, &x, 1, 2, 3 ) ), true );
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::f0, std::ref(x) ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::f1, std::ref(x), 1 ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::f2, std::ref(x), 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::f3, std::ref(x), 1, 2, 3 ) ), true );
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::f2, std::cref(x), 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::f3, std::cref(x), 1, 2, 3 ) ), true );
|
||||
}
|
||||
|
||||
{
|
||||
Y y;
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::f0, y ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::f1, y, 1 ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::f2, y, 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::f3, y, 1, 2, 3 ) ), true );
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::f0, &y ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::f1, &y, 1 ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::f2, &y, 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::f3, &y, 1, 2, 3 ) ), true );
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::f0, std::ref(y) ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::f1, std::ref(y), 1 ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::f2, std::ref(y), 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::f3, std::ref(y), 1, 2, 3 ) ), true );
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::f2, std::cref(y), 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::f3, std::cref(y), 1, 2, 3 ) ), true );
|
||||
}
|
||||
|
||||
{
|
||||
Y y;
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::f0, y ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::f1, y, 1 ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::f2, y, 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::f3, y, 1, 2, 3 ) ), true );
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::f0, &y ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::f1, &y, 1 ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::f2, &y, 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::f3, &y, 1, 2, 3 ) ), true );
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::f0, std::ref(y) ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::f1, std::ref(y), 1 ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::f2, std::ref(y), 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::f3, std::ref(y), 1, 2, 3 ) ), true );
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::f2, std::cref(y), 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::f3, std::cref(y), 1, 2, 3 ) ), true );
|
||||
}
|
||||
|
||||
{
|
||||
X const x = {};
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::f2, x, 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::f3, x, 1, 2, 3 ) ), true );
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::f2, &x, 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::f3, &x, 1, 2, 3 ) ), true );
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::f2, std::ref(x), 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::f3, std::ref(x), 1, 2, 3 ) ), true );
|
||||
}
|
||||
|
||||
{
|
||||
X const x = {};
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::f2, x, 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::f3, x, 1, 2, 3 ) ), true );
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::f2, &x, 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::f3, &x, 1, 2, 3 ) ), true );
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::f2, std::ref(x), 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::f3, std::ref(x), 1, 2, 3 ) ), true );
|
||||
}
|
||||
|
||||
{
|
||||
Y const y = {};
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::f2, y, 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::f3, y, 1, 2, 3 ) ), true );
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::f2, &y, 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::f3, &y, 1, 2, 3 ) ), true );
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::f2, std::ref(y), 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( &X::f3, std::ref(y), 1, 2, 3 ) ), true );
|
||||
}
|
||||
|
||||
{
|
||||
Y const y = {};
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::f2, y, 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::f3, y, 1, 2, 3 ) ), true );
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::f2, &y, 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::f3, &y, 1, 2, 3 ) ), true );
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::f2, std::ref(y), 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( &X::f3, std::ref(y), 1, 2, 3 ) ), true );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
#endif
|
||||
211
test/invoke_r_mfn_test.cpp
Normal file
211
test/invoke_r_mfn_test.cpp
Normal file
@@ -0,0 +1,211 @@
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ == 7
|
||||
# pragma GCC diagnostic ignored "-Wnoexcept-type"
|
||||
#endif
|
||||
|
||||
#include <boost/compat/invoke.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <functional>
|
||||
|
||||
struct X
|
||||
{
|
||||
int f0()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int f1( int x1 ) noexcept
|
||||
{
|
||||
return x1;
|
||||
}
|
||||
|
||||
int f2( int x1, int x2 ) const
|
||||
{
|
||||
return 10*x1+x2;
|
||||
}
|
||||
|
||||
int f3( int x1, int x2, int x3 ) const noexcept
|
||||
{
|
||||
return 100*x1 + 10*x2 + x3;
|
||||
}
|
||||
};
|
||||
|
||||
struct Y: public virtual X
|
||||
{
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f0, X() ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f1, X(), 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f2, X(), 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f3, X(), 1, 2, 3 ), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f0, Y() ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f1, Y(), 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f2, Y(), 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f3, Y(), 1, 2, 3 ), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
X x;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f0, x ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f1, x, 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f2, x, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f3, x, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f0, &x ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f1, &x, 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f2, &x, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f3, &x, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f0, std::ref(x) ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f1, std::ref(x), 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f2, std::ref(x), 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f3, std::ref(x), 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f2, std::cref(x), 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f3, std::cref(x), 1, 2, 3 ), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
Y y;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f0, y ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f1, y, 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f2, y, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f3, y, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f0, &y ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f1, &y, 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f2, &y, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f3, &y, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f0, std::ref(y) ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f1, std::ref(y), 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f2, std::ref(y), 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f3, std::ref(y), 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f2, std::cref(y), 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f3, std::cref(y), 1, 2, 3 ), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
X const x = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f2, x, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f3, x, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f2, &x, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f3, &x, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f2, std::ref(x), 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f3, std::ref(x), 1, 2, 3 ), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
Y const y = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f2, y, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f3, y, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f2, &y, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f3, &y, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f2, std::ref(y), 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( &X::f3, std::ref(y), 1, 2, 3 ), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::compat::invoke_r<void>( &X::f0, X() );
|
||||
boost::compat::invoke_r<void>( &X::f1, X(), 1 );
|
||||
boost::compat::invoke_r<void>( &X::f2, X(), 1, 2 );
|
||||
boost::compat::invoke_r<void>( &X::f3, X(), 1, 2, 3 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::compat::invoke_r<void>( &X::f0, Y() );
|
||||
boost::compat::invoke_r<void>( &X::f1, Y(), 1 );
|
||||
boost::compat::invoke_r<void>( &X::f2, Y(), 1, 2 );
|
||||
boost::compat::invoke_r<void>( &X::f3, Y(), 1, 2, 3 );
|
||||
}
|
||||
|
||||
{
|
||||
X x;
|
||||
|
||||
boost::compat::invoke_r<void>( &X::f0, x );
|
||||
boost::compat::invoke_r<void>( &X::f1, x, 1 );
|
||||
boost::compat::invoke_r<void>( &X::f2, x, 1, 2 );
|
||||
boost::compat::invoke_r<void>( &X::f3, x, 1, 2, 3 );
|
||||
|
||||
boost::compat::invoke_r<void>( &X::f0, &x );
|
||||
boost::compat::invoke_r<void>( &X::f1, &x, 1 );
|
||||
boost::compat::invoke_r<void>( &X::f2, &x, 1, 2 );
|
||||
boost::compat::invoke_r<void>( &X::f3, &x, 1, 2, 3 );
|
||||
|
||||
boost::compat::invoke_r<void>( &X::f0, std::ref(x) );
|
||||
boost::compat::invoke_r<void>( &X::f1, std::ref(x), 1 );
|
||||
boost::compat::invoke_r<void>( &X::f2, std::ref(x), 1, 2 );
|
||||
boost::compat::invoke_r<void>( &X::f3, std::ref(x), 1, 2, 3 );
|
||||
|
||||
boost::compat::invoke_r<void>( &X::f2, std::cref(x), 1, 2 );
|
||||
boost::compat::invoke_r<void>( &X::f3, std::cref(x), 1, 2, 3 );
|
||||
}
|
||||
|
||||
{
|
||||
Y y;
|
||||
|
||||
boost::compat::invoke_r<void>( &X::f0, y );
|
||||
boost::compat::invoke_r<void>( &X::f1, y, 1 );
|
||||
boost::compat::invoke_r<void>( &X::f2, y, 1, 2 );
|
||||
boost::compat::invoke_r<void>( &X::f3, y, 1, 2, 3 );
|
||||
|
||||
boost::compat::invoke_r<void>( &X::f0, &y );
|
||||
boost::compat::invoke_r<void>( &X::f1, &y, 1 );
|
||||
boost::compat::invoke_r<void>( &X::f2, &y, 1, 2 );
|
||||
boost::compat::invoke_r<void>( &X::f3, &y, 1, 2, 3 );
|
||||
|
||||
boost::compat::invoke_r<void>( &X::f0, std::ref(y) );
|
||||
boost::compat::invoke_r<void>( &X::f1, std::ref(y), 1 );
|
||||
boost::compat::invoke_r<void>( &X::f2, std::ref(y), 1, 2 );
|
||||
boost::compat::invoke_r<void>( &X::f3, std::ref(y), 1, 2, 3 );
|
||||
|
||||
boost::compat::invoke_r<void>( &X::f2, std::cref(y), 1, 2 );
|
||||
boost::compat::invoke_r<void>( &X::f3, std::cref(y), 1, 2, 3 );
|
||||
}
|
||||
|
||||
{
|
||||
X const x = {};
|
||||
|
||||
boost::compat::invoke_r<void>( &X::f2, x, 1, 2 );
|
||||
boost::compat::invoke_r<void>( &X::f3, x, 1, 2, 3 );
|
||||
|
||||
boost::compat::invoke_r<void>( &X::f2, &x, 1, 2 );
|
||||
boost::compat::invoke_r<void>( &X::f3, &x, 1, 2, 3 );
|
||||
|
||||
boost::compat::invoke_r<void>( &X::f2, std::ref(x), 1, 2 );
|
||||
boost::compat::invoke_r<void>( &X::f3, std::ref(x), 1, 2, 3 );
|
||||
}
|
||||
|
||||
{
|
||||
Y const y = {};
|
||||
|
||||
boost::compat::invoke_r<long>( &X::f2, y, 1, 2 );
|
||||
boost::compat::invoke_r<long>( &X::f3, y, 1, 2, 3 );
|
||||
|
||||
boost::compat::invoke_r<long>( &X::f2, &y, 1, 2 );
|
||||
boost::compat::invoke_r<long>( &X::f3, &y, 1, 2, 3 );
|
||||
|
||||
boost::compat::invoke_r<long>( &X::f2, std::ref(y), 1, 2 );
|
||||
boost::compat::invoke_r<long>( &X::f3, std::ref(y), 1, 2, 3 );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
68
test/invoke_r_obj_constexpr_test.cpp
Normal file
68
test/invoke_r_obj_constexpr_test.cpp
Normal file
@@ -0,0 +1,68 @@
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/compat/invoke.hpp>
|
||||
|
||||
#define STATIC_ASSERT(...) static_assert((__VA_ARGS__), #__VA_ARGS__)
|
||||
#define BOOST_TEST_EQ(x, y) STATIC_ASSERT((x) == (y))
|
||||
|
||||
struct F
|
||||
{
|
||||
constexpr int operator()() const
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
constexpr int operator()( int x1 ) const noexcept
|
||||
{
|
||||
return x1;
|
||||
}
|
||||
|
||||
constexpr int operator()( int x1, int x2 ) const
|
||||
{
|
||||
return 10*x1+x2;
|
||||
}
|
||||
|
||||
constexpr int operator()( int x1, int x2, int x3 ) const noexcept
|
||||
{
|
||||
return 100*x1 + 10*x2 + x3;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( F() ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( F(), 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( F(), 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( F(), 1, 2, 3 ), 123 );
|
||||
|
||||
#if !defined(BOOST_NO_CXX14_CONSTEXPR)
|
||||
|
||||
STATIC_ASSERT( boost::compat::invoke_r<void>( F() ), true );
|
||||
STATIC_ASSERT( boost::compat::invoke_r<void>( F(), 1 ), true );
|
||||
STATIC_ASSERT( boost::compat::invoke_r<void>( F(), 1, 2 ), true );
|
||||
STATIC_ASSERT( boost::compat::invoke_r<void>( F(), 1, 2, 3 ), true );
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
{
|
||||
constexpr F f = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( f ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( f, 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( f, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( f, 1, 2, 3 ), 123 );
|
||||
|
||||
#if !defined(BOOST_NO_CXX14_CONSTEXPR)
|
||||
|
||||
STATIC_ASSERT( boost::compat::invoke_r<void>( f ), true );
|
||||
STATIC_ASSERT( boost::compat::invoke_r<void>( f, 1 ), true );
|
||||
STATIC_ASSERT( boost::compat::invoke_r<void>( f, 1, 2 ), true );
|
||||
STATIC_ASSERT( boost::compat::invoke_r<void>( f, 1, 2, 3 ), true );
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
70
test/invoke_r_obj_noexcept_test.cpp
Normal file
70
test/invoke_r_obj_noexcept_test.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/compat/invoke.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
struct F
|
||||
{
|
||||
int operator()()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int operator()( int x1 ) noexcept
|
||||
{
|
||||
return x1;
|
||||
}
|
||||
|
||||
int operator()( int x1, int x2 ) const
|
||||
{
|
||||
return 10*x1+x2;
|
||||
}
|
||||
|
||||
int operator()( int x1, int x2, int x3 ) const noexcept
|
||||
{
|
||||
return 100*x1 + 10*x2 + x3;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( F() ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( F(), 1 ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( F(), 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( F(), 1, 2, 3 ) ), true );
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( F() ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( F(), 1 ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( F(), 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( F(), 1, 2, 3 ) ), true );
|
||||
}
|
||||
|
||||
{
|
||||
F f = {};
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( f ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( f, 1 ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( f, 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( f, 1, 2, 3 ) ), true );
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( f ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( f, 1 ) ), true );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( f, 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( f, 1, 2, 3 ) ), true );
|
||||
}
|
||||
|
||||
{
|
||||
F const f = {};
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( f, 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<long>( f, 1, 2, 3 ) ), true );
|
||||
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( f, 1, 2 ) ), false );
|
||||
BOOST_TEST_EQ( noexcept( boost::compat::invoke_r<void>( f, 1, 2, 3 ) ), true );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
80
test/invoke_r_obj_test.cpp
Normal file
80
test/invoke_r_obj_test.cpp
Normal file
@@ -0,0 +1,80 @@
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/compat/invoke.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
struct F
|
||||
{
|
||||
int operator()()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int operator()( int x1 ) noexcept
|
||||
{
|
||||
return x1;
|
||||
}
|
||||
|
||||
int operator()( int x1, int x2 ) const
|
||||
{
|
||||
return 10*x1+x2;
|
||||
}
|
||||
|
||||
int operator()( int x1, int x2, int x3 ) const noexcept
|
||||
{
|
||||
return 100*x1 + 10*x2 + x3;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( F() ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( F(), 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( F(), 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( F(), 1, 2, 3 ), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
F f;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( f ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( f, 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( f, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( f, 1, 2, 3 ), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
F const f = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( f, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::invoke_r<long>( f, 1, 2, 3 ), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
boost::compat::invoke_r<void>( F() );
|
||||
boost::compat::invoke_r<void>( F(), 1 );
|
||||
boost::compat::invoke_r<void>( F(), 1, 2 );
|
||||
boost::compat::invoke_r<void>( F(), 1, 2, 3 );
|
||||
}
|
||||
|
||||
{
|
||||
F f;
|
||||
|
||||
boost::compat::invoke_r<void>( f );
|
||||
boost::compat::invoke_r<void>( f, 1 );
|
||||
boost::compat::invoke_r<void>( f, 1, 2 );
|
||||
boost::compat::invoke_r<void>( f, 1, 2, 3 );
|
||||
}
|
||||
|
||||
{
|
||||
F const f = {};
|
||||
|
||||
boost::compat::invoke_r<void>( f, 1, 2 );
|
||||
boost::compat::invoke_r<void>( f, 1, 2, 3 );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
107
test/invoke_result_test.cpp
Normal file
107
test/invoke_result_test.cpp
Normal file
@@ -0,0 +1,107 @@
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/compat/invoke.hpp>
|
||||
#include <boost/core/lightweight_test_trait.hpp>
|
||||
#include <boost/mp11/utility.hpp>
|
||||
|
||||
struct F
|
||||
{
|
||||
void operator()()
|
||||
{
|
||||
}
|
||||
|
||||
char operator()( char x1 ) noexcept
|
||||
{
|
||||
return x1;
|
||||
}
|
||||
|
||||
int operator()( int x1, int x2 ) const
|
||||
{
|
||||
return 10*x1+x2;
|
||||
}
|
||||
|
||||
double operator()( float x1, float x2, float x3 ) const noexcept
|
||||
{
|
||||
return 100*x1 + 10*x2 + x3;
|
||||
}
|
||||
};
|
||||
|
||||
struct X
|
||||
{
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
using boost::compat::invoke_result_t;
|
||||
using boost::mp11::mp_valid;
|
||||
|
||||
// nonfunction
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( mp_valid<invoke_result_t, int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( mp_valid<invoke_result_t, int, int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( mp_valid<invoke_result_t, int, int, int> ));
|
||||
|
||||
// function reference
|
||||
|
||||
BOOST_TEST_TRAIT_SAME( invoke_result_t<void(&)()>, void );
|
||||
BOOST_TEST_TRAIT_SAME( invoke_result_t<char(&)(int), char>, char );
|
||||
BOOST_TEST_TRAIT_SAME( invoke_result_t<int(&)(int, int), int, int>, int );
|
||||
BOOST_TEST_TRAIT_SAME( invoke_result_t<double(&)(double, double, double), float, float, float>, double );
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( mp_valid<invoke_result_t, void(&)(), int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( mp_valid<invoke_result_t, char(&)(int)> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( mp_valid<invoke_result_t, char(&)(int), int, int> ));
|
||||
|
||||
// function pointer
|
||||
|
||||
BOOST_TEST_TRAIT_SAME( invoke_result_t<void(*)()>, void );
|
||||
BOOST_TEST_TRAIT_SAME( invoke_result_t<char(*)(int), char>, char );
|
||||
BOOST_TEST_TRAIT_SAME( invoke_result_t<int(*)(int, int), int, int>, int );
|
||||
BOOST_TEST_TRAIT_SAME( invoke_result_t<double(*)(double, double, double), float, float, float>, double );
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( mp_valid<invoke_result_t, void(*)(), int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( mp_valid<invoke_result_t, char(*)(int)> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( mp_valid<invoke_result_t, char(*)(int), int, int> ));
|
||||
|
||||
// object
|
||||
|
||||
BOOST_TEST_TRAIT_SAME( invoke_result_t<F>, void );
|
||||
BOOST_TEST_TRAIT_SAME( invoke_result_t<F, char>, char );
|
||||
BOOST_TEST_TRAIT_SAME( invoke_result_t<F, int, int>, int );
|
||||
BOOST_TEST_TRAIT_SAME( invoke_result_t<F, float, float, float>, double );
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( mp_valid<invoke_result_t, F, int, int, int, int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( mp_valid<invoke_result_t, F const> ));
|
||||
|
||||
// member function pointer
|
||||
|
||||
BOOST_TEST_TRAIT_SAME( invoke_result_t<void(X::*)(), X>, void );
|
||||
BOOST_TEST_TRAIT_SAME( invoke_result_t<char(X::*)(int), X, char>, char );
|
||||
BOOST_TEST_TRAIT_SAME( invoke_result_t<int(X::*)(int, int), X, int, int>, int );
|
||||
BOOST_TEST_TRAIT_SAME( invoke_result_t<double(X::*)(double, double, double), X, float, float, float>, double );
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( mp_valid<invoke_result_t, void(X::*)()> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( mp_valid<invoke_result_t, void(X::*)(), int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( mp_valid<invoke_result_t, void(X::*)(), X, int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( mp_valid<invoke_result_t, char(X::*)(int)> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( mp_valid<invoke_result_t, char(X::*)(int), int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( mp_valid<invoke_result_t, char(X::*)(int), X> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( mp_valid<invoke_result_t, char(X::*)(int), X, int, int> ));
|
||||
|
||||
// member data pointer
|
||||
|
||||
BOOST_TEST_TRAIT_SAME( invoke_result_t<int X::*, X>, int&& );
|
||||
BOOST_TEST_TRAIT_SAME( invoke_result_t<int X::*, X const>, int const&& );
|
||||
BOOST_TEST_TRAIT_SAME( invoke_result_t<int X::*, X&>, int& );
|
||||
BOOST_TEST_TRAIT_SAME( invoke_result_t<int X::*, X const&>, int const& );
|
||||
BOOST_TEST_TRAIT_SAME( invoke_result_t<int X::*, X*>, int& );
|
||||
BOOST_TEST_TRAIT_SAME( invoke_result_t<int X::*, X const*>, int const& );
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( mp_valid<invoke_result_t, int X::*> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( mp_valid<invoke_result_t, int X::*, int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( mp_valid<invoke_result_t, int X::*, X, int> ));
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
195
test/is_invocable_r_test.cpp
Normal file
195
test/is_invocable_r_test.cpp
Normal file
@@ -0,0 +1,195 @@
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/compat/invoke.hpp>
|
||||
#include <boost/core/lightweight_test_trait.hpp>
|
||||
|
||||
struct F
|
||||
{
|
||||
void operator()()
|
||||
{
|
||||
}
|
||||
|
||||
char operator()( char x1 ) noexcept
|
||||
{
|
||||
return x1;
|
||||
}
|
||||
|
||||
int operator()( int x1, int x2 ) const
|
||||
{
|
||||
return 10*x1+x2;
|
||||
}
|
||||
|
||||
double operator()( float x1, float x2, float x3 ) const noexcept
|
||||
{
|
||||
return 100*x1 + 10*x2 + x3;
|
||||
}
|
||||
};
|
||||
|
||||
struct X
|
||||
{
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
using boost::compat::is_invocable_r;
|
||||
|
||||
// nonfunction
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<long, int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<long, int, int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<long, int, int, int> ));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<void, int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<void, int, int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<void, int, int, int> ));
|
||||
|
||||
// function reference
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<long, void(&)()> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable_r<long, char(&)(int), char> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable_r<long, int(&)(int, int), int, int> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable_r<long, double(&)(double, double, double), float, float, float> ));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable_r<void, void(&)()> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable_r<void, char(&)(int), char> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable_r<void, int(&)(int, int), int, int> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable_r<void, double(&)(double, double, double), float, float, float> ));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<X, void(&)()> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<X, char(&)(int), char> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<X, int(&)(int, int), int, int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<X, double(&)(double, double, double), float, float, float> ));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<long, void(&)(), int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<long, char(&)(int)> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<long, char(&)(int), int, int> ));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<void, void(&)(), int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<void, char(&)(int)> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<void, char(&)(int), int, int> ));
|
||||
|
||||
// function pointer
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<long, void(*)()> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable_r<long, char(*)(int), char> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable_r<long, int(*)(int, int), int, int> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable_r<long, double(*)(double, double, double), float, float, float> ));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable_r<void, void(*)()> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable_r<void, char(*)(int), char> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable_r<void, int(*)(int, int), int, int> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable_r<void, double(*)(double, double, double), float, float, float> ));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<X, void(*)()> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<X, char(*)(int), char> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<X, int(*)(int, int), int, int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<X, double(*)(double, double, double), float, float, float> ));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<long, void(*)(), int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<long, char(*)(int)> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<long, char(*)(int), int, int> ));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<void, void(*)(), int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<void, char(*)(int)> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<void, char(*)(int), int, int> ));
|
||||
|
||||
// object
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<long, F> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable_r<long, F, char> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable_r<long, F, int, int> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable_r<long, F, float, float, float> ));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable_r<void, F> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable_r<void, F, char> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable_r<void, F, int, int> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable_r<void, F, float, float, float> ));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<X, F> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<X, F, char> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<X, F, int, int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<X, F, float, float, float> ));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<long, F, int, int, int, int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<long, F const> ));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<void, F, int, int, int, int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<void, F const> ));
|
||||
|
||||
// member function pointer
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<long, void(X::*)(), X> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable_r<long, char(X::*)(int), X, char> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable_r<long, int(X::*)(int, int), X, int, int> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable_r<long, double(X::*)(double, double, double), X, float, float, float> ));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable_r<void, void(X::*)(), X> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable_r<void, char(X::*)(int), X, char> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable_r<void, int(X::*)(int, int), X, int, int> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable_r<void, double(X::*)(double, double, double), X, float, float, float> ));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<X, void(X::*)(), X> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<X, char(X::*)(int), X, char> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<X, int(X::*)(int, int), X, int, int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<X, double(X::*)(double, double, double), X, float, float, float> ));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<long, void(X::*)()> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<long, void(X::*)(), int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<long, void(X::*)(), X, int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<long, char(X::*)(int)> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<long, char(X::*)(int), int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<long, char(X::*)(int), X> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<long, char(X::*)(int), X, int, int> ));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<void, void(X::*)()> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<void, void(X::*)(), int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<void, void(X::*)(), X, int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<void, char(X::*)(int)> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<void, char(X::*)(int), int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<void, char(X::*)(int), X> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<void, char(X::*)(int), X, int, int> ));
|
||||
|
||||
// member data pointer
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable_r<long, int X::*, X> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable_r<long, int X::*, X const> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable_r<long, int X::*, X&> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable_r<long, int X::*, X const&> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable_r<long, int X::*, X*> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable_r<long, int X::*, X const*> ));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable_r<void, int X::*, X> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable_r<void, int X::*, X const> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable_r<void, int X::*, X&> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable_r<void, int X::*, X const&> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable_r<void, int X::*, X*> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable_r<void, int X::*, X const*> ));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<X, int X::*, X> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<X, int X::*, X const> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<X, int X::*, X&> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<X, int X::*, X const&> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<X, int X::*, X*> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<X, int X::*, X const*> ));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<int&, int X::*, X> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<int&, int X::*, X const> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable_r<int&, int X::*, X&> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<int&, int X::*, X const&> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable_r<int&, int X::*, X*> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<int&, int X::*, X const*> ));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable_r<int&&, int X::*, X> ));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<long, int X::*> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<long, int X::*, int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<long, int X::*, X, int> ));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<void, int X::*> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<void, int X::*, int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable_r<void, int X::*, X, int> ));
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
105
test/is_invocable_test.cpp
Normal file
105
test/is_invocable_test.cpp
Normal file
@@ -0,0 +1,105 @@
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/compat/invoke.hpp>
|
||||
#include <boost/core/lightweight_test_trait.hpp>
|
||||
|
||||
struct F
|
||||
{
|
||||
void operator()()
|
||||
{
|
||||
}
|
||||
|
||||
char operator()( char x1 ) noexcept
|
||||
{
|
||||
return x1;
|
||||
}
|
||||
|
||||
int operator()( int x1, int x2 ) const
|
||||
{
|
||||
return 10*x1+x2;
|
||||
}
|
||||
|
||||
double operator()( float x1, float x2, float x3 ) const noexcept
|
||||
{
|
||||
return 100*x1 + 10*x2 + x3;
|
||||
}
|
||||
};
|
||||
|
||||
struct X
|
||||
{
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
using boost::compat::is_invocable;
|
||||
|
||||
// nonfunction
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable<int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable<int, int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable<int, int, int> ));
|
||||
|
||||
// function reference
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable<void(&)()> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable<char(&)(int), char> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable<int(&)(int, int), int, int> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable<double(&)(double, double, double), float, float, float> ));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable<void(&)(), int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable<char(&)(int)> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable<char(&)(int), int, int> ));
|
||||
|
||||
// function pointer
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable<void(*)()> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable<char(*)(int), char> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable<int(*)(int, int), int, int> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable<double(*)(double, double, double), float, float, float> ));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable<void(*)(), int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable<char(*)(int)> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable<char(*)(int), int, int> ));
|
||||
|
||||
// object
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable<F> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable<F, char> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable<F, int, int> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable<F, float, float, float> ));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable<F, int, int, int, int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable<F const> ));
|
||||
|
||||
// member function pointer
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable<void(X::*)(), X> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable<char(X::*)(int), X, char> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable<int(X::*)(int, int), X, int, int> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable<double(X::*)(double, double, double), X, float, float, float> ));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable<void(X::*)()> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable<void(X::*)(), int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable<void(X::*)(), X, int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable<char(X::*)(int)> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable<char(X::*)(int), int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable<char(X::*)(int), X> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable<char(X::*)(int), X, int, int> ));
|
||||
|
||||
// member data pointer
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable<int X::*, X> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable<int X::*, X const> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable<int X::*, X&> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable<int X::*, X const&> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable<int X::*, X*> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_invocable<int X::*, X const*> ));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable<int X::*> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable<int X::*, int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_invocable<int X::*, X, int> ));
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
288
test/is_nothrow_invocable_r_test.cpp
Normal file
288
test/is_nothrow_invocable_r_test.cpp
Normal file
@@ -0,0 +1,288 @@
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/compat/invoke.hpp>
|
||||
#include <boost/core/lightweight_test_trait.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/config/workaround.hpp>
|
||||
|
||||
struct F
|
||||
{
|
||||
void operator()()
|
||||
{
|
||||
}
|
||||
|
||||
char operator()( char x1 ) noexcept
|
||||
{
|
||||
return x1;
|
||||
}
|
||||
|
||||
int operator()( int x1, int x2 ) const
|
||||
{
|
||||
return 10*x1+x2;
|
||||
}
|
||||
|
||||
double operator()( float x1, float x2, float x3 ) const noexcept
|
||||
{
|
||||
return 100*x1 + 10*x2 + x3;
|
||||
}
|
||||
};
|
||||
|
||||
struct X
|
||||
{
|
||||
};
|
||||
|
||||
struct Y
|
||||
{
|
||||
Y( int );
|
||||
Y( double ) noexcept;
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
using boost::compat::is_nothrow_invocable_r;
|
||||
|
||||
// nonfunction
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<long, int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<long, int, int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<long, int, int, int> ));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<void, int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<void, int, int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<void, int, int, int> ));
|
||||
|
||||
// function reference
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<long, void(&)()> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<long, char(&)(int), char> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<long, int(&)(int, int), int, int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<long, double(&)(double, double, double), float, float, float> ));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<void, void(&)()> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<void, char(&)(int), char> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<void, int(&)(int, int), int, int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<void, double(&)(double, double, double), float, float, float> ));
|
||||
|
||||
#if defined(__cpp_noexcept_function_type)
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<long, void(&)() noexcept> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r<long, char(&)(int) noexcept, char> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r<long, int(&)(int, int) noexcept, int, int> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r<long, double(&)(double, double, double) noexcept, float, float, float> ));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r<void, void(&)() noexcept> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r<void, char(&)(int) noexcept, char> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r<void, int(&)(int, int) noexcept, int, int> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r<void, double(&)(double, double, double) noexcept, float, float, float> ));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<X, void(&)() noexcept> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<X, char(&)(int) noexcept, char> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<X, int(&)(int, int) noexcept, int, int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<X, double(&)(double, double, double) noexcept, float, float, float> ));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<Y, void(&)() noexcept> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<Y, char(&)(int) noexcept, char> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<Y, int(&)(int, int) noexcept, int, int> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r<Y, double(&)(double, double, double) noexcept, float, float, float> ));
|
||||
|
||||
#endif
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<long, void(&)(), int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<long, char(&)(int)> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<long, char(&)(int), int, int> ));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<void, void(&)(), int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<void, char(&)(int)> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<void, char(&)(int), int, int> ));
|
||||
|
||||
// function pointer
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<long, void(*)()> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<long, char(*)(int), char> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<long, int(*)(int, int), int, int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<long, double(*)(double, double, double), float, float, float> ));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<void, void(*)()> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<void, char(*)(int), char> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<void, int(*)(int, int), int, int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<void, double(*)(double, double, double), float, float, float> ));
|
||||
|
||||
#if defined(__cpp_noexcept_function_type)
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<long, void(*)() noexcept> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r<long, char(*)(int) noexcept, char> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r<long, int(*)(int, int) noexcept, int, int> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r<long, double(*)(double, double, double) noexcept, float, float, float> ));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r<void, void(*)() noexcept> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r<void, char(*)(int) noexcept, char> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r<void, int(*)(int, int) noexcept, int, int> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r<void, double(*)(double, double, double) noexcept, float, float, float> ));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<X, void(*)() noexcept> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<X, char(*)(int) noexcept, char> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<X, int(*)(int, int) noexcept, int, int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<X, double(*)(double, double, double) noexcept, float, float, float> ));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<Y, void(*)() noexcept> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<Y, char(*)(int) noexcept, char> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<Y, int(*)(int, int) noexcept, int, int> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r<Y, double(*)(double, double, double) noexcept, float, float, float> ));
|
||||
|
||||
#endif
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<long, void(*)(), int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<long, char(*)(int)> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<long, char(*)(int), int, int> ));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<void, void(*)(), int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<void, char(*)(int)> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<void, char(*)(int), int, int> ));
|
||||
|
||||
// object
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<long, F> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<long, F, int, int> ));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<void, F> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<void, F, int, int> ));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<X, F> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<X, F, int, int> ));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<Y, F> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<Y, F, int, int> ));
|
||||
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1910)
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r<long, F, char> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r<long, F, float, float, float> ));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r<void, F, char> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r<void, F, float, float, float> ));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<X, F, char> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<X, F, float, float, float> ));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<Y, F, char> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r<Y, F, float, float, float> ));
|
||||
|
||||
#endif
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<long, F, int, int, int, int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<long, F const> ));
|
||||
|
||||
// member function pointer
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<long, void(X::*)(), X> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<long, char(X::*)(int), X, char> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<long, int(X::*)(int, int), X, int, int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<long, double(X::*)(double, double, double), X, float, float, float> ));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<void, void(X::*)(), X> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<void, char(X::*)(int), X, char> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<void, int(X::*)(int, int), X, int, int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<void, double(X::*)(double, double, double), X, float, float, float> ));
|
||||
|
||||
#if defined(__cpp_noexcept_function_type)
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<long, void(X::*)() noexcept, X> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r<long, char(X::*)(int) noexcept, X, char> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r<long, int(X::*)(int, int) noexcept, X, int, int> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r<long, double(X::*)(double, double, double) noexcept, X, float, float, float> ));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r<void, void(X::*)() noexcept, X> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r<void, char(X::*)(int) noexcept, X, char> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r<void, int(X::*)(int, int) noexcept, X, int, int> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r<void, double(X::*)(double, double, double) noexcept, X, float, float, float> ));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<X, void(X::*)() noexcept, X> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<X, char(X::*)(int) noexcept, X, char> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<X, int(X::*)(int, int) noexcept, X, int, int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<X, double(X::*)(double, double, double) noexcept, X, float, float, float> ));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<Y, void(X::*)() noexcept, X> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<Y, char(X::*)(int) noexcept, X, char> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<Y, int(X::*)(int, int) noexcept, X, int, int> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r<Y, double(X::*)(double, double, double) noexcept, X, float, float, float> ));
|
||||
|
||||
#endif
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<long, void(X::*)()> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<long, void(X::*)(), int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<long, void(X::*)(), X, int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<long, char(X::*)(int)> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<long, char(X::*)(int), int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<long, char(X::*)(int), X> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<long, char(X::*)(int), X, int, int> ));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<void, void(X::*)()> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<void, void(X::*)(), int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<void, void(X::*)(), X, int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<void, char(X::*)(int)> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<void, char(X::*)(int), int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<void, char(X::*)(int), X> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<void, char(X::*)(int), X, int, int> ));
|
||||
|
||||
// member data pointer
|
||||
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1910)
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r<long, int X::*, X> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r<long, int X::*, X const> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r<long, int X::*, X&> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r<long, int X::*, X const&> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r<long, int X::*, X*> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r<long, int X::*, X const*> ));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r<void, int X::*, X> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r<void, int X::*, X const> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r<void, int X::*, X&> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r<void, int X::*, X const&> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r<void, int X::*, X*> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r<void, int X::*, X const*> ));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<X, int X::*, X> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<X, int X::*, X const> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<X, int X::*, X&> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<X, int X::*, X const&> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<X, int X::*, X*> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<X, int X::*, X const*> ));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<Y, int X::*, X> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<Y, int X::*, X const> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<Y, int X::*, X&> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<Y, int X::*, X const&> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<Y, int X::*, X*> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<Y, int X::*, X const*> ));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r<Y, double X::*, X> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r<Y, double X::*, X const> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r<Y, double X::*, X&> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r<Y, double X::*, X const&> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r<Y, double X::*, X*> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r<Y, double X::*, X const*> ));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<int&, int X::*, X> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<int&, int X::*, X const> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r<int&, int X::*, X&> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<int&, int X::*, X const&> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r<int&, int X::*, X*> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<int&, int X::*, X const*> ));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable_r<int&&, int X::*, X> ));
|
||||
|
||||
#endif
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<long, int X::*> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<long, int X::*, int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<long, int X::*, X, int> ));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<void, int X::*> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<void, int X::*, int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable_r<void, int X::*, X, int> ));
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
143
test/is_nothrow_invocable_test.cpp
Normal file
143
test/is_nothrow_invocable_test.cpp
Normal file
@@ -0,0 +1,143 @@
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/compat/invoke.hpp>
|
||||
#include <boost/core/lightweight_test_trait.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/config/workaround.hpp>
|
||||
|
||||
struct F
|
||||
{
|
||||
void operator()()
|
||||
{
|
||||
}
|
||||
|
||||
char operator()( char x1 ) noexcept
|
||||
{
|
||||
return x1;
|
||||
}
|
||||
|
||||
int operator()( int x1, int x2 ) const
|
||||
{
|
||||
return 10*x1+x2;
|
||||
}
|
||||
|
||||
double operator()( float x1, float x2, float x3 ) const noexcept
|
||||
{
|
||||
return 100*x1 + 10*x2 + x3;
|
||||
}
|
||||
};
|
||||
|
||||
struct X
|
||||
{
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
using boost::compat::is_nothrow_invocable;
|
||||
|
||||
// nonfunction
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable<int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable<int, int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable<int, int, int> ));
|
||||
|
||||
// function reference
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable<void(&)()> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable<char(&)(int), char> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable<int(&)(int, int), int, int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable<double(&)(double, double, double), float, float, float> ));
|
||||
|
||||
#if defined(__cpp_noexcept_function_type)
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable<void(&)() noexcept> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable<char(&)(int) noexcept, char> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable<int(&)(int, int) noexcept, int, int> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable<double(&)(double, double, double) noexcept, float, float, float> ));
|
||||
|
||||
#endif
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable<void(&)(), int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable<char(&)(int)> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable<char(&)(int), int, int> ));
|
||||
|
||||
// function pointer
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable<void(*)()> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable<char(*)(int), char> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable<int(*)(int, int), int, int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable<double(*)(double, double, double), float, float, float> ));
|
||||
|
||||
#if defined(__cpp_noexcept_function_type)
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable<void(*)() noexcept> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable<char(*)(int) noexcept, char> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable<int(*)(int, int) noexcept, int, int> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable<double(*)(double, double, double) noexcept, float, float, float> ));
|
||||
|
||||
#endif
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable<void(*)(), int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable<char(*)(int)> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable<char(*)(int), int, int> ));
|
||||
|
||||
// object
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable<F> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable<F, int, int> ));
|
||||
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1910)
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable<F, char> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable<F, float, float, float> ));
|
||||
|
||||
#endif
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable<F, int, int, int, int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable<F const> ));
|
||||
|
||||
// member function pointer
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable<void(X::*)(), X> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable<char(X::*)(int), X, char> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable<int(X::*)(int, int), X, int, int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable<double(X::*)(double, double, double), X, float, float, float> ));
|
||||
|
||||
#if defined(__cpp_noexcept_function_type)
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable<void(X::*)() noexcept, X> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable<char(X::*)(int) noexcept, X, char> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable<int(X::*)(int, int) noexcept, X, int, int> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable<double(X::*)(double, double, double) noexcept, X, float, float, float> ));
|
||||
|
||||
#endif
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable<void(X::*)()> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable<void(X::*)(), int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable<void(X::*)(), X, int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable<char(X::*)(int)> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable<char(X::*)(int), int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable<char(X::*)(int), X> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable<char(X::*)(int), X, int, int> ));
|
||||
|
||||
// member data pointer
|
||||
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1910)
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable<int X::*, X> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable<int X::*, X const> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable<int X::*, X&> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable<int X::*, X const&> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable<int X::*, X*> ));
|
||||
BOOST_TEST_TRAIT_TRUE(( is_nothrow_invocable<int X::*, X const*> ));
|
||||
|
||||
#endif
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable<int X::*> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable<int X::*, int> ));
|
||||
BOOST_TEST_TRAIT_FALSE(( is_nothrow_invocable<int X::*, X, int> ));
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
105
test/mem_fn_md_test.cpp
Normal file
105
test/mem_fn_md_test.cpp
Normal file
@@ -0,0 +1,105 @@
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/compat/mem_fn.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <functional>
|
||||
|
||||
struct X
|
||||
{
|
||||
int m = -1;
|
||||
};
|
||||
|
||||
struct Y: public virtual X
|
||||
{
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::m )( X() ), -1 );
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::m )( Y() ), -1 );
|
||||
}
|
||||
|
||||
{
|
||||
X x;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::m )( x ), -1 );
|
||||
boost::compat::mem_fn( &X::m )( x ) = +1;
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::m )( x ), +1 );
|
||||
}
|
||||
|
||||
{
|
||||
X x;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::m )( &x ), -1 );
|
||||
boost::compat::mem_fn( &X::m )( &x ) = +1;
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::m )( &x ), +1 );
|
||||
}
|
||||
|
||||
{
|
||||
X x;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::m )( std::ref(x) ), -1 );
|
||||
boost::compat::mem_fn( &X::m )( std::ref(x) ) = +1;
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::m )( std::ref(x) ), +1 );
|
||||
}
|
||||
|
||||
{
|
||||
X x;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::m )( std::cref(x) ), -1 );
|
||||
}
|
||||
|
||||
{
|
||||
Y y;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::m )( y ), -1 );
|
||||
boost::compat::mem_fn( &X::m )( y ) = +1;
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::m )( y ), +1 );
|
||||
}
|
||||
|
||||
{
|
||||
Y y;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::m )( &y ), -1 );
|
||||
boost::compat::mem_fn( &X::m )( &y ) = +1;
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::m )( &y ), +1 );
|
||||
}
|
||||
|
||||
{
|
||||
Y y;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::m )( std::ref(y) ), -1 );
|
||||
boost::compat::mem_fn( &X::m )( std::ref(y) ) = +1;
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::m )( std::ref(y) ), +1 );
|
||||
}
|
||||
|
||||
{
|
||||
Y y;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::m )( std::cref(y) ), -1 );
|
||||
}
|
||||
|
||||
{
|
||||
X const x = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::m )( x ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::m )( &x ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::m )( std::ref(x) ), -1 );
|
||||
}
|
||||
|
||||
{
|
||||
Y const y = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::m )( y ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::m )( &y ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::m )( std::ref(y) ), -1 );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
127
test/mem_fn_mfn_test.cpp
Normal file
127
test/mem_fn_mfn_test.cpp
Normal file
@@ -0,0 +1,127 @@
|
||||
// Copyright 2024 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ == 7
|
||||
# pragma GCC diagnostic ignored "-Wnoexcept-type"
|
||||
#endif
|
||||
|
||||
#include <boost/compat/mem_fn.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <functional>
|
||||
|
||||
struct X
|
||||
{
|
||||
int f0()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int f1( int x1 ) noexcept
|
||||
{
|
||||
return x1;
|
||||
}
|
||||
|
||||
int f2( int x1, int x2 ) const
|
||||
{
|
||||
return 10*x1+x2;
|
||||
}
|
||||
|
||||
int f3( int x1, int x2, int x3 ) const noexcept
|
||||
{
|
||||
return 100*x1 + 10*x2 + x3;
|
||||
}
|
||||
};
|
||||
|
||||
struct Y: public virtual X
|
||||
{
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::f0 )( X() ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::f1 )( X(), 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::f2 )( X(), 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::f3 )( X(), 1, 2, 3 ), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::f0 )( Y() ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::f1 )( Y(), 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::f2 )( Y(), 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::f3 )( Y(), 1, 2, 3 ), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
X x;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::f0 )( x ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::f1 )( x, 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::f2 )( x, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::f3 )( x, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::f0 )( &x ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::f1 )( &x, 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::f2 )( &x, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::f3 )( &x, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::f0 )( std::ref(x) ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::f1 )( std::ref(x), 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::f2 )( std::ref(x), 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::f3 )( std::ref(x), 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::f2 )( std::cref(x), 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::f3 )( std::cref(x), 1, 2, 3 ), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
Y y;
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::f0 )( y ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::f1 )( y, 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::f2 )( y, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::f3 )( y, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::f0 )( &y ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::f1 )( &y, 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::f2 )( &y, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::f3 )( &y, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::f0 )( std::ref(y) ), -1 );
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::f1 )( std::ref(y), 1 ), 1 );
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::f2 )( std::ref(y), 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::f3 )( std::ref(y), 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::f2 )( std::cref(y), 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::f3 )( std::cref(y), 1, 2, 3 ), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
X const x = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::f2 )( x, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::f3 )( x, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::f2 )( &x, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::f3 )( &x, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::f2 )( std::ref(x), 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::f3 )( std::ref(x), 1, 2, 3 ), 123 );
|
||||
}
|
||||
|
||||
{
|
||||
Y const y = {};
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::f2 )( y, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::f3 )( y, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::f2 )( &y, 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::f3 )( &y, 1, 2, 3 ), 123 );
|
||||
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::f2 )( std::ref(y), 1, 2 ), 12 );
|
||||
BOOST_TEST_EQ( boost::compat::mem_fn( &X::f3 )( std::ref(y), 1, 2, 3 ), 123 );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
@@ -3,6 +3,10 @@
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/compat/latch.hpp>
|
||||
#include <boost/compat/shared_lock.hpp>
|
||||
#include <boost/compat/invoke.hpp>
|
||||
#include <boost/compat/bind_front.hpp>
|
||||
#include <boost/compat/bind_back.hpp>
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
// Copyright 2023 Peter Dimov.
|
||||
// Copyright 2023 Christian Mazakas.
|
||||
// Copyright 2023 Ed Catmur
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable: 4530) // C++ exception handler used, but unwing semantics not enabled
|
||||
#pragma warning(disable: 4577) // noexcept used with no exception handling mode specified
|
||||
@@ -23,6 +29,9 @@
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic ignored "-Wself-move"
|
||||
#endif
|
||||
#if defined(__GNUC__) && __GNUC__ >= 13
|
||||
#pragma GCC diagnostic ignored "-Wself-move"
|
||||
#endif
|
||||
|
||||
struct invalid_lock_use: public std::runtime_error
|
||||
{
|
||||
|
||||
60
test/to_array_lvalue_test.cpp
Normal file
60
test/to_array_lvalue_test.cpp
Normal file
@@ -0,0 +1,60 @@
|
||||
// Copyright 2024 Ruben Perez Hidalgo.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/compat/to_array.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <vector>
|
||||
|
||||
namespace compat = boost::compat;
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
// regular C array
|
||||
int input[] = {1, 2};
|
||||
auto output = compat::to_array(input);
|
||||
static_assert(std::is_same<decltype(output), std::array<int, 2>>::value, "");
|
||||
BOOST_TEST_EQ(output[0], 1);
|
||||
BOOST_TEST_EQ(output[1], 2);
|
||||
}
|
||||
{
|
||||
// regular C array, const
|
||||
const int input[] = {1, 2};
|
||||
auto output = compat::to_array(input);
|
||||
static_assert(std::is_same<decltype(output), std::array<int, 2>>::value, "");
|
||||
BOOST_TEST_EQ(output[0], 1);
|
||||
BOOST_TEST_EQ(output[1], 2);
|
||||
}
|
||||
{
|
||||
// values not moved
|
||||
const std::vector<int> vec{1, 2};
|
||||
std::vector<int> input[]{vec};
|
||||
auto output = compat::to_array(input);
|
||||
static_assert(std::is_same<decltype(output), std::array<std::vector<int>, 1>>::value, "");
|
||||
BOOST_TEST_ALL_EQ(output[0].begin(), output[0].end(), vec.begin(), vec.end());
|
||||
BOOST_TEST_ALL_EQ(input[0].begin(), input[0].end(), vec.begin(), vec.end()); // input not modified
|
||||
}
|
||||
{
|
||||
// const values work
|
||||
const std::vector<int> vec{1, 2};
|
||||
const std::vector<int> input[]{vec};
|
||||
auto output = compat::to_array(input);
|
||||
static_assert(std::is_same<decltype(output), std::array<std::vector<int>, 1>>::value, "");
|
||||
BOOST_TEST_ALL_EQ(output[0].begin(), output[0].end(), vec.begin(), vec.end());
|
||||
BOOST_TEST_ALL_EQ(input[0].begin(), input[0].end(), vec.begin(), vec.end()); // input not modified
|
||||
}
|
||||
{
|
||||
// constexpr check
|
||||
constexpr int input[] = {1, 2, 3};
|
||||
constexpr auto output = compat::to_array(input);
|
||||
static_assert(std::is_same<decltype(output), const std::array<int, 3>>::value, "");
|
||||
BOOST_TEST_EQ(output[0], 1);
|
||||
BOOST_TEST_EQ(output[1], 2);
|
||||
BOOST_TEST_EQ(output[2], 3);
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
88
test/to_array_rvalue_test.cpp
Normal file
88
test/to_array_rvalue_test.cpp
Normal file
@@ -0,0 +1,88 @@
|
||||
// Copyright 2024 Ruben Perez Hidalgo.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/compat/to_array.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/config/workaround.hpp>
|
||||
#include <boost/config/pragma_message.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#if defined(BOOST_MSVC) && BOOST_MSVC < 1910
|
||||
|
||||
BOOST_PRAGMA_MESSAGE( "Test skipped because BOOST_MSVC < 1910" )
|
||||
int main() {}
|
||||
|
||||
#else
|
||||
|
||||
namespace compat = boost::compat;
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
// regular C array
|
||||
int input[] = {5, 6};
|
||||
auto output = compat::to_array(std::move(input));
|
||||
static_assert(std::is_same<decltype(output), std::array<int, 2>>::value, "");
|
||||
BOOST_TEST_EQ(output[0], 5);
|
||||
BOOST_TEST_EQ(output[1], 6);
|
||||
}
|
||||
{
|
||||
// regular C array, const
|
||||
const int input[] = {5, 6};
|
||||
auto output = compat::to_array(std::move(input));
|
||||
static_assert(std::is_same<decltype(output), std::array<int, 2>>::value, "");
|
||||
BOOST_TEST_EQ(output[0], 5);
|
||||
BOOST_TEST_EQ(output[1], 6);
|
||||
}
|
||||
{
|
||||
// values moved
|
||||
const std::vector<int> vec{1, 2};
|
||||
std::vector<int> input[]{vec};
|
||||
auto output = compat::to_array(std::move(input));
|
||||
static_assert(std::is_same<decltype(output), std::array<std::vector<int>, 1>>::value, "");
|
||||
BOOST_TEST_ALL_EQ(output[0].begin(), output[0].end(), vec.begin(), vec.end());
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1920)
|
||||
BOOST_TEST(input[0].empty()); // input left in a moved-from state
|
||||
#endif
|
||||
}
|
||||
{
|
||||
// const values work (although they don't result in an effective move)
|
||||
const std::vector<int> vec{1, 2};
|
||||
const std::vector<int> input[]{vec};
|
||||
auto output = compat::to_array(std::move(input));
|
||||
static_assert(std::is_same<decltype(output), std::array<std::vector<int>, 1>>::value, "");
|
||||
BOOST_TEST_ALL_EQ(output[0].begin(), output[0].end(), vec.begin(), vec.end());
|
||||
BOOST_TEST_ALL_EQ(input[0].begin(), input[0].end(), vec.begin(), vec.end()); // input not modified
|
||||
}
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1920)
|
||||
{
|
||||
// move-only types work
|
||||
std::unique_ptr<int> input[] = {std::unique_ptr<int>{new int(42)}};
|
||||
int* ptr = input[0].get();
|
||||
auto output = compat::to_array(std::move(input));
|
||||
static_assert(std::is_same<decltype(output), std::array<std::unique_ptr<int>, 1>>::value, "");
|
||||
BOOST_TEST_EQ(output[0].get(), ptr);
|
||||
BOOST_TEST_EQ(input[0].get(), nullptr); // input left in a moved-from state
|
||||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
// constexpr check
|
||||
constexpr int input[] = {1, 2, 3};
|
||||
constexpr auto output = compat::to_array(std::move(input));
|
||||
static_assert(std::is_same<decltype(output), const std::array<int, 3>>::value, "");
|
||||
BOOST_TEST_EQ(output[0], 1);
|
||||
BOOST_TEST_EQ(output[1], 2);
|
||||
BOOST_TEST_EQ(output[2], 3);
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user