mirror of
https://github.com/boostorg/mp11.git
synced 2025-07-29 20:17:15 +02:00
Compare commits
237 Commits
boost-1.70
...
esp-idf-co
Author | SHA1 | Date | |
---|---|---|---|
fb8490e37c | |||
015adf50a6 | |||
590df5e0bc | |||
8faca18e01 | |||
4ce658d221 | |||
8b8c569cb9 | |||
7bc4e1ae9b | |||
1336c4f9c3 | |||
28036d0bdb | |||
44ca553edb | |||
219c8c1027 | |||
edba135739 | |||
df5e51c667 | |||
40a25aab6b | |||
d15c63c0a6 | |||
a1e6106e89 | |||
ae1bb087cb | |||
f471bf4997 | |||
4db9263091 | |||
8e883ae9e7 | |||
e364f2575e | |||
86121bb76b | |||
de09706e79 | |||
a01908774a | |||
8bece6d0a6 | |||
6781db002b | |||
754af95379 | |||
b2365dd68d | |||
a4d7c46670 | |||
df1cb655be | |||
91ac80468e | |||
c32d86f224 | |||
2ae1c458a6 | |||
151bf2aa2a | |||
48f5b642aa | |||
c8bff426ec | |||
8cee5a4ce0 | |||
294fc9335e | |||
c4e2259c8f | |||
fc1a347d57 | |||
891b4ddd88 | |||
28a9ff62f1 | |||
cfdda0378b | |||
758d51b4c0 | |||
f8206aa37d | |||
ce1046f007 | |||
3d8901bf8b | |||
f081f3e516 | |||
5954168980 | |||
f4b3414e62 | |||
8cd25cc950 | |||
7b854477f8 | |||
9d43d1f696 | |||
20aa0f9dcd | |||
c3aed9a44f | |||
ab2ed40371 | |||
ec581685d8 | |||
03fbf117f3 | |||
575b858a9b | |||
7694815d7b | |||
b7295ee2c3 | |||
680d5e6396 | |||
6fdfb5bde8 | |||
531a8d173e | |||
091648424d | |||
9215c68d35 | |||
ae4c83c8a6 | |||
598a40644e | |||
76f68d09a0 | |||
a07cc9062f | |||
2132bae540 | |||
e893d535f1 | |||
7749432254 | |||
c92d2d0b6f | |||
0348adbed9 | |||
b6451c4ae4 | |||
085980c876 | |||
47cf2e9a5f | |||
b08452c21c | |||
50382f0127 | |||
5babdec063 | |||
c7dbff81e5 | |||
e7f2e7a45d | |||
d669ed844c | |||
0837acfde1 | |||
4a1f343dbc | |||
0075288002 | |||
080c3437ed | |||
0dea2f1a2b | |||
a0658d7797 | |||
09780a6df8 | |||
2d709e5639 | |||
bfeef9e50e | |||
f257a448a4 | |||
e81291318c | |||
586a485325 | |||
6d51a12e57 | |||
1524f2587b | |||
064e9d415b | |||
37adad6624 | |||
6bb260ff65 | |||
90f40dd999 | |||
4349457f84 | |||
bbb73a9025 | |||
21cace4e57 | |||
727ecfc0cf | |||
28a736954f | |||
8a2e945417 | |||
02d185fce9 | |||
e4f789b0cc | |||
697e3e40a3 | |||
db78dc101c | |||
0a12995d9d | |||
2b0b900938 | |||
a069fdcce6 | |||
3f316ae626 | |||
4515938bbd | |||
637c586e02 | |||
4fb4837f92 | |||
29764aad48 | |||
10ba80acb9 | |||
d709610087 | |||
f26810ef47 | |||
645c90b11d | |||
44be76e9b6 | |||
1ffb98882d | |||
49afe16b55 | |||
e653eb3e8b | |||
588bc4458a | |||
cad3c61045 | |||
348166471e | |||
a0ea1055d2 | |||
917ac15ee1 | |||
857ba905e4 | |||
3427d716c6 | |||
35a86da178 | |||
b3fa2c4de0 | |||
9349a82e6b | |||
0ee00ee64a | |||
a8f6fa891f | |||
c51f83c25a | |||
dcf0d7ebdf | |||
b07eb08a2f | |||
13c36a793c | |||
0198b6e5a7 | |||
742980e533 | |||
2e6c2abcde | |||
6c1628b713 | |||
e984111860 | |||
7debd787dd | |||
91c6f556cd | |||
cb2705df26 | |||
984da7f1a1 | |||
20ea61df94 | |||
59d8f1b3d7 | |||
5267548813 | |||
e9684a1f66 | |||
6bc2682936 | |||
a7a2c97383 | |||
2c8ce53efb | |||
64b9c1f874 | |||
0851643af5 | |||
c806f70b73 | |||
c89fd0b7e0 | |||
03c221f2d5 | |||
de026d8322 | |||
5d25ec4ad8 | |||
1f634c7071 | |||
f321b05926 | |||
66681de1ed | |||
2b0d107844 | |||
4e177f73ae | |||
8ef7658518 | |||
d3f0738bf4 | |||
03f6096230 | |||
f5dbff1379 | |||
b0b33a4fcf | |||
392151cdc9 | |||
64b2e12971 | |||
7ff533876c | |||
2d65367919 | |||
3f07d53041 | |||
87ab394510 | |||
22fc4198e5 | |||
d48d5c8708 | |||
bbb6f3aa84 | |||
3afdb0e876 | |||
054f576d14 | |||
2deeac36b4 | |||
2afc07f189 | |||
6b2b305117 | |||
219cf35ea8 | |||
33bf90a050 | |||
bf655dd4c9 | |||
868dcae683 | |||
3b4814a91c | |||
e73693b588 | |||
d5e4dda1b4 | |||
ea37a24f98 | |||
49edfceea2 | |||
85fb466414 | |||
b53bab4b7d | |||
a1ada99d10 | |||
3425d6bb00 | |||
25cbde3f91 | |||
cd2c492be7 | |||
b24d2285a6 | |||
f14309e92d | |||
4a8a049a3e | |||
3efbc9d3cd | |||
76442f9120 | |||
4f91ee2e96 | |||
523c23619c | |||
6a2e8e8384 | |||
d151f9a712 | |||
409147714c | |||
1542a0c388 | |||
aa11577812 | |||
f64bc319c0 | |||
ed5dc75e18 | |||
8b0ab6130d | |||
900a0c842e | |||
0ca69d98c9 | |||
85a2099874 | |||
164aa375f2 | |||
b23b97856c | |||
9bd902c1c9 | |||
d0e6e29abb | |||
bf6f3e0221 | |||
23a1432e8d | |||
45cc05a298 | |||
bba027610f | |||
cb15f6b94e | |||
d03c53a693 | |||
417e0db55a | |||
f1ededad7a | |||
fd1b8081b7 |
502
.github/workflows/ci.yml
vendored
Normal file
502
.github/workflows/ci.yml
vendored
Normal file
@ -0,0 +1,502 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
- feature/**
|
||||
|
||||
env:
|
||||
UBSAN_OPTIONS: print_stacktrace=1
|
||||
|
||||
jobs:
|
||||
posix:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- toolset: gcc-4.8
|
||||
cxxstd: "03,11"
|
||||
os: ubuntu-18.04
|
||||
install: g++-4.8
|
||||
- toolset: gcc-5
|
||||
cxxstd: "03,11,14,1z"
|
||||
os: ubuntu-18.04
|
||||
install: g++-5
|
||||
- toolset: gcc-6
|
||||
cxxstd: "03,11,14,1z"
|
||||
os: ubuntu-18.04
|
||||
install: g++-6
|
||||
- toolset: gcc-7
|
||||
cxxstd: "03,11,14,17"
|
||||
os: ubuntu-18.04
|
||||
- toolset: gcc-8
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: ubuntu-18.04
|
||||
install: g++-8
|
||||
- toolset: gcc-9
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: ubuntu-20.04
|
||||
- toolset: gcc-10
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: ubuntu-20.04
|
||||
install: g++-10
|
||||
- toolset: gcc-11
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: ubuntu-20.04
|
||||
install: g++-11
|
||||
- toolset: clang
|
||||
compiler: clang++-3.9
|
||||
cxxstd: "03,11,14"
|
||||
os: ubuntu-18.04
|
||||
install: clang-3.9
|
||||
- toolset: clang
|
||||
compiler: clang++-4.0
|
||||
cxxstd: "03,11,14"
|
||||
os: ubuntu-18.04
|
||||
install: clang-4.0
|
||||
- toolset: clang
|
||||
compiler: clang++-5.0
|
||||
cxxstd: "03,11,14,1z"
|
||||
os: ubuntu-18.04
|
||||
install: clang-5.0
|
||||
- toolset: clang
|
||||
compiler: clang++-6.0
|
||||
cxxstd: "03,11,14,17"
|
||||
os: ubuntu-18.04
|
||||
install: clang-6.0
|
||||
- toolset: clang
|
||||
compiler: clang++-7
|
||||
cxxstd: "03,11,14,17"
|
||||
os: ubuntu-18.04
|
||||
install: clang-7
|
||||
- toolset: clang
|
||||
compiler: clang++-8
|
||||
cxxstd: "03,11,14,17"
|
||||
os: ubuntu-20.04
|
||||
install: clang-8
|
||||
- toolset: clang
|
||||
compiler: clang++-9
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: ubuntu-20.04
|
||||
install: clang-9
|
||||
- toolset: clang
|
||||
compiler: clang++-10
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: ubuntu-20.04
|
||||
- toolset: clang
|
||||
compiler: clang++-11
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: ubuntu-20.04
|
||||
- toolset: clang
|
||||
compiler: clang++-12
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: ubuntu-20.04
|
||||
- toolset: clang
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: macos-10.15
|
||||
|
||||
runs-on: ${{matrix.os}}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Install packages
|
||||
if: matrix.install
|
||||
run: sudo apt install ${{matrix.install}}
|
||||
|
||||
- name: Setup Boost
|
||||
run: |
|
||||
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
|
||||
LIBRARY=${GITHUB_REPOSITORY#*/}
|
||||
echo LIBRARY: $LIBRARY
|
||||
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
|
||||
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
|
||||
echo GITHUB_REF: $GITHUB_REF
|
||||
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
|
||||
REF=${REF#refs/heads/}
|
||||
echo REF: $REF
|
||||
BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true
|
||||
echo BOOST_BRANCH: $BOOST_BRANCH
|
||||
cd ..
|
||||
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
|
||||
cd boost-root
|
||||
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
|
||||
git submodule update --init tools/boostdep
|
||||
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
|
||||
./bootstrap.sh
|
||||
./b2 -d0 headers
|
||||
|
||||
- name: Create user-config.jam
|
||||
if: matrix.compiler
|
||||
run: |
|
||||
echo "using ${{matrix.toolset}} : : ${{matrix.compiler}} ;" > ~/user-config.jam
|
||||
|
||||
- name: Run tests
|
||||
run: |
|
||||
cd ../boost-root
|
||||
./b2 -j3 libs/$LIBRARY/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} variant=debug,release
|
||||
|
||||
windows:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
# msvc-14.0 not included, because it fails with "compiler is out of heap space"
|
||||
- toolset: msvc-14.2
|
||||
cxxstd: "14,17,20,latest"
|
||||
addrmd: 32,64
|
||||
os: windows-2019
|
||||
- toolset: msvc-14.3
|
||||
cxxstd: "14,17,20,latest"
|
||||
addrmd: 32,64
|
||||
os: windows-2022
|
||||
- toolset: clang-win
|
||||
cxxstd: "14,17,latest"
|
||||
addrmd: 32,64
|
||||
os: windows-2022
|
||||
- toolset: gcc
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
addrmd: 64
|
||||
os: windows-2019
|
||||
|
||||
runs-on: ${{matrix.os}}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Setup Boost
|
||||
shell: cmd
|
||||
run: |
|
||||
echo GITHUB_REPOSITORY: %GITHUB_REPOSITORY%
|
||||
for /f %%i in ("%GITHUB_REPOSITORY%") do set LIBRARY=%%~nxi
|
||||
echo LIBRARY: %LIBRARY%
|
||||
echo LIBRARY=%LIBRARY%>>%GITHUB_ENV%
|
||||
echo GITHUB_BASE_REF: %GITHUB_BASE_REF%
|
||||
echo GITHUB_REF: %GITHUB_REF%
|
||||
if "%GITHUB_BASE_REF%" == "" set GITHUB_BASE_REF=%GITHUB_REF%
|
||||
set BOOST_BRANCH=develop
|
||||
for /f %%i in ("%GITHUB_BASE_REF%") do if "%%~nxi" == "master" set BOOST_BRANCH=master
|
||||
echo BOOST_BRANCH: %BOOST_BRANCH%
|
||||
cd ..
|
||||
git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
|
||||
cd boost-root
|
||||
xcopy /s /e /q %GITHUB_WORKSPACE% libs\%LIBRARY%\
|
||||
git submodule update --init tools/boostdep
|
||||
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" %LIBRARY%
|
||||
cmd /c bootstrap
|
||||
b2 -d0 headers
|
||||
|
||||
- name: Run tests
|
||||
shell: cmd
|
||||
run: |
|
||||
cd ../boost-root
|
||||
b2 -j3 libs/%LIBRARY%/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release embed-manifest-via=linker
|
||||
|
||||
posix-cmake-subdir:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-18.04
|
||||
- os: ubuntu-20.04
|
||||
- os: macos-10.15
|
||||
|
||||
runs-on: ${{matrix.os}}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Install packages
|
||||
if: matrix.install
|
||||
run: sudo apt install ${{matrix.install}}
|
||||
|
||||
- name: Setup Boost
|
||||
run: |
|
||||
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
|
||||
LIBRARY=${GITHUB_REPOSITORY#*/}
|
||||
echo LIBRARY: $LIBRARY
|
||||
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
|
||||
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
|
||||
echo GITHUB_REF: $GITHUB_REF
|
||||
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
|
||||
REF=${REF#refs/heads/}
|
||||
echo REF: $REF
|
||||
BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true
|
||||
echo BOOST_BRANCH: $BOOST_BRANCH
|
||||
cd ..
|
||||
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
|
||||
cd boost-root
|
||||
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
|
||||
git submodule update --init tools/boostdep
|
||||
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
|
||||
|
||||
- name: Use library with add_subdirectory
|
||||
run: |
|
||||
cd ../boost-root/libs/$LIBRARY/test/cmake_subdir_test
|
||||
mkdir __build__ && cd __build__
|
||||
cmake ..
|
||||
cmake --build .
|
||||
ctest --output-on-failure --no-tests=error
|
||||
|
||||
posix-cmake-install:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-18.04
|
||||
- os: ubuntu-20.04
|
||||
- os: macos-10.15
|
||||
|
||||
runs-on: ${{matrix.os}}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Install packages
|
||||
if: matrix.install
|
||||
run: sudo apt install ${{matrix.install}}
|
||||
|
||||
- name: Setup Boost
|
||||
run: |
|
||||
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
|
||||
LIBRARY=${GITHUB_REPOSITORY#*/}
|
||||
echo LIBRARY: $LIBRARY
|
||||
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
|
||||
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
|
||||
echo GITHUB_REF: $GITHUB_REF
|
||||
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
|
||||
REF=${REF#refs/heads/}
|
||||
echo REF: $REF
|
||||
BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true
|
||||
echo BOOST_BRANCH: $BOOST_BRANCH
|
||||
cd ..
|
||||
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
|
||||
cd boost-root
|
||||
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
|
||||
git submodule update --init tools/boostdep
|
||||
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
|
||||
|
||||
- name: Configure
|
||||
run: |
|
||||
cd ../boost-root
|
||||
mkdir __build__ && cd __build__
|
||||
cmake -DBOOST_INCLUDE_LIBRARIES=$LIBRARY -DCMAKE_INSTALL_PREFIX=~/.local ..
|
||||
|
||||
- name: Install
|
||||
run: |
|
||||
cd ../boost-root/__build__
|
||||
cmake --build . --target install
|
||||
|
||||
- name: Use the installed library
|
||||
run: |
|
||||
cd ../boost-root/libs/$LIBRARY/test/cmake_install_test && mkdir __build__ && cd __build__
|
||||
cmake -DCMAKE_INSTALL_PREFIX=~/.local ..
|
||||
cmake --build .
|
||||
ctest --output-on-failure --no-tests=error
|
||||
|
||||
posix-cmake-test:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-18.04
|
||||
- os: ubuntu-20.04
|
||||
- os: macos-10.15
|
||||
|
||||
runs-on: ${{matrix.os}}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Install packages
|
||||
if: matrix.install
|
||||
run: sudo apt install ${{matrix.install}}
|
||||
|
||||
- name: Setup Boost
|
||||
run: |
|
||||
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
|
||||
LIBRARY=${GITHUB_REPOSITORY#*/}
|
||||
echo LIBRARY: $LIBRARY
|
||||
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
|
||||
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
|
||||
echo GITHUB_REF: $GITHUB_REF
|
||||
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
|
||||
REF=${REF#refs/heads/}
|
||||
echo REF: $REF
|
||||
BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true
|
||||
echo BOOST_BRANCH: $BOOST_BRANCH
|
||||
cd ..
|
||||
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
|
||||
cd boost-root
|
||||
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
|
||||
git submodule update --init tools/boostdep
|
||||
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
|
||||
|
||||
- name: Configure
|
||||
run: |
|
||||
cd ../boost-root
|
||||
mkdir __build__ && cd __build__
|
||||
cmake -DBOOST_INCLUDE_LIBRARIES=$LIBRARY -DBUILD_TESTING=ON ..
|
||||
|
||||
- name: Build tests
|
||||
run: |
|
||||
cd ../boost-root/__build__
|
||||
cmake --build . --target tests
|
||||
|
||||
- name: Run tests
|
||||
run: |
|
||||
cd ../boost-root/__build__
|
||||
ctest --output-on-failure --no-tests=error
|
||||
|
||||
standalone-cmake-subdir:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-18.04
|
||||
- os: ubuntu-20.04
|
||||
- os: macos-10.15
|
||||
|
||||
runs-on: ${{matrix.os}}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Install packages
|
||||
if: matrix.install
|
||||
run: sudo apt install ${{matrix.install}}
|
||||
|
||||
- name: Use library with add_subdirectory
|
||||
run: |
|
||||
cd test/cmake_subdir_test
|
||||
mkdir __build__ && cd __build__
|
||||
cmake ..
|
||||
cmake --build .
|
||||
ctest --output-on-failure --no-tests=error
|
||||
|
||||
standalone-cmake-install:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-18.04
|
||||
- os: ubuntu-20.04
|
||||
- os: macos-10.15
|
||||
|
||||
runs-on: ${{matrix.os}}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Install packages
|
||||
if: matrix.install
|
||||
run: sudo apt install ${{matrix.install}}
|
||||
|
||||
- name: Configure
|
||||
run: |
|
||||
mkdir __build__ && cd __build__
|
||||
cmake -DCMAKE_INSTALL_PREFIX=~/.local ..
|
||||
|
||||
- name: Install
|
||||
run: |
|
||||
cd __build__
|
||||
cmake --build . --target install
|
||||
|
||||
- name: Use the installed library
|
||||
run: |
|
||||
cd test/cmake_install_test && mkdir __build__ && cd __build__
|
||||
cmake -DCMAKE_INSTALL_PREFIX=~/.local ..
|
||||
cmake --build .
|
||||
ctest --output-on-failure --no-tests=error
|
||||
|
||||
standalone-cmake-test:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-18.04
|
||||
- os: ubuntu-20.04
|
||||
- os: macos-10.15
|
||||
|
||||
runs-on: ${{matrix.os}}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Install packages
|
||||
if: matrix.install
|
||||
run: sudo apt install ${{matrix.install}}
|
||||
|
||||
- name: Configure
|
||||
run: |
|
||||
mkdir __build__ && cd __build__
|
||||
cmake -DBUILD_TESTING=ON ..
|
||||
|
||||
- name: Build tests
|
||||
run: |
|
||||
cd __build__
|
||||
cmake --build . --target tests
|
||||
|
||||
- name: Run tests
|
||||
run: |
|
||||
cd __build__
|
||||
ctest --output-on-failure --no-tests=error
|
||||
|
||||
cuda-linux:
|
||||
runs-on: ubuntu-20.04
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: Jimver/cuda-toolkit@v0.2.4
|
||||
|
||||
- name: Setup Boost
|
||||
run: |
|
||||
cd ..
|
||||
git clone --depth 1 https://github.com/boostorg/assert
|
||||
git clone --depth 1 https://github.com/boostorg/config
|
||||
git clone --depth 1 https://github.com/boostorg/core
|
||||
|
||||
- name: Run Tests
|
||||
run: |
|
||||
nvcc -x cu -I ./include -I ../assert/include -I ../config/include -I ../core/include -std=c++11 -c test/mp11.cpp
|
||||
nvcc -x cu -I ./include -I ../assert/include -I ../config/include -I ../core/include -std=c++14 -c test/mp11.cpp
|
||||
nvcc -x cu -I ./include -I ../assert/include -I ../config/include -I ../core/include -std=c++17 -c test/mp11.cpp
|
||||
nvcc -x cu -I ./include -I ../assert/include -I ../config/include -I ../core/include -std=c++11 -c test/mp_all.cpp
|
||||
nvcc -x cu -I ./include -I ../assert/include -I ../config/include -I ../core/include -std=c++14 -c test/mp_all.cpp
|
||||
nvcc -x cu -I ./include -I ../assert/include -I ../config/include -I ../core/include -std=c++17 -c test/mp_all.cpp
|
||||
nvcc -x cu -I ./include -I ../assert/include -I ../config/include -I ../core/include -std=c++11 -c test/mp_any.cpp
|
||||
nvcc -x cu -I ./include -I ../assert/include -I ../config/include -I ../core/include -std=c++14 -c test/mp_any.cpp
|
||||
nvcc -x cu -I ./include -I ../assert/include -I ../config/include -I ../core/include -std=c++17 -c test/mp_any.cpp
|
||||
nvcc -x cu -I ./include -I ../assert/include -I ../config/include -I ../core/include -std=c++11 -c test/mp_count.cpp
|
||||
nvcc -x cu -I ./include -I ../assert/include -I ../config/include -I ../core/include -std=c++14 -c test/mp_count.cpp
|
||||
nvcc -x cu -I ./include -I ../assert/include -I ../config/include -I ../core/include -std=c++17 -c test/mp_count.cpp
|
||||
nvcc -x cu -I ./include -I ../assert/include -I ../config/include -I ../core/include -std=c++11 -c test/mp_count_if.cpp
|
||||
nvcc -x cu -I ./include -I ../assert/include -I ../config/include -I ../core/include -std=c++14 -c test/mp_count_if.cpp
|
||||
nvcc -x cu -I ./include -I ../assert/include -I ../config/include -I ../core/include -std=c++17 -c test/mp_count_if.cpp
|
||||
|
||||
cuda-windows:
|
||||
runs-on: windows-2019
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: Jimver/cuda-toolkit@v0.2.4
|
||||
- uses: ilammy/msvc-dev-cmd@v1
|
||||
|
||||
- name: Setup Boost
|
||||
run: |
|
||||
cd ..
|
||||
git clone --depth 1 https://github.com/boostorg/assert
|
||||
git clone --depth 1 https://github.com/boostorg/config
|
||||
git clone --depth 1 https://github.com/boostorg/core
|
||||
|
||||
- name: Run Tests
|
||||
shell: cmd
|
||||
run: |
|
||||
nvcc -x cu -I ./include -I ../assert/include -I ../config/include -I ../core/include -c test/mp11.cpp || exit /b
|
||||
nvcc -x cu -I ./include -I ../assert/include -I ../config/include -I ../core/include -c test/mp_all.cpp || exit /b
|
||||
nvcc -x cu -I ./include -I ../assert/include -I ../config/include -I ../core/include -c test/mp_any.cpp || exit /b
|
||||
nvcc -x cu -I ./include -I ../assert/include -I ../config/include -I ../core/include -c test/mp_count.cpp || exit /b
|
||||
nvcc -x cu -I ./include -I ../assert/include -I ../config/include -I ../core/include -c test/mp_count_if.cpp || exit /b
|
136
.travis.yml
136
.travis.yml
@ -4,7 +4,8 @@
|
||||
|
||||
language: cpp
|
||||
|
||||
sudo: false
|
||||
os: linux
|
||||
dist: xenial
|
||||
|
||||
branches:
|
||||
only:
|
||||
@ -92,6 +93,27 @@ matrix:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: g++-9
|
||||
env: TOOLSET=gcc COMPILER=g++-9 CXXSTD=11,14,17,2a
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-9
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
dist: bionic
|
||||
compiler: g++-10
|
||||
env: TOOLSET=gcc COMPILER=g++-10 CXXSTD=11,14,17,2a
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-10
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: g++
|
||||
env: NVCC=1
|
||||
@ -102,6 +124,7 @@ matrix:
|
||||
- $HOME/lib/cuda-9.1.85/bin/nvcc -x cu -I . -c -std=c++11 libs/mp11/test/mp11.cpp
|
||||
|
||||
- os: linux
|
||||
dist: trusty
|
||||
compiler: /usr/bin/clang++
|
||||
env: TOOLSET=clang COMPILER=/usr/bin/clang++ CXXSTD=11
|
||||
addons:
|
||||
@ -110,6 +133,7 @@ matrix:
|
||||
- clang-3.3
|
||||
|
||||
- os: linux
|
||||
dist: trusty
|
||||
compiler: /usr/bin/clang++
|
||||
env: TOOLSET=clang COMPILER=/usr/bin/clang++ CXXSTD=11
|
||||
addons:
|
||||
@ -137,6 +161,16 @@ matrix:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: clang++-3.7
|
||||
env: TOOLSET=clang COMPILER=clang++-3.7 CXXSTD=11,14,1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.7
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: clang++-3.8
|
||||
env: TOOLSET=clang COMPILER=clang++-3.8 CXXSTD=11,14,1z
|
||||
@ -166,9 +200,9 @@ matrix:
|
||||
- clang-4.0
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-trusty-4.0
|
||||
|
||||
- os: linux
|
||||
dist: bionic
|
||||
compiler: clang++-5.0
|
||||
env: TOOLSET=clang COMPILER=clang++-5.0 CXXSTD=11,14,1z
|
||||
addons:
|
||||
@ -177,9 +211,9 @@ matrix:
|
||||
- clang-5.0
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-trusty-5.0
|
||||
|
||||
- os: linux
|
||||
dist: bionic
|
||||
compiler: clang++-6.0
|
||||
env: TOOLSET=clang COMPILER=clang++-6.0 CXXSTD=11,14,17
|
||||
addons:
|
||||
@ -188,9 +222,9 @@ matrix:
|
||||
- clang-6.0
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-trusty-6.0
|
||||
|
||||
- os: linux
|
||||
dist: bionic
|
||||
compiler: clang++-7
|
||||
env: TOOLSET=clang COMPILER=clang++-7 CXXSTD=11,14,17,2a
|
||||
addons:
|
||||
@ -199,7 +233,71 @@ matrix:
|
||||
- clang-7
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-trusty-7
|
||||
- llvm-toolchain-bionic-7
|
||||
|
||||
- os: linux
|
||||
dist: bionic
|
||||
compiler: clang++-8
|
||||
env: TOOLSET=clang COMPILER=clang++-8 CXXSTD=11,14,17,2a
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-8
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-bionic-8
|
||||
|
||||
- os: linux
|
||||
dist: bionic
|
||||
compiler: clang++-9
|
||||
env: TOOLSET=clang COMPILER=clang++-9 CXXSTD=11,14,17,2a
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-9
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: 'deb https://apt.llvm.org/bionic/ llvm-toolchain-bionic-9 main'
|
||||
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
|
||||
|
||||
- os: linux
|
||||
dist: bionic
|
||||
compiler: clang++-10
|
||||
env: TOOLSET=clang COMPILER=clang++-10 CXXSTD=11,14,17,2a
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-10
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: 'deb https://apt.llvm.org/bionic/ llvm-toolchain-bionic-10 main'
|
||||
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
|
||||
|
||||
- os: linux
|
||||
dist: bionic
|
||||
compiler: clang++-11
|
||||
env: TOOLSET=clang COMPILER=clang++-11 CXXSTD=11,14,17,2a
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-11
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: 'deb https://apt.llvm.org/bionic/ llvm-toolchain-bionic-11 main'
|
||||
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
|
||||
|
||||
- os: linux
|
||||
dist: bionic
|
||||
compiler: clang++-12
|
||||
env: TOOLSET=clang COMPILER=clang++-12 CXXSTD=11,14,17,2a
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-12
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: 'deb https://apt.llvm.org/bionic/ llvm-toolchain-bionic-12 main'
|
||||
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
|
||||
|
||||
- os: linux
|
||||
compiler: clang++-libc++
|
||||
@ -210,6 +308,7 @@ matrix:
|
||||
- libc++-dev
|
||||
|
||||
- os: linux
|
||||
dist: bionic
|
||||
compiler: clang++-5.0
|
||||
env: CLANG_X_CUDA=1
|
||||
addons:
|
||||
@ -221,7 +320,6 @@ matrix:
|
||||
- nvidia-cuda-toolkit
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-trusty-5.0
|
||||
script:
|
||||
- clang++-5.0 -I . -c -x cuda -nocudainc -nocudalib --cuda-gpu-arch=sm_30 -D__device__="__attribute__((device))" -std=c++11 libs/mp11/test/mp11.cpp
|
||||
- clang++-5.0 -I . -c -x cuda -nocudainc -nocudalib --cuda-gpu-arch=sm_30 -D__device__="__attribute__((device))" -std=c++14 libs/mp11/test/mp11.cpp
|
||||
@ -243,18 +341,29 @@ matrix:
|
||||
env: TOOLSET=clang COMPILER=clang++ CXXSTD=11,14,1z
|
||||
|
||||
- os: osx
|
||||
osx_image: xcode10.1
|
||||
osx_image: xcode10.3
|
||||
compiler: clang++
|
||||
env: TOOLSET=clang COMPILER=clang++ CXXSTD=11,14,1z
|
||||
|
||||
- os: osx
|
||||
osx_image: xcode11.6
|
||||
compiler: clang++
|
||||
env: TOOLSET=clang COMPILER=clang++ CXXSTD=11,14,1z
|
||||
|
||||
- os: osx
|
||||
osx_image: xcode12.2
|
||||
compiler: clang++
|
||||
env: TOOLSET=clang COMPILER=clang++ CXXSTD=11,14,1z
|
||||
|
||||
- os: linux
|
||||
compiler: clang++
|
||||
env: CMAKE=1
|
||||
env: CMAKE_STANDALONE_TEST=1
|
||||
install: true
|
||||
script:
|
||||
- mkdir __build__ && cd __build__
|
||||
- cmake ..
|
||||
- cmake --build . --target check
|
||||
- cmake --build . --target tests
|
||||
- ctest --output-on-failure
|
||||
|
||||
- os: linux
|
||||
compiler: clang++
|
||||
@ -279,6 +388,15 @@ matrix:
|
||||
- cmake --build .
|
||||
- cmake --build . --target check
|
||||
|
||||
- os: linux
|
||||
compiler: clang++
|
||||
env: BOOST_CMAKE_TEST=1
|
||||
script:
|
||||
- mkdir __build__ && cd __build__
|
||||
- cmake -DBUILD_TESTING=ON -DBOOST_INCLUDE_LIBRARIES=mp11 ..
|
||||
- cmake --build . --target tests
|
||||
- ctest --output-on-failure
|
||||
|
||||
install:
|
||||
- BOOST_BRANCH=develop && [ "$TRAVIS_BRANCH" == "master" ] && BOOST_BRANCH=master || true
|
||||
- cd ..
|
||||
|
@ -1,72 +1,81 @@
|
||||
# Copyright 2018 Peter Dimov
|
||||
# Copyright 2018, 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
|
||||
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
if(NOT DEFINED IDF_TARGET)
|
||||
|
||||
project(BoostMp11 VERSION 1.70.0 LANGUAGES CXX)
|
||||
cmake_minimum_required(VERSION 3.5...3.16)
|
||||
|
||||
project(boost_mp11 VERSION 1.80.0 LANGUAGES CXX)
|
||||
|
||||
add_library(boost_mp11 INTERFACE)
|
||||
set_property(TARGET boost_mp11 PROPERTY EXPORT_NAME mp11)
|
||||
|
||||
add_library(Boost::mp11 ALIAS boost_mp11)
|
||||
|
||||
target_include_directories(boost_mp11 INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> $<INSTALL_INTERFACE:include>)
|
||||
target_include_directories(boost_mp11 INTERFACE include)
|
||||
target_compile_features(boost_mp11 INTERFACE cxx_alias_templates cxx_variadic_templates cxx_decltype)
|
||||
|
||||
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
|
||||
|
||||
# --target check
|
||||
# Fetch support files
|
||||
|
||||
# `function` confuses FetchContent, sees empty CMAKE_CURRENT_LIST_DIR
|
||||
macro(fetch_and_include name)
|
||||
message(STATUS "Fetching BoostFetch.cmake")
|
||||
|
||||
message(STATUS "Fetching ${name}")
|
||||
file(DOWNLOAD
|
||||
"https://raw.githubusercontent.com/boostorg/cmake/develop/include/BoostFetch.cmake"
|
||||
"${CMAKE_BINARY_DIR}/fetch_and_include/BoostFetch.cmake"
|
||||
)
|
||||
|
||||
file(DOWNLOAD
|
||||
"https://raw.githubusercontent.com/boostorg/mincmake/master/${name}"
|
||||
"${CMAKE_BINARY_DIR}/fetch_and_include/${name}"
|
||||
)
|
||||
include("${CMAKE_BINARY_DIR}/fetch_and_include/BoostFetch.cmake")
|
||||
|
||||
include("${CMAKE_BINARY_DIR}/fetch_and_include/${name}")
|
||||
boost_fetch(boostorg/cmake TAG develop NO_ADD_SUBDIR)
|
||||
|
||||
endmacro()
|
||||
FetchContent_GetProperties(boostorg_cmake)
|
||||
|
||||
fetch_and_include(cmake/boost_fetch.cmake)
|
||||
fetch_and_include(cmake/boost_test.cmake)
|
||||
list(APPEND CMAKE_MODULE_PATH ${boostorg_cmake_SOURCE_DIR}/include)
|
||||
|
||||
boost_fetch(boostorg/assert TAG develop)
|
||||
boost_fetch(boostorg/config TAG develop)
|
||||
boost_fetch(boostorg/core TAG develop)
|
||||
# Testing (off by default)
|
||||
|
||||
enable_testing()
|
||||
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -C $<CONFIG>)
|
||||
option(BUILD_TESTING "Build the tests." OFF)
|
||||
include(CTest)
|
||||
|
||||
# --target install
|
||||
if(BUILD_TESTING)
|
||||
|
||||
set(CONFIG_INSTALL_DIR lib/cmake/${PROJECT_NAME}-${PROJECT_VERSION})
|
||||
set(BUILD_TESTING OFF) # hide cache variable
|
||||
|
||||
install(TARGETS boost_mp11 EXPORT ${PROJECT_NAME}Targets)
|
||||
install(EXPORT ${PROJECT_NAME}Targets DESTINATION ${CONFIG_INSTALL_DIR} NAMESPACE Boost:: FILE ${PROJECT_NAME}Config.cmake)
|
||||
boost_fetch(boostorg/assert TAG develop EXCLUDE_FROM_ALL)
|
||||
boost_fetch(boostorg/config TAG develop EXCLUDE_FROM_ALL)
|
||||
boost_fetch(boostorg/core TAG develop EXCLUDE_FROM_ALL)
|
||||
boost_fetch(boostorg/static_assert TAG develop EXCLUDE_FROM_ALL)
|
||||
boost_fetch(boostorg/throw_exception TAG develop EXCLUDE_FROM_ALL)
|
||||
|
||||
install(DIRECTORY include/ DESTINATION include)
|
||||
unset(BUILD_TESTING)
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
endif()
|
||||
|
||||
# Mp11 is independent of 32/64, so this hack makes BoostMp11ConfigVersion.cmake skip the check
|
||||
set(OLD_CMAKE_SIZEOF_VOID_P ${CMAKE_SIZEOF_VOID_P})
|
||||
unset(CMAKE_SIZEOF_VOID_P)
|
||||
write_basic_package_version_file("${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" COMPATIBILITY AnyNewerVersion)
|
||||
set(CMAKE_SIZEOF_VOID_P ${OLD_CMAKE_SIZEOF_VOID_P})
|
||||
# Do not use the default BoostInstall versioned layout on Windows when standalone
|
||||
set(BOOST_INSTALL_LAYOUT "system" CACHE STRING "Installation layout (versioned, tagged, or system)")
|
||||
|
||||
install(FILES "${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" DESTINATION ${CONFIG_INSTALL_DIR})
|
||||
include(BoostInstall)
|
||||
|
||||
#export(EXPORT ${PROJECT_NAME}Targets NAMESPACE Boost:: FILE ${PROJECT_NAME}Config.cmake)
|
||||
boost_install(TARGETS boost_mp11 HEADER_DIRECTORY include/)
|
||||
|
||||
endif()
|
||||
|
||||
if(COMMAND boost_test)
|
||||
if(BUILD_TESTING)
|
||||
|
||||
add_subdirectory(test)
|
||||
add_subdirectory(test)
|
||||
|
||||
endif()
|
||||
|
||||
else()
|
||||
|
||||
FILE(GLOB_RECURSE headers include/*.h include/*.hpp)
|
||||
|
||||
idf_component_register(
|
||||
SRCS
|
||||
${headers}
|
||||
INCLUDE_DIRS
|
||||
include
|
||||
)
|
||||
|
||||
endif()
|
||||
|
14
README.md
14
README.md
@ -2,21 +2,21 @@
|
||||
|
||||
Mp11 is a C++11 metaprogramming library based on template aliases and variadic templates.
|
||||
It implements the approach outlined in the article
|
||||
["Simple C++11 metaprogramming"](http://pdimov.com/cpp2/simple_cxx11_metaprogramming.html)
|
||||
and [its sequel](http://pdimov.com/cpp2/simple_cxx11_metaprogramming_2.html).
|
||||
["Simple C++11 metaprogramming"](https://www.boost.org/libs/mp11/doc/html/simple_cxx11_metaprogramming.html)
|
||||
and [its sequel](https://www.boost.org/libs/mp11/doc/html/simple_cxx11_metaprogramming_2.html).
|
||||
|
||||
Mp11 is part of [Boost](http://boost.org/libs/mp11), starting with release 1.66.0. It
|
||||
however has no Boost dependencies and can be used standalone, as a Git submodule, for
|
||||
instance. For CMake users, `add_subdirectory` is supported, as is installation and
|
||||
`find_package(BoostMp11)`.
|
||||
`find_package(boost_mp11)`.
|
||||
|
||||
## Supported compilers
|
||||
|
||||
* g++ 4.7 or later
|
||||
* clang++ 3.3 or later
|
||||
* Visual Studio 2013, 2015, 2017
|
||||
* g++ 4.8 or later
|
||||
* clang++ 3.9 or later
|
||||
* Visual Studio 2013, 2015, 2017, 2019
|
||||
|
||||
Tested on [Travis](https://travis-ci.org/boostorg/mp11/) and [Appveyor](https://ci.appveyor.com/project/pdimov/mp11/).
|
||||
Tested on [Github Actions](https://github.com/boostorg/mp11/actions) and [Appveyor](https://ci.appveyor.com/project/pdimov/mp11/).
|
||||
|
||||
## License
|
||||
|
||||
|
57
appveyor.yml
57
appveyor.yml
@ -1,4 +1,4 @@
|
||||
# Copyright 2016, 2017 Peter Dimov
|
||||
# Copyright 2016-2021 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)
|
||||
|
||||
@ -14,15 +14,39 @@ branches:
|
||||
|
||||
environment:
|
||||
matrix:
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
|
||||
TOOLSET: msvc-12.0
|
||||
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
TOOLSET: msvc-12.0
|
||||
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
TOOLSET: msvc-14.0
|
||||
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
TOOLSET: msvc-14.1
|
||||
CXXSTD: 14,17,latest
|
||||
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
TOOLSET: clang-win
|
||||
CXXSTD: 14,17,latest
|
||||
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
CMAKE: 1
|
||||
CONFIG: MinSizeRel
|
||||
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
CMAKE_SUBDIR: 1
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
CMAKE_INSTALL: 1
|
||||
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
TOOLSET: msvc-14.1
|
||||
CXXSTD: 17
|
||||
CMAKE_SUBDIR: 1
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
CMAKE_INSTALL: 1
|
||||
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
CMAKE_SUBDIR: 1
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
CMAKE_INSTALL: 1
|
||||
|
||||
install:
|
||||
- set BOOST_BRANCH=develop
|
||||
@ -34,10 +58,29 @@ install:
|
||||
- xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\mp11\
|
||||
- python tools/boostdep/depinst/depinst.py mp11
|
||||
- cmd /c bootstrap
|
||||
- b2 headers
|
||||
- b2 -d0 headers
|
||||
|
||||
build: off
|
||||
|
||||
test_script:
|
||||
- if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
|
||||
- b2 -j3 libs/mp11/test toolset=%TOOLSET% %CXXSTD%
|
||||
- if "%CMAKE%%CMAKE_SUBDIR%%CMAKE_INSTALL%" == "" b2 -j3 libs/mp11/test toolset=%TOOLSET% %CXXSTD% address-model=32,64 variant=debug,release embed-manifest-via=linker
|
||||
|
||||
- if not "%CMAKE%" == "" mkdir __build__ && cd __build__
|
||||
- if not "%CMAKE%" == "" cmake -DBUILD_TESTING=ON -DBOOST_INCLUDE_LIBRARIES=mp11 ..
|
||||
- if not "%CMAKE%" == "" cmake --build . --target tests --config %CONFIG%
|
||||
- if not "%CMAKE%" == "" ctest --output-on-failure --no-tests=error -C %CONFIG%
|
||||
|
||||
- if not "%CMAKE_SUBDIR%" == "" cd libs/mp11/test/cmake_subdir_test && mkdir __build__ && cd __build__
|
||||
- if not "%CMAKE_SUBDIR%" == "" cmake ..
|
||||
- if not "%CMAKE_SUBDIR%" == "" cmake --build . --config Debug && cmake --build . --target check --config Debug
|
||||
- if not "%CMAKE_SUBDIR%" == "" cmake --build . --config Release && cmake --build . --target check --config Release
|
||||
|
||||
- if not "%CMAKE_INSTALL%" == "" cd libs/mp11 && mkdir __build__ && cd __build__
|
||||
- if not "%CMAKE_INSTALL%" == "" cmake -DCMAKE_INSTALL_PREFIX=C:/cmake-prefix ..
|
||||
- if not "%CMAKE_INSTALL%" == "" cmake --build . --target install --config Debug
|
||||
- if not "%CMAKE_INSTALL%" == "" cmake --build . --target install --config Release
|
||||
- if not "%CMAKE_INSTALL%" == "" cd ../test/cmake_install_test && mkdir __build__ && cd __build__
|
||||
- if not "%CMAKE_INSTALL%" == "" cmake -DCMAKE_INSTALL_PREFIX=C:/cmake-prefix ..
|
||||
- if not "%CMAKE_INSTALL%" == "" cmake --build . --config Debug && cmake --build . --target check --config Debug
|
||||
- if not "%CMAKE_INSTALL%" == "" cmake --build . --config Release && cmake --build . --target check --config Release
|
||||
|
@ -1,6 +1,7 @@
|
||||
<style>
|
||||
|
||||
*:not(pre)>code { background: none; color: #600000; }
|
||||
:not(pre):not([class^=L])>code { background: none; color: #600000; }
|
||||
table tr.even, table tr.alt, table tr:nth-of-type(even) { background: none; }
|
||||
|
||||
</style>
|
||||
|
@ -15,6 +15,8 @@ Peter Dimov
|
||||
:listing-caption: Code Example
|
||||
:table-caption: Illustration
|
||||
:docinfo: private-footer
|
||||
:source-highlighter: rouge
|
||||
:source-language: c++
|
||||
|
||||
:leveloffset: +1
|
||||
|
||||
|
@ -33,7 +33,7 @@ using R1 = mp_transform<add_pointer_t, L1>; // std::tuple<void*, int*, float*>
|
||||
using L1 = std::tuple<void, int, float>;
|
||||
using L2 = mp_list<void, int, float>;
|
||||
|
||||
using R1 = mp_all<mp_transform<std::is_same, L1, L2>>; // mp_true
|
||||
using R1 = mp_apply<mp_all, mp_transform<std::is_same, L1, L2>>; // mp_true
|
||||
```
|
||||
|
||||
.Using mp_transform to compare the contents of two lists of integral constants
|
||||
@ -43,7 +43,7 @@ template<class T1, class T2> using eq = mp_bool<T1::value == T2::value>;
|
||||
using L1 = std::tuple<mp_int<1>, mp_int<2>, mp_int<3>>;
|
||||
using L2 = mp_list<mp_size_t<1>, mp_size_t<2>, mp_size_t<3>>;
|
||||
|
||||
using R1 = mp_all<mp_transform<eq, L1, L2>>; // mp_true
|
||||
using R1 = mp_apply<mp_all, mp_transform<eq, L1, L2>>; // mp_true
|
||||
```
|
||||
|
||||
.mp_transform on one list
|
||||
@ -262,7 +262,8 @@ Same as `mp_repeat_c` but with a type argument `N`. The number of copies is `N::
|
||||
|
||||
`mp_product<F, L1<T1...>, L2<T2...>, ..., Ln<Tn...>>` evaluates `F<U1, U2, ..., Un>` for values `Ui` taken from
|
||||
the Cartesian product of the lists, as if the elements `Ui` are formed by `n` nested loops, each traversing `Li`.
|
||||
It returns a list of the form `L1<V...>` containing the results of the application of `F`.
|
||||
It returns a list of the form `L1<V...>` containing the results of the application of `F`. The degenerate case
|
||||
of zero lists, `mp_product<F>`, returns `mp_list<F<>>`.
|
||||
|
||||
.mp_product on two lists
|
||||
[cols="<.^4m,4*^.^1m",width=85%]
|
||||
@ -284,6 +285,20 @@ It returns a list of the form `L1<V...>` containing the results of the applicati
|
||||
|
||||
As `mp_product`, but takes a quoted metafunction.
|
||||
|
||||
## mp_power_set<L>
|
||||
|
||||
template<class L> using mp_power_set = /*...*/;
|
||||
|
||||
`mp_power_set<L>` returns a list (of the same form as `L`) of all possible 2^n^ subsets of `L` (where `n` is the length of `L`.)
|
||||
|
||||
`mp_power_set<L<>>` returns `L<L<>>`.
|
||||
|
||||
`mp_power_set<L<T1>>` returns `L<L<>, L<T1>>`.
|
||||
|
||||
`mp_power_set<L<T1, T2>>` returns `L<L<>, L<T2>, L<T1>, L<T1, T2>>`.
|
||||
|
||||
`mp_power_set<L<T1, T...>>` returns the concatenation of `mp_power_set<L<T...>>` and that same list with `T1` prepended to each element.
|
||||
|
||||
## mp_drop_c<L, N>
|
||||
|
||||
template<class L, std::size_t N> using mp_drop_c = /*...*/;
|
||||
@ -472,6 +487,32 @@ Replaces the element of `L` at zero-based index `I` with `W` and returns the res
|
||||
|
||||
Same as `mp_replace_at_c`, but with a type argument `I`. `I::value` must be a nonnegative number.
|
||||
|
||||
## mp_rotate_left_c<L, N>
|
||||
|
||||
template<class L, std::size_t N> using mp_rotate_left_c = /*...*/;
|
||||
|
||||
Moves the `N % M` initial elements of the list `L` to the back, where `M` is the size of `L`. Empty
|
||||
lists are unchanged.
|
||||
|
||||
## mp_rotate_left<L, N>
|
||||
|
||||
template<class L, class N> using mp_rotate_left = /*...*/;
|
||||
|
||||
Same as `mp_rotate_left_c`, but with a type argument `N`. `N::value` must be a nonnegative number.
|
||||
|
||||
## mp_rotate_right_c<L, N>
|
||||
|
||||
template<class L, std::size_t N> using mp_rotate_right_c = /*...*/;
|
||||
|
||||
Moves the `N % M` trailing elements of the list `L` to the front, where `M` is the size of `L`. Empty
|
||||
lists are unchanged.
|
||||
|
||||
## mp_rotate_right<L, N>
|
||||
|
||||
template<class L, class N> using mp_rotate_right = /*...*/;
|
||||
|
||||
Same as `mp_rotate_right_c`, but with a type argument `N`. `N::value` must be a nonnegative number.
|
||||
|
||||
## mp_copy_if<L, P>
|
||||
|
||||
template<class L, template<class...> class P> using mp_copy_if = /*...*/;
|
||||
@ -502,6 +543,61 @@ Removes all elements `T` of `L` for which `mp_to_bool<P<T>>` is `mp_true` and re
|
||||
|
||||
As `mp_remove_if`, but takes a quoted metafunction.
|
||||
|
||||
## mp_flatten<L>
|
||||
|
||||
template<class L, class L2 = mp_clear<L>> using mp_flatten = /*...*/;
|
||||
|
||||
Replaces all elements `T` of `L` that are lists of the same form as `L2` (that is, those for which
|
||||
`mp_similar<T, L2>` is `mp_true`) with their elements and returns the result.
|
||||
|
||||
.Using mp_flatten
|
||||
```
|
||||
using L1 = tuple<int, tuple<>, void, tuple<float, double>>;
|
||||
using R1 = mp_flatten<L1>; // tuple<int, void, float, double>
|
||||
|
||||
using L2 = mp_list<int, mp_list<float>, tuple<void>>;
|
||||
using R2a = mp_flatten<L2>; // mp_list<int, float, tuple<void>>
|
||||
using R2b = mp_flatten<L2, tuple<>>; // mp_list<int, mp_list<float>, void>
|
||||
|
||||
using L3 = mp_list<mp_list<float>, mp_list<mp_list<void>>>;
|
||||
using R3 = mp_flatten<L3>; // mp_list<float, mp_list<void>>
|
||||
```
|
||||
|
||||
## mp_intersperse<L, S>
|
||||
|
||||
template<class L, class S> using mp_intersperse = /*...*/;
|
||||
|
||||
Inserts the separator `S` between the elements of the list `L`.
|
||||
|
||||
`mp_intersperse<L<>, S>` is `L<>`. `mp_intersperse<L<T1>, S>` is `L<T1>`.
|
||||
`mp_intersperse<L<T1, T2, T3, ..., Tn-1, Tn>, S>` is `L<T1, S, T2, S, T3, S, ..., Tn-1, S, Tn>`.
|
||||
|
||||
## mp_split<L, S>
|
||||
|
||||
template<class L, class S> using mp_split = /*...*/;
|
||||
|
||||
Splits the list `L` into segments at each separator `S` and returns a list of
|
||||
the segments.
|
||||
|
||||
`mp_split<L<>, S>` is `L<L<>>`. `mp_split<L<T...>, S>`, where `S` does not occur in `T...`,
|
||||
is `L<L<T...>>`. `mp_split<L<T1..., S, T2..., S, T3...>, S>` is `L<L<T1...>, L<T2...>, L<T3...>>`.
|
||||
|
||||
The segments may be empty; `mp_split<L<S, X, Y, S, S>, S>` is `L<L<>, L<X, Y>, L<>, L<>>`.
|
||||
|
||||
## mp_join<L, S>
|
||||
|
||||
template<class L, class S> using mp_join = /*...*/;
|
||||
|
||||
`mp_join` is the reverse operation of `mp_split`; it takes a list of segments `L` and joins
|
||||
them into a single list, inserting the separator `S` between them.
|
||||
|
||||
`mp_join<mp_split<L, S>, S>` yields back the original list `L`.
|
||||
|
||||
For example, `mp_split<L<X1, X2, S, X3>, S>` gives `L<L<X1, X2>, L<X3>>`, and
|
||||
`mp_join<L<L<X1, X2>, L<X3>>, S>` results in `L<X1, X2, S, X3>`.
|
||||
|
||||
`mp_join<L, S>` is equivalent to (and is implemented as) `mp_apply<mp_append, mp_intersperse<L, mp_list<S>>>`.
|
||||
|
||||
## mp_partition<L, P>
|
||||
|
||||
template<class L, template<class...> class P> using mp_partition = /*...*/;
|
||||
@ -653,12 +749,136 @@ As `mp_fold`, but takes a quoted metafunction.
|
||||
|
||||
As `mp_reverse_fold`, but takes a quoted metafunction.
|
||||
|
||||
## mp_partial_sum<L, V, F>
|
||||
|
||||
template<class L, class V, template<class...> class F> using mp_partial_sum = /*...*/;
|
||||
|
||||
`mp_partial_sum<L, V, F>` is similar to `mp_fold<L, V, F>`, but instead of its final result, it returns
|
||||
a list (of the same form as `L`) holding the intermediate results of the fold. The last element of the
|
||||
result of `mp_partial_sum` is the same as the result of `mp_fold`.
|
||||
|
||||
For example, `mp_fold<mp_list<X1, X2, X3>, V, F>` is `F<F<F<V, X1>, X2>, X3>`, but
|
||||
`mp_partial_sum<mp_list<X1, X2, X3>, V, F>` is `mp_list<F<V, X1>, F<F<V, X1>, X2>, F<F<F<V, X1>, X2>, X3>>`.
|
||||
|
||||
It's common for `F` to be `mp_plus`, in which case the result contains the partial sums of `L`.
|
||||
|
||||
.Using mp_partial_sum
|
||||
----
|
||||
using L1 = mp_list_c<int, 1, 2, 3, 4>;
|
||||
using R1 = mp_partial_sum<L1, mp_int<0>, mp_plus>; // mp_list_c<int, 1, 3, 6, 10>
|
||||
----
|
||||
|
||||
## mp_partial_sum_q<L, V, Q>
|
||||
|
||||
template<class L, class V, class Q> using mp_partial_sum_q =
|
||||
mp_partial_sum<L, V, Q::template fn>;
|
||||
|
||||
As `mp_partial_sum`, but takes a quoted metafunction.
|
||||
|
||||
## mp_pairwise_fold<L, F>
|
||||
|
||||
template<class L, template<class...> class F> using mp_pairwise_fold = /*...*/;
|
||||
|
||||
`mp_pairwise_fold<L, F>` returns a list of the same form as `L` whose elements are
|
||||
the result of the application of the binary metafunction `F` to each pair of adjacent
|
||||
elements of `L`. That is, `mp_pairwise_fold<L<T1, T2, T3>, F>` is
|
||||
`L<F<T1, T2>, F<T2, T3>>`.
|
||||
|
||||
The result has one fewer element than the original. If `L` has only one element, the
|
||||
result is an empty list. If `L` is an empty list, the result is also an empty list.
|
||||
|
||||
.Using mp_pairwise_fold
|
||||
----
|
||||
template<class L> using is_increasing = mp_all_of<
|
||||
mp_pairwise_fold<L, mp_less>, mp_to_bool>;
|
||||
----
|
||||
|
||||
## mp_pairwise_fold_q<L, Q>
|
||||
|
||||
template<class L, class Q> using mp_pairwise_fold_q =
|
||||
mp_pairwise_fold<L, Q::template fn>;
|
||||
|
||||
As `mp_pairwise_fold`, but takes a quoted metafunction.
|
||||
|
||||
.Using mp_pairwise_fold_q
|
||||
----
|
||||
template<class L, template<class...> class P> using is_sorted =
|
||||
mp_none_of<mp_pairwise_fold_q<L, mp_bind<P, _2, _1>>, mp_to_bool>;
|
||||
----
|
||||
|
||||
## mp_iterate<V, F, R>
|
||||
|
||||
template<class V, template<class...> class F, template<class...> class R>
|
||||
using mp_iterate = /*...*/;
|
||||
|
||||
`mp_iterate<V, F, R>` applies `R` to `V` successively until that's no longer possible,
|
||||
yielding the sequence `V`, `R<V>`, `R<R<V>>`, `R<R<R<V>>>`...
|
||||
|
||||
It then returns an `mp_list` whose elements are formed by applying `F` to the above
|
||||
sequence of values. That is, it returns `mp_list<F<V>, F<R<V>>, F<R<R<V>>>, ...>`.
|
||||
|
||||
`mp_iterate` is in a way the reverse operation of `mp_reverse_fold`. Given
|
||||
|
||||
template<class T, class U> struct cons {};
|
||||
struct nil {};
|
||||
|
||||
`mp_reverse_fold<mp_list<X1, X2, X3>, nil, cons>` produces `cons<X1, cons<X2, cons<X3, nil>>>`,
|
||||
which when passed as `V` to `mp_iterate<V, mp_first, mp_second>` recovers the original
|
||||
`mp_list<X1, X2, X3>`.
|
||||
|
||||
.Using mp_iterate
|
||||
----
|
||||
struct X1 {};
|
||||
struct X2 {};
|
||||
struct X3 {};
|
||||
|
||||
using L1 = mp_list<X1, X2, X3>;
|
||||
using R1 = mp_iterate<L1, mp_first, mp_rest>; // L1
|
||||
|
||||
template<class T, class U> struct cons {};
|
||||
struct nil {};
|
||||
|
||||
using V2 = mp_reverse_fold<L1, nil, cons>; // cons<X1, cons<X2, cons<X3, nil>>>
|
||||
using R2 = mp_iterate<V2, mp_first, mp_second>; // L1
|
||||
|
||||
struct Y1 {};
|
||||
struct Y2 { using value_type = double; using next_type = Y1; };
|
||||
struct Y3 { using value_type = float; using next_type = Y2; };
|
||||
struct Y4 { using value_type = int; using next_type = Y3; };
|
||||
|
||||
template<class T> using value_type = typename T::value_type;
|
||||
template<class T> using next_type = typename T::next_type;
|
||||
|
||||
using R3 = mp_iterate<Y4, mp_identity_t, next_type>; // mp_list<Y4, Y3, Y2, Y1>
|
||||
using R4 = mp_iterate<Y4, value_type, next_type>; // mp_list<int, float, double>
|
||||
----
|
||||
|
||||
## mp_iterate_q<V, Qf, Qr>
|
||||
|
||||
template<class V, class Qf, class Qr> using mp_iterate_q =
|
||||
mp_iterate<V, Qf::template fn, Qr::template fn>;
|
||||
|
||||
As `mp_iterate`, but takes quoted metafunctions.
|
||||
|
||||
## mp_unique<L>
|
||||
|
||||
template<class L> using mp_unique = /*...*/;
|
||||
|
||||
`mp_unique<L>` returns a list of the same form as `L` with the duplicate elements removed.
|
||||
|
||||
## mp_unique_if<L, P>
|
||||
|
||||
template<class L, template<class...> class P> using mp_unique_if = /*...*/;
|
||||
|
||||
As `mp_unique`, but two elements `T` and `U` are considered duplicates when `mp_to_bool<P<T, U>>` is `mp_true`.
|
||||
|
||||
## mp_unique_if_q<L, Q>
|
||||
|
||||
template<class L, class Q> using mp_unique_if_q =
|
||||
mp_unique_if<L, Q::template fn>;
|
||||
|
||||
As `mp_unique_if`, but takes a quoted metafunction.
|
||||
|
||||
## mp_all_of<L, P>
|
||||
|
||||
template<class L, template<class...> class P> using mp_all_of =
|
||||
@ -722,6 +942,10 @@ template<class... T> void print( std::tuple<T...> const & tp )
|
||||
}
|
||||
```
|
||||
|
||||
In case the elements of the list `L` are not default-constructible, you can use
|
||||
`mp_for_each<mp_transform<mp_identity, L>>`, which would call `f` with `mp_identity<T>()`
|
||||
instead of `T()`.
|
||||
|
||||
## mp_with_index<N>(i, f)
|
||||
|
||||
template<std::size_t N, class F>
|
||||
@ -743,7 +967,7 @@ template<class... T> void print( std::variant<T...> const& v )
|
||||
{
|
||||
mp_with_index<sizeof...(T)>( v.index(), [&]( auto I ) {
|
||||
|
||||
// I is mp_size_t<v.index()> here
|
||||
// I is mp_size_t<v.index()>{} here
|
||||
|
||||
std::cout << std::get<I>( v ) << std::endl;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
////
|
||||
Copyright 2019 Peter Dimov
|
||||
Copyright 2019-2020 Peter Dimov
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
|
||||
@ -10,6 +10,30 @@ http://www.boost.org/LICENSE_1_0.txt
|
||||
[#changelog]
|
||||
# Revision History
|
||||
|
||||
## Changes in 1.77.0
|
||||
|
||||
* Added `mp_intersperse`, `mp_split`, `mp_join`
|
||||
|
||||
## Changes in 1.75.0
|
||||
|
||||
* Added `mp_pairwise_fold` (suggested by Barry Revzin)
|
||||
* Removed `mp_invoke` (use `mp_invoke_q`)
|
||||
|
||||
## Changes in 1.74.0
|
||||
|
||||
* Improved compilation performance of `mp_with_index<N>` for large `N`
|
||||
* Added `tuple_transform` (contributed by Hans Dembinski)
|
||||
|
||||
## Changes in 1.73.0
|
||||
|
||||
* Added `mp_unique_if` (contributed by Kris Jusiak)
|
||||
* Added `mp_flatten`
|
||||
* Added `mp_rotate_left`, `mp_rotate_right` (contributed by Duncan Barber)
|
||||
* Added `mp_compose`
|
||||
* Added `mp_power_set`
|
||||
* Added `mp_partial_sum`
|
||||
* Added `mp_iterate`
|
||||
|
||||
## Changes in 1.70.0
|
||||
|
||||
* Renamed `mp_invoke` to `mp_invoke_q`
|
||||
|
@ -370,7 +370,7 @@ template<class... Tp,
|
||||
|
||||
## Computing Return Types
|
||||
|
||||
C++17 has a standard variant type, called `std::variant`. It also defines a function template
|
||||
{cpp}17 has a standard variant type, called `std::variant`. It also defines a function template
|
||||
`std::visit` that can be used to apply a function to the contained value of one or more variants.
|
||||
So for instance, if the variant `v1` contains `1`, and the variant `v2` contains `2.0f`,
|
||||
`std::visit(f, v1, v2)` will call `f(1, 2.0f)`.
|
||||
@ -410,21 +410,31 @@ We'll first define a helper quoted metafunction `Qret<F>` that returns the resul
|
||||
decltype( std::declval<F>()( std::declval<T>()... ) );
|
||||
};
|
||||
|
||||
(Unfortunately, we can't just define this metafunction inside `rvisit`; the language prohibits defining template aliases inside functions.)
|
||||
It turns out that {cpp}17 already contains a metafunction that returns the result of the application of a function `F` to arguments
|
||||
of type `T...`: `std::invoke_result_t<F, T...>`. We can make use of it to simplify our `Qret` to
|
||||
|
||||
template<class F> struct Qret
|
||||
{
|
||||
template<class... T> using fn = std::invoke_result_t<F, T...>;
|
||||
};
|
||||
|
||||
which in Mp11 can be expressed more concisely as
|
||||
|
||||
using Qret = mp_bind_front<std::invoke_result_t, F>;
|
||||
|
||||
With `Qret` in hand, a `variant` of the possible return types is just a matter of applying it over the possible combinations of the variant values:
|
||||
|
||||
using R = mp_product_q<Qret<F>, std::remove_reference_t<V>...>;
|
||||
using R = mp_product_q<Qret, remove_cv_ref<V>...>;
|
||||
|
||||
Why does this work? `mp_product<F, L1<T1...>, L2<T2...>, ..., Ln<Tn...>>` returns `L1<F<U1, U2, ..., Un>, ...>`, where `Ui` traverse all
|
||||
possible combinations of list values. Since in our case all `Li` are `std::variant`, the result will also be `std::variant`. (`mp_product_q` is
|
||||
the same as `mp_product`, but for quoted metafunctions such as our `Qret<F>`.)
|
||||
the same as `mp_product`, but for quoted metafunctions such as our `Qret`.)
|
||||
|
||||
One more step remains. Suppose that, as above, we're passing two variants of type `std::variant<short, int, float>` and `F` is
|
||||
`[]( auto const& x, auto const& y ){ return x + y; }`. This will generate `R` of length 9, one per each combination, but many of those
|
||||
elements will be the same, either `int` or `float`, and we need to filter out the duplicates. So, we pass the result to `mp_unique`:
|
||||
|
||||
using R = mp_unique<mp_product_q<Qret<F>, std::remove_reference_t<V>...>>;
|
||||
using R = mp_unique<mp_product_q<Qret, remove_cv_ref<V>...>>;
|
||||
|
||||
and we're done:
|
||||
|
||||
@ -438,15 +448,14 @@ and we're done:
|
||||
|
||||
using namespace boost::mp11;
|
||||
|
||||
template<class F> struct Qret
|
||||
{
|
||||
template<class... T> using fn =
|
||||
decltype( std::declval<F>()( std::declval<T>()... ) );
|
||||
};
|
||||
template<class T> using remove_cv_ref = typename std::remove_cv<
|
||||
typename std::remove_reference<T>::type>::type;
|
||||
|
||||
template<class F, class... V> auto rvisit( F&& f, V&&... v )
|
||||
{
|
||||
using R = mp_unique<mp_product_q<Qret<F>, std::remove_reference_t<V>...>>;
|
||||
using Qret = mp_bind_front<std::invoke_result_t, F>;
|
||||
|
||||
using R = mp_unique<mp_product_q<Qret, remove_cv_ref<V>...>>;
|
||||
|
||||
return std::visit( [&]( auto&&... x )
|
||||
{ return R( std::forward<F>(f)( std::forward<decltype(x)>(x)... ) ); },
|
||||
@ -472,7 +481,7 @@ int main()
|
||||
|
||||
print_variant( "v1", v1 );
|
||||
|
||||
std::variant<short, int, double> v2( 3.14 );
|
||||
std::variant<short, int, double> const v2( 3.14 );
|
||||
|
||||
print_variant( "v2", v2 );
|
||||
|
||||
|
@ -18,3 +18,14 @@ necessary support infrastructure for `mp_list` and `std::tuple`
|
||||
to be valid link:../../../../libs/mpl[MPL] sequences.
|
||||
|
||||
NOTE: `mpl.hpp` is not included by `<boost/mp11.hpp>`.
|
||||
|
||||
It's also possible to only enable support for `mp_list` by
|
||||
including `<boost/mp11/mpl_list.hpp>`, and for `std::tuple`
|
||||
by including `<boost/mp11/mpl_tuple.hpp>`. This may be required
|
||||
because some libraries, such as Boost.Fusion, contain their own MPL
|
||||
support for `std::tuple`, which conflicts with Mp11's one.
|
||||
|
||||
.Converting an existing MPL Sequence into an mp_list
|
||||
```
|
||||
using L = mpl::copy<Sequence, mpl::back_inserter<mp11::mp_list<>>>::type;
|
||||
```
|
||||
|
@ -32,7 +32,24 @@ The name of the function doesn't match the {cpp}17 one to avoid ambiguities when
|
||||
|
||||
template<class Tp, class F> constexpr F tuple_for_each(Tp&& tp, F&& f);
|
||||
|
||||
`tuple_for_each(tp, f)` applies the function object `f` to each element of `tp` by evaluating the
|
||||
`tuple_for_each(tp, f)` applies the function object `f` to each element of `tp` in order by evaluating the
|
||||
expression `f(std::get<J>(std::forward<Tp>(tp)))` for `J` in 0..`N-1`, where `N` is `std::tuple_size<typename std::remove_reference<Tp>::type>::value`.
|
||||
|
||||
Returns `std::forward<F>(f)`.
|
||||
|
||||
## tuple_transform(f, tp...)
|
||||
|
||||
template<class F, class... Tp> constexpr /*...*/ tuple_transform(F const& f, Tp&&... tp);
|
||||
|
||||
`tuple_transform(f, tp...)` accepts a function object `f` followed by one or more tuples of equal length
|
||||
(`std::tuple`, `std::pair` and `std::array` are considered tuples.)
|
||||
|
||||
The callable `f` must accept as many arguments as there are tuples. The function object is called with the
|
||||
first elements of each tuple, with the second elements of each tuple, and so on, as if by evaluating
|
||||
the expression `f(std::get<J>(std::forward<Tp>(tp))...)` for `J` in 0..`N-1`, where `N` is the length of
|
||||
the tuples.
|
||||
|
||||
The order in which the elements of the tuples are processed is unspecified.
|
||||
|
||||
The results are returned as a `std::tuple<T...>` with `T...` deduced from the return values of `f` (lvalue
|
||||
references are preserved, rvalue references are returned by value.)
|
||||
|
@ -1,5 +1,5 @@
|
||||
////
|
||||
Copyright 2017, 2019 Peter Dimov
|
||||
Copyright 2017-2020 Peter Dimov
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
|
||||
@ -113,7 +113,7 @@ is to avoid evaluating `F<U...>` when the condition is `true` as it may not be v
|
||||
.Using mp_eval_if_c to select the first pack element, or void
|
||||
```
|
||||
template<class... T> using first_or_void =
|
||||
mp_eval_if_c<sizeof...(T) == 0, void, mp_apply, mp_first, mp_list<T...>>;
|
||||
mp_eval_if_c<sizeof...(T) == 0, void, mp_first, mp_list<T...>>;
|
||||
```
|
||||
|
||||
## mp_eval_if<C, T, F, U...>
|
||||
@ -175,6 +175,12 @@ Like `mp_valid`, but takes a quoted metafunction.
|
||||
|
||||
`mp_eval_or<T, F, U...>` is an alias for `F<U...>` when this expression is valid, for `T` otherwise.
|
||||
|
||||
.Using mp_eval_or to select the first pack element, or void
|
||||
```
|
||||
template<class... T> using first_or_void =
|
||||
mp_eval_or<void, mp_first, mp_list<T...>>;
|
||||
```
|
||||
|
||||
## mp_eval_or_q<T, Q, U...>
|
||||
|
||||
template<class T, class Q, class... U> using mp_eval_or_q =
|
||||
@ -182,6 +188,20 @@ Like `mp_valid`, but takes a quoted metafunction.
|
||||
|
||||
Like `mp_eval_or`, but takes a quoted metafunction.
|
||||
|
||||
## mp_valid_and_true<F, T...>
|
||||
|
||||
template<template<class...> class F, class... T> using mp_valid_and_true =
|
||||
mp_eval_or<mp_false, F, T...>;
|
||||
|
||||
`mp_valid_and_true<F, T...>` is an alias for `F<T...>` when this expression is valid, for `mp_false` otherwise.
|
||||
|
||||
## mp_valid_and_true_q<Q, T...>
|
||||
|
||||
template<class Q, class... T> using mp_valid_and_true_q =
|
||||
mp_valid_and_true<Q::template fn, T...>;
|
||||
|
||||
Like `mp_valid_and_true`, but takes a quoted metafunction.
|
||||
|
||||
## mp_cond<C, T, R...>
|
||||
|
||||
template<class C, class T, class... R> using mp_cond = /*...*/;
|
||||
@ -251,19 +271,19 @@ using R1 = mp_transform_q<mp_quote_trait<std::add_pointer>, L1>;
|
||||
using LQ = mp_list<mp_quote<std::is_const>, mp_quote<std::is_volatile>>;
|
||||
|
||||
template<class T> using is_const_and_volatile =
|
||||
mp_all<mp_product<mp_invoke_q, LQ, mp_list<T>>>;
|
||||
mp_apply<mp_all, mp_product<mp_invoke_q, LQ, mp_list<T>>>;
|
||||
```
|
||||
|
||||
.Using mp_invoke_q to invoke a list of metafunctions, technique 2
|
||||
```
|
||||
template<class T> using is_const_and_volatile =
|
||||
mp_all<mp_transform_q<mp_bind_back<mp_invoke_q, T>, LQ>>;
|
||||
mp_apply<mp_all, mp_transform_q<mp_bind_back<mp_invoke_q, T>, LQ>>;
|
||||
```
|
||||
|
||||
.Using mp_invoke_q to invoke a list of metafunctions, technique 3
|
||||
```
|
||||
template<class T> using is_const_and_volatile =
|
||||
mp_all<mp_transform<mp_invoke_q, LQ, mp_fill<LQ, T>>>;
|
||||
mp_apply<mp_all, mp_transform<mp_invoke_q, LQ, mp_fill<LQ, T>>>;
|
||||
```
|
||||
|
||||
## mp_not_fn<P>
|
||||
@ -282,3 +302,17 @@ That is, it negates the result of `P`.
|
||||
template<class Q> using mp_not_fn_q = mp_not_fn<Q::template fn>;
|
||||
|
||||
As `mp_not_fn`, but takes a quoted metafunction.
|
||||
|
||||
## mp_compose<F...>
|
||||
|
||||
template<template<class...> class... F> struct mp_compose;
|
||||
|
||||
`mp_compose<F1, F2, ..., Fn>` is a quoted metafunction that applies
|
||||
`F1`, `F2`, ..., `Fn` to its argument, in sequence. That is,
|
||||
`mp_compose<F1, F2, ..., Fn>::fn<T...>` is `Fn<...F2<F1<T...>>...>`.
|
||||
|
||||
## mp_compose_q<Q...>
|
||||
|
||||
template<class... Q> struct mp_compose_q;
|
||||
|
||||
As `mp_compose`, but takes quoted metafunctions.
|
||||
|
@ -254,7 +254,9 @@ template<class L, class N> using mp_repeat = typename detail::mp_repeat_c_impl<L
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<template<class...> class F, class P, class... L> struct mp_product_impl_2;
|
||||
template<template<class...> class F, class P, class... L> struct mp_product_impl_2
|
||||
{
|
||||
};
|
||||
|
||||
template<template<class...> class F, class P> struct mp_product_impl_2<F, P>
|
||||
{
|
||||
@ -266,7 +268,14 @@ template<template<class...> class F, class P, template<class...> class L1, class
|
||||
using type = mp_append<typename mp_product_impl_2<F, mp_push_back<P, T1>, L...>::type...>;
|
||||
};
|
||||
|
||||
template<template<class...> class F, class... L> struct mp_product_impl;
|
||||
template<template<class...> class F, class... L> struct mp_product_impl
|
||||
{
|
||||
};
|
||||
|
||||
template<template<class...> class F> struct mp_product_impl<F>
|
||||
{
|
||||
using type = mp_list< F<> >;
|
||||
};
|
||||
|
||||
template<template<class...> class F, class L1, class... L> struct mp_product_impl<F, L1, L...>
|
||||
{
|
||||
@ -405,31 +414,31 @@ struct mp_take_c_impl<4, L<T1, T2, T3, T4, T...>>
|
||||
template<template<class...> class L, class T1, class T2, class T3, class T4, class T5, class... T>
|
||||
struct mp_take_c_impl<5, L<T1, T2, T3, T4, T5, T...>>
|
||||
{
|
||||
using type = L<T1, T2, T3, T4, T5>;
|
||||
using type = L<T1, T2, T3, T4, T5>;
|
||||
};
|
||||
|
||||
template<template<class...> class L, class T1, class T2, class T3, class T4, class T5, class T6, class... T>
|
||||
struct mp_take_c_impl<6, L<T1, T2, T3, T4, T5, T6, T...>>
|
||||
{
|
||||
using type = L<T1, T2, T3, T4, T5, T6>;
|
||||
using type = L<T1, T2, T3, T4, T5, T6>;
|
||||
};
|
||||
|
||||
template<template<class...> class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class... T>
|
||||
struct mp_take_c_impl<7, L<T1, T2, T3, T4, T5, T6, T7, T...>>
|
||||
{
|
||||
using type = L<T1, T2, T3, T4, T5, T6, T7>;
|
||||
using type = L<T1, T2, T3, T4, T5, T6, T7>;
|
||||
};
|
||||
|
||||
template<template<class...> class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class... T>
|
||||
struct mp_take_c_impl<8, L<T1, T2, T3, T4, T5, T6, T7, T8, T...>>
|
||||
{
|
||||
using type = L<T1, T2, T3, T4, T5, T6, T7, T8>;
|
||||
using type = L<T1, T2, T3, T4, T5, T6, T7, T8>;
|
||||
};
|
||||
|
||||
template<template<class...> class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class... T>
|
||||
struct mp_take_c_impl<9, L<T1, T2, T3, T4, T5, T6, T7, T8, T9, T...>>
|
||||
{
|
||||
using type = L<T1, T2, T3, T4, T5, T6, T7, T8, T9>;
|
||||
using type = L<T1, T2, T3, T4, T5, T6, T7, T8, T9>;
|
||||
};
|
||||
|
||||
template<template<class...> class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class... T, std::size_t N>
|
||||
@ -519,6 +528,19 @@ template<class L, class V> using mp_remove = typename detail::mp_remove_impl<L,
|
||||
// mp_remove_if<L, P>
|
||||
// in detail/mp_remove_if.hpp
|
||||
|
||||
// mp_flatten<L, L2 = mp_clear<L>>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L2> struct mp_flatten_impl
|
||||
{
|
||||
template<class T> using fn = mp_if<mp_similar<L2, T>, T, mp_list<T>>;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L, class L2 = mp_clear<L>> using mp_flatten = mp_apply<mp_append, mp_push_front<mp_transform_q<detail::mp_flatten_impl<L2>, L>, mp_clear<L>>>;
|
||||
|
||||
// mp_partition<L, P>
|
||||
namespace detail
|
||||
{
|
||||
@ -950,6 +972,32 @@ template<template<class...> class L, class... T> struct mp_unique_impl<L<T...>>
|
||||
|
||||
template<class L> using mp_unique = typename detail::mp_unique_impl<L>::type;
|
||||
|
||||
// mp_unique_if<L, P>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<template<class...> class P> struct mp_unique_if_push_back
|
||||
{
|
||||
template<class...> struct impl
|
||||
{
|
||||
};
|
||||
|
||||
template<template<class...> class L, class... Ts, class T>
|
||||
struct impl<L<Ts...>, T>
|
||||
{
|
||||
using type = mp_if<mp_any<P<Ts, T>...>, L<Ts...>, L<Ts..., T>>;
|
||||
};
|
||||
|
||||
template<class... T> using fn = typename impl<T...>::type;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L, template<class...> class P>
|
||||
using mp_unique_if = mp_fold_q<L, mp_clear<L>, detail::mp_unique_if_push_back<P>>;
|
||||
|
||||
template<class L, class Q> using mp_unique_if_q = mp_unique_if<L, Q::template fn>;
|
||||
|
||||
// mp_all_of<L, P>
|
||||
template<class L, template<class...> class P> using mp_all_of = mp_bool< mp_count_if<L, P>::value == mp_size<L>::value >;
|
||||
template<class L, class Q> using mp_all_of_q = mp_all_of<L, Q::template fn>;
|
||||
@ -1062,10 +1110,196 @@ struct mp_starts_with_impl<L1<T1...>, L2<T2...> > {
|
||||
template<class L1, class L2>
|
||||
using mp_starts_with = typename detail::mp_starts_with_impl<L1, L2>::type;
|
||||
|
||||
// mp_rotate_left(_c)<L, N>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
// limit divisor to 1 to avoid division by 0 and give a rotation of 0 for lists containing 0 or 1 elements
|
||||
template<std::size_t Ln, std::size_t N> using canonical_left_rotation = mp_size_t<N % (Ln == 0? 1: Ln)>;
|
||||
|
||||
// perform right rotation as a left rotation by inverting the number of elements to rotate
|
||||
template<std::size_t Ln, std::size_t N> using canonical_right_rotation = mp_size_t<Ln - N % (Ln == 0? 1: Ln)>;
|
||||
|
||||
// avoid errors when rotating fixed-sized lists by using mp_list for the transformation
|
||||
template<class L, class N, class L2 = mp_rename<L, mp_list>> using mp_rotate_impl = mp_assign<L, mp_append< mp_drop<L2, N>, mp_take<L2, N> >>;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L, std::size_t N> using mp_rotate_left_c = detail::mp_rotate_impl<L, detail::canonical_left_rotation<mp_size<L>::value, N>>;
|
||||
template<class L, class N> using mp_rotate_left = mp_rotate_left_c<L, std::size_t{ N::value }>;
|
||||
|
||||
// mp_rotate_right(_c)<L, N>
|
||||
template<class L, std::size_t N> using mp_rotate_right_c = mp_rotate_left<L, detail::canonical_right_rotation<mp_size<L>::value, N>>;
|
||||
template<class L, class N> using mp_rotate_right = mp_rotate_right_c<L, std::size_t{ N::value }>;
|
||||
|
||||
// mp_min_element<L, P>
|
||||
// mp_max_element<L, P>
|
||||
// in detail/mp_min_element.hpp
|
||||
|
||||
// mp_power_set<L>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L> struct mp_power_set_impl;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L> using mp_power_set = typename detail::mp_power_set_impl<L>::type;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 )
|
||||
|
||||
template<template<class...> class L, class... T> struct mp_power_set_impl< L<T...> >
|
||||
{
|
||||
static_assert( sizeof...(T) == 0, "T... must be empty" );
|
||||
using type = L< L<> >;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
template<template<class...> class L> struct mp_power_set_impl< L<> >
|
||||
{
|
||||
using type = L< L<> >;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
template<template<class...> class L, class T1, class... T> struct mp_power_set_impl< L<T1, T...> >
|
||||
{
|
||||
using S1 = mp_power_set< L<T...> >;
|
||||
|
||||
template<class L2> using _f = mp_push_front<L2, T1>;
|
||||
|
||||
using S2 = mp_transform<_f, S1>;
|
||||
|
||||
using type = mp_append< S1, S2 >;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// mp_partial_sum<L, V, F>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<template<class...> class F> struct mp_partial_sum_impl_f
|
||||
{
|
||||
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1900 )
|
||||
|
||||
template<class V, class T> using fn = mp_list<F<mp_first<V>, T>, mp_push_back<mp_second<V>, F<mp_first<V>, T>> >;
|
||||
|
||||
#else
|
||||
|
||||
template<class V, class T, class N = F<mp_first<V>, T>> using fn = mp_list<N, mp_push_back<mp_second<V>, N>>;
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L, class V, template<class...> class F> using mp_partial_sum = mp_second<mp_fold_q<L, mp_list<V, mp_clear<L>>, detail::mp_partial_sum_impl_f<F>> >;
|
||||
template<class L, class V, class Q> using mp_partial_sum_q = mp_partial_sum<L, V, Q::template fn>;
|
||||
|
||||
// mp_iterate<V, F, R>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class V, template<class...> class F, template<class...> class R, class N> struct mp_iterate_impl;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class V, template<class...> class F, template<class...> class R> using mp_iterate = typename detail::mp_iterate_impl<V, F, R, mp_valid<R, V>>::type;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class V, template<class...> class F, template<class...> class R> struct mp_iterate_impl<V, F, R, mp_false>
|
||||
{
|
||||
template<class X> using _f = mp_list<F<X>>;
|
||||
using type = mp_eval_or<mp_list<>, _f, V>;
|
||||
};
|
||||
|
||||
template<class V, template<class...> class F, template<class...> class R> struct mp_iterate_impl<V, F, R, mp_true>
|
||||
{
|
||||
using type = mp_push_front<mp_iterate<R<V>, F, R>, F<V>>;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class V, class Qf, class Qr> using mp_iterate_q = mp_iterate<V, Qf::template fn, Qr::template fn>;
|
||||
|
||||
// mp_pairwise_fold<L, F>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L, class Q> using mp_pairwise_fold_impl = mp_transform_q<Q, mp_pop_back<L>, mp_pop_front<L>>;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L, class Q> using mp_pairwise_fold_q = mp_eval_if<mp_empty<L>, mp_clear<L>, detail::mp_pairwise_fold_impl, L, Q>;
|
||||
template<class L, template<class...> class F> using mp_pairwise_fold = mp_pairwise_fold_q<L, mp_quote<F>>;
|
||||
|
||||
// mp_intersperse<L, S>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L, class S> struct mp_intersperse_impl
|
||||
{
|
||||
};
|
||||
|
||||
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 )
|
||||
|
||||
template<template<class...> class L, class... T, class S> struct mp_intersperse_impl<L<T...>, S>
|
||||
{
|
||||
static_assert( sizeof...(T) == 0, "T... must be empty" );
|
||||
using type = L<>;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
template<template<class...> class L, class S> struct mp_intersperse_impl<L<>, S>
|
||||
{
|
||||
using type = L<>;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
template<template<class...> class L, class T1, class... T, class S> struct mp_intersperse_impl<L<T1, T...>, S>
|
||||
{
|
||||
using type = mp_append<L<T1>, L<S, T>...>;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L, class S> using mp_intersperse = typename detail::mp_intersperse_impl<L, S>::type;
|
||||
|
||||
// mp_split<L, S>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L, class S, class J> struct mp_split_impl;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L, class S> using mp_split = typename detail::mp_split_impl<L, S, mp_find<L, S>>::type;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L, class S, class J> using mp_split_impl_ = mp_push_front<mp_split<mp_drop_c<L, J::value + 1>, S>, mp_take<L, J>>;
|
||||
|
||||
template<class L, class S, class J> struct mp_split_impl
|
||||
{
|
||||
using type = mp_eval_if_c<mp_size<L>::value == J::value, mp_push_back<mp_clear<L>, L>, mp_split_impl_, L, S, J>;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// mp_join<L, S>
|
||||
|
||||
template<class L, class S> using mp_join = mp_apply<mp_append, mp_intersperse<L, mp_list<S>>>;
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
|
@ -47,7 +47,9 @@
|
||||
|
||||
# endif
|
||||
|
||||
#elif defined(__clang__)
|
||||
#endif
|
||||
|
||||
#if defined(__clang__)
|
||||
|
||||
// Clang
|
||||
|
||||
@ -123,25 +125,14 @@
|
||||
|
||||
// BOOST_MP11_DEPRECATED(msg)
|
||||
|
||||
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1900 )
|
||||
#if BOOST_MP11_WORKAROUND( BOOST_MP11_CLANG, < 304 )
|
||||
# define BOOST_MP11_DEPRECATED(msg)
|
||||
#elif BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, < 50000 )
|
||||
#elif defined(__GNUC__) || defined(__clang__)
|
||||
# define BOOST_MP11_DEPRECATED(msg) __attribute__((deprecated(msg)))
|
||||
#elif BOOST_MP11_CLANG
|
||||
# if defined(__has_cpp_attribute)
|
||||
// 3.8 warns about [[deprecated]] when in C++11 mode
|
||||
// so we only use it on 3.9 and above, detected via [[fallthrough]]
|
||||
// can't version check because Apple
|
||||
# if __has_cpp_attribute(deprecated) && __has_cpp_attribute(fallthrough)
|
||||
# define BOOST_MP11_DEPRECATED(msg) [[deprecated(msg)]]
|
||||
# else
|
||||
# define BOOST_MP11_DEPRECATED(msg)
|
||||
# endif
|
||||
# else // defined(__has_cpp_attribute)
|
||||
# define BOOST_MP11_DEPRECATED(msg)
|
||||
# endif
|
||||
#else
|
||||
#elif defined(_MSC_VER) && _MSC_VER >= 1900
|
||||
# define BOOST_MP11_DEPRECATED(msg) [[deprecated(msg)]]
|
||||
#else
|
||||
# define BOOST_MP11_DEPRECATED(msg)
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_MP11_DETAIL_CONFIG_HPP_INCLUDED
|
||||
|
@ -21,16 +21,7 @@ namespace mp11
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L, class V> struct mp_count_impl;
|
||||
|
||||
#if defined( BOOST_MP11_HAS_FOLD_EXPRESSIONS )
|
||||
|
||||
template<template<class...> class L, class... T, class V> struct mp_count_impl<L<T...>, V>
|
||||
{
|
||||
using type = mp_size_t<(std::is_same<T, V>::value + ... + 0)>;
|
||||
};
|
||||
|
||||
#elif !defined( BOOST_MP11_NO_CONSTEXPR )
|
||||
#if !defined( BOOST_MP11_NO_CONSTEXPR )
|
||||
|
||||
constexpr std::size_t cx_plus()
|
||||
{
|
||||
@ -39,15 +30,42 @@ constexpr std::size_t cx_plus()
|
||||
|
||||
template<class T1, class... T> constexpr std::size_t cx_plus(T1 t1, T... t)
|
||||
{
|
||||
return t1 + cx_plus(t...);
|
||||
return static_cast<std::size_t>(t1) + cx_plus(t...);
|
||||
}
|
||||
|
||||
template<class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class... T>
|
||||
constexpr std::size_t cx_plus(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T... t)
|
||||
{
|
||||
return t1 + t2 + t3 + t4 + t5 + t6 + t7 + t8 + t9 + t10 + cx_plus(t...);
|
||||
return static_cast<std::size_t>(t1 + t2 + t3 + t4 + t5 + t6 + t7 + t8 + t9 + t10) + cx_plus(t...);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template<class L, class V> struct mp_count_impl;
|
||||
|
||||
#if defined( BOOST_MP11_HAS_CXX14_CONSTEXPR )
|
||||
|
||||
template<class V, class... T> constexpr std::size_t cx_count()
|
||||
{
|
||||
constexpr bool a[] = { false, std::is_same<T, V>::value... };
|
||||
|
||||
std::size_t r = 0;
|
||||
|
||||
for( std::size_t i = 1; i < sizeof...(T) + 1; ++i )
|
||||
{
|
||||
r += a[ i ];
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
template<template<class...> class L, class... T, class V> struct mp_count_impl<L<T...>, V>
|
||||
{
|
||||
using type = mp_size_t<cx_count<V, T...>()>;
|
||||
};
|
||||
|
||||
#elif !defined( BOOST_MP11_NO_CONSTEXPR )
|
||||
|
||||
template<template<class...> class L, class... T, class V> struct mp_count_impl<L<T...>, V>
|
||||
{
|
||||
using type = mp_size_t<cx_plus(std::is_same<T, V>::value...)>;
|
||||
@ -72,11 +90,25 @@ namespace detail
|
||||
|
||||
template<class L, template<class...> class P> struct mp_count_if_impl;
|
||||
|
||||
#if defined( BOOST_MP11_HAS_FOLD_EXPRESSIONS ) && !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 )
|
||||
#if defined( BOOST_MP11_HAS_CXX14_CONSTEXPR ) && !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1930 )
|
||||
|
||||
template<template<class...> class P, class... T> constexpr std::size_t cx_count_if()
|
||||
{
|
||||
constexpr bool a[] = { false, static_cast<bool>( P<T>::value )... };
|
||||
|
||||
std::size_t r = 0;
|
||||
|
||||
for( std::size_t i = 1; i < sizeof...(T) + 1; ++i )
|
||||
{
|
||||
r += a[ i ];
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
template<template<class...> class L, class... T, template<class...> class P> struct mp_count_if_impl<L<T...>, P>
|
||||
{
|
||||
using type = mp_size_t<(mp_to_bool<P<T>>::value + ... + 0)>;
|
||||
using type = mp_size_t<cx_count_if<P, T...>()>;
|
||||
};
|
||||
|
||||
#elif !defined( BOOST_MP11_NO_CONSTEXPR )
|
||||
|
38
include/boost/mp11/detail/mp_front.hpp
Normal file
38
include/boost/mp11/detail/mp_front.hpp
Normal file
@ -0,0 +1,38 @@
|
||||
#ifndef BOOST_MP11_DETAIL_MP_FRONT_HPP_INCLUDED
|
||||
#define BOOST_MP11_DETAIL_MP_FRONT_HPP_INCLUDED
|
||||
|
||||
// Copyright 2015-2021 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
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
// mp_front<L>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L> struct mp_front_impl
|
||||
{
|
||||
// An error "no type named 'type'" here means that the argument to mp_front
|
||||
// is either not a list, or is an empty list
|
||||
};
|
||||
|
||||
template<template<class...> class L, class T1, class... T> struct mp_front_impl<L<T1, T...>>
|
||||
{
|
||||
using type = T1;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L> using mp_front = typename detail::mp_front_impl<L>::type;
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_DETAIL_MP_FRONT_HPP_INCLUDED
|
@ -9,6 +9,17 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/utility.hpp>
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
|
||||
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1930 )
|
||||
|
||||
// not exactly good practice, but...
|
||||
namespace std
|
||||
{
|
||||
template<class... _Types> class tuple;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
@ -19,18 +30,51 @@ namespace mp11
|
||||
namespace detail
|
||||
{
|
||||
|
||||
#if !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1930 )
|
||||
|
||||
template<class T> using mpmf_wrap = mp_identity<T>;
|
||||
template<class T> using mpmf_unwrap = typename T::type;
|
||||
|
||||
#else
|
||||
|
||||
template<class... T> struct mpmf_tuple {};
|
||||
|
||||
template<class T> struct mpmf_wrap_impl
|
||||
{
|
||||
using type = mp_identity<T>;
|
||||
};
|
||||
|
||||
template<class... T> struct mpmf_wrap_impl< std::tuple<T...> >
|
||||
{
|
||||
using type = mp_identity< mpmf_tuple<T...> >;
|
||||
};
|
||||
|
||||
template<class T> using mpmf_wrap = typename mpmf_wrap_impl<T>::type;
|
||||
|
||||
template<class T> struct mpmf_unwrap_impl
|
||||
{
|
||||
using type = typename T::type;
|
||||
};
|
||||
|
||||
template<class... T> struct mpmf_unwrap_impl< mp_identity< mpmf_tuple<T...> > >
|
||||
{
|
||||
using type = std::tuple<T...>;
|
||||
};
|
||||
|
||||
template<class T> using mpmf_unwrap = typename mpmf_unwrap_impl<T>::type;
|
||||
|
||||
#endif // #if !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1930 )
|
||||
|
||||
template<class M, class K> struct mp_map_find_impl;
|
||||
|
||||
template<template<class...> class M, class... T, class K> struct mp_map_find_impl<M<T...>, K>
|
||||
{
|
||||
using U = mp_inherit<mp_identity<T>...>;
|
||||
using U = mp_inherit<mpmf_wrap<T>...>;
|
||||
|
||||
template<template<class...> class L, class... U> static mp_identity<L<K, U...>> f( mp_identity<L<K, U...>>* );
|
||||
static mp_identity<void> f( ... );
|
||||
|
||||
using V = decltype( f((U*)0) );
|
||||
|
||||
using type = typename V::type;
|
||||
using type = mpmf_unwrap< decltype( f((U*)0) ) >;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
41
include/boost/mp11/detail/mp_rename.hpp
Normal file
41
include/boost/mp11/detail/mp_rename.hpp
Normal file
@ -0,0 +1,41 @@
|
||||
#ifndef BOOST_MP11_DETAIL_MP_RENAME_HPP_INCLUDED
|
||||
#define BOOST_MP11_DETAIL_MP_RENAME_HPP_INCLUDED
|
||||
|
||||
// Copyright 2015-2021 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
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
// mp_rename<L, B>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class A, template<class...> class B> struct mp_rename_impl
|
||||
{
|
||||
// An error "no type named 'type'" here means that the first argument to mp_rename is not a list
|
||||
};
|
||||
|
||||
template<template<class...> class A, class... T, template<class...> class B> struct mp_rename_impl<A<T...>, B>
|
||||
{
|
||||
using type = B<T...>;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class A, template<class...> class B> using mp_rename = typename detail::mp_rename_impl<A, B>::type;
|
||||
|
||||
template<template<class...> class F, class L> using mp_apply = typename detail::mp_rename_impl<L, F>::type;
|
||||
|
||||
template<class Q, class L> using mp_apply_q = typename detail::mp_rename_impl<L, Q::template fn>::type;
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_DETAIL_MP_RENAME_HPP_INCLUDED
|
@ -20,10 +20,12 @@
|
||||
# define BOOST_MP11_CONSTEXPR14
|
||||
#endif
|
||||
|
||||
#if defined( _MSC_VER ) && !defined( __clang__ )
|
||||
# define BOOST_MP11_UNREACHABLE() __assume(false)
|
||||
#if defined( __GNUC__ ) || defined( __clang__ )
|
||||
# define BOOST_MP11_UNREACHABLE_DEFAULT default: __builtin_unreachable();
|
||||
#elif defined( _MSC_VER )
|
||||
# define BOOST_MP11_UNREACHABLE_DEFAULT default: __assume(false);
|
||||
#else
|
||||
# define BOOST_MP11_UNREACHABLE() __builtin_unreachable()
|
||||
# define BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
@ -38,27 +40,14 @@ template<std::size_t N> struct mp_with_index_impl_
|
||||
{
|
||||
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
|
||||
{
|
||||
switch( i )
|
||||
if( i < N / 2 )
|
||||
{
|
||||
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
||||
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
||||
case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
|
||||
case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
|
||||
case 7: return std::forward<F>(f)( mp_size_t<K+7>() );
|
||||
case 8: return std::forward<F>(f)( mp_size_t<K+8>() );
|
||||
case 9: return std::forward<F>(f)( mp_size_t<K+9>() );
|
||||
case 10: return std::forward<F>(f)( mp_size_t<K+10>() );
|
||||
case 11: return std::forward<F>(f)( mp_size_t<K+11>() );
|
||||
case 12: return std::forward<F>(f)( mp_size_t<K+12>() );
|
||||
case 13: return std::forward<F>(f)( mp_size_t<K+13>() );
|
||||
case 14: return std::forward<F>(f)( mp_size_t<K+14>() );
|
||||
case 15: return std::forward<F>(f)( mp_size_t<K+15>() );
|
||||
return mp_with_index_impl_<N/2>::template call<K>( i, std::forward<F>(f) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return mp_with_index_impl_<N-N/2>::template call<K+N/2>( i - N/2, std::forward<F>(f) );
|
||||
}
|
||||
|
||||
return mp_with_index_impl_<N-16>::template call<K+16>( i-16, std::forward<F>(f) );
|
||||
}
|
||||
};
|
||||
|
||||
@ -80,7 +69,7 @@ template<> struct mp_with_index_impl_<2>
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
default: BOOST_MP11_UNREACHABLE();
|
||||
BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||
}
|
||||
@ -93,7 +82,7 @@ template<> struct mp_with_index_impl_<3>
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
default: BOOST_MP11_UNREACHABLE();
|
||||
BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||
@ -107,7 +96,7 @@ template<> struct mp_with_index_impl_<4>
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
default: BOOST_MP11_UNREACHABLE();
|
||||
BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||
@ -122,7 +111,7 @@ template<> struct mp_with_index_impl_<5>
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
default: BOOST_MP11_UNREACHABLE();
|
||||
BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||
@ -138,7 +127,7 @@ template<> struct mp_with_index_impl_<6>
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
default: BOOST_MP11_UNREACHABLE();
|
||||
BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||
@ -155,7 +144,7 @@ template<> struct mp_with_index_impl_<7>
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
default: BOOST_MP11_UNREACHABLE();
|
||||
BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||
@ -173,7 +162,7 @@ template<> struct mp_with_index_impl_<8>
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
default: BOOST_MP11_UNREACHABLE();
|
||||
BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||
@ -192,7 +181,7 @@ template<> struct mp_with_index_impl_<9>
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
default: BOOST_MP11_UNREACHABLE();
|
||||
BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||
@ -212,7 +201,7 @@ template<> struct mp_with_index_impl_<10>
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
default: BOOST_MP11_UNREACHABLE();
|
||||
BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||
@ -233,7 +222,7 @@ template<> struct mp_with_index_impl_<11>
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
default: BOOST_MP11_UNREACHABLE();
|
||||
BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||
@ -255,7 +244,7 @@ template<> struct mp_with_index_impl_<12>
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
default: BOOST_MP11_UNREACHABLE();
|
||||
BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||
@ -278,7 +267,7 @@ template<> struct mp_with_index_impl_<13>
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
default: BOOST_MP11_UNREACHABLE();
|
||||
BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||
@ -302,7 +291,7 @@ template<> struct mp_with_index_impl_<14>
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
default: BOOST_MP11_UNREACHABLE();
|
||||
BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||
@ -327,7 +316,7 @@ template<> struct mp_with_index_impl_<15>
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
default: BOOST_MP11_UNREACHABLE();
|
||||
BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||
@ -353,7 +342,7 @@ template<> struct mp_with_index_impl_<16>
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
default: BOOST_MP11_UNREACHABLE();
|
||||
BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||
@ -388,7 +377,7 @@ template<class N, class F> inline BOOST_MP11_CONSTEXPR14 decltype(std::declval<F
|
||||
}
|
||||
|
||||
#undef BOOST_MP11_CONSTEXPR14
|
||||
#undef BOOST_MP11_UNREACHABLE
|
||||
#undef BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
160
include/boost/mp11/detail/mpl_common.hpp
Normal file
160
include/boost/mp11/detail/mpl_common.hpp
Normal file
@ -0,0 +1,160 @@
|
||||
#ifndef BOOST_MP11_DETAIL_MPL_COMMON_HPP_INCLUDED
|
||||
#define BOOST_MP11_DETAIL_MPL_COMMON_HPP_INCLUDED
|
||||
|
||||
// Copyright 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 <boost/mp11/list.hpp>
|
||||
#include <boost/mp11/algorithm.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mpl
|
||||
{
|
||||
|
||||
struct forward_iterator_tag;
|
||||
|
||||
namespace aux
|
||||
{
|
||||
|
||||
struct mp11_tag {};
|
||||
|
||||
template<class L> struct mp11_iterator
|
||||
{
|
||||
using category = forward_iterator_tag;
|
||||
|
||||
using type = mp11::mp_first<L>;
|
||||
using next = mp11_iterator<mp11::mp_rest<L>>;
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
// at
|
||||
|
||||
template< typename Tag > struct at_impl;
|
||||
|
||||
template<> struct at_impl<aux::mp11_tag>
|
||||
{
|
||||
template<class L, class I> struct apply
|
||||
{
|
||||
using type = mp11::mp_at<L, I>;
|
||||
};
|
||||
};
|
||||
|
||||
// back
|
||||
|
||||
template< typename Tag > struct back_impl;
|
||||
|
||||
template<> struct back_impl<aux::mp11_tag>
|
||||
{
|
||||
template<class L> struct apply
|
||||
{
|
||||
using N = mp11::mp_size<L>;
|
||||
using type = mp11::mp_at_c<L, N::value - 1>;
|
||||
};
|
||||
};
|
||||
|
||||
// begin
|
||||
|
||||
template< typename Tag > struct begin_impl;
|
||||
|
||||
template<> struct begin_impl<aux::mp11_tag>
|
||||
{
|
||||
template<class L> struct apply
|
||||
{
|
||||
using type = aux::mp11_iterator<L>;
|
||||
};
|
||||
};
|
||||
|
||||
// clear
|
||||
|
||||
template< typename Tag > struct clear_impl;
|
||||
|
||||
template<> struct clear_impl<aux::mp11_tag>
|
||||
{
|
||||
template<class L> struct apply
|
||||
{
|
||||
using type = mp11::mp_clear<L>;
|
||||
};
|
||||
};
|
||||
|
||||
// end
|
||||
|
||||
template< typename Tag > struct end_impl;
|
||||
|
||||
template<> struct end_impl<aux::mp11_tag>
|
||||
{
|
||||
template<class L> struct apply
|
||||
{
|
||||
using type = aux::mp11_iterator<mp11::mp_clear<L>>;
|
||||
};
|
||||
};
|
||||
|
||||
// front
|
||||
|
||||
template< typename Tag > struct front_impl;
|
||||
|
||||
template<> struct front_impl<aux::mp11_tag>
|
||||
{
|
||||
template<class L> struct apply
|
||||
{
|
||||
using type = mp11::mp_front<L>;
|
||||
};
|
||||
};
|
||||
|
||||
// pop_front
|
||||
|
||||
template< typename Tag > struct pop_front_impl;
|
||||
|
||||
template<> struct pop_front_impl<aux::mp11_tag>
|
||||
{
|
||||
template<class L> struct apply
|
||||
{
|
||||
using type = mp11::mp_pop_front<L>;
|
||||
};
|
||||
};
|
||||
|
||||
// push_back
|
||||
|
||||
template< typename Tag > struct push_back_impl;
|
||||
|
||||
template<> struct push_back_impl<aux::mp11_tag>
|
||||
{
|
||||
template<class L, class T> struct apply
|
||||
{
|
||||
using type = mp11::mp_push_back<L, T>;
|
||||
};
|
||||
};
|
||||
|
||||
// push_front
|
||||
|
||||
template< typename Tag > struct push_front_impl;
|
||||
|
||||
template<> struct push_front_impl<aux::mp11_tag>
|
||||
{
|
||||
template<class L, class T> struct apply
|
||||
{
|
||||
using type = mp11::mp_push_front<L, T>;
|
||||
};
|
||||
};
|
||||
|
||||
// size
|
||||
|
||||
template< typename Tag > struct size_impl;
|
||||
|
||||
template<> struct size_impl<aux::mp11_tag>
|
||||
{
|
||||
template<class L> struct apply
|
||||
{
|
||||
using type = mp11::mp_size<L>;
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace mpl
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_DETAIL_MPL_COMMON_HPP_INCLUDED
|
@ -80,17 +80,14 @@ template<class... T> using mp_and = typename detail::mp_and_impl<mp_list<T...>>:
|
||||
#endif
|
||||
|
||||
// mp_all<T...>
|
||||
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) || BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, < 100000 )
|
||||
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86355
|
||||
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) || BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, != 0 )
|
||||
|
||||
template<class... T> using mp_all = mp_bool< mp_count_if< mp_list<T...>, mp_not >::value == 0 >;
|
||||
|
||||
#elif defined( BOOST_MP11_HAS_FOLD_EXPRESSIONS )
|
||||
|
||||
template<class... T> using mp_all = mp_bool<(static_cast<bool>(T::value) && ...)>;
|
||||
|
||||
#else
|
||||
|
||||
template<class... T> using mp_all = mp_and<mp_to_bool<T>...>;
|
||||
template<class... T> using mp_all = mp_bool< mp_count< mp_list<mp_to_bool<T>...>, mp_false >::value == 0 >;
|
||||
|
||||
#endif
|
||||
|
||||
@ -125,13 +122,14 @@ template<class T1, class... T> struct mp_or_impl<T1, T...>
|
||||
} // namespace detail
|
||||
|
||||
// mp_any<T...>
|
||||
#if defined( BOOST_MP11_HAS_FOLD_EXPRESSIONS ) && !BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, < 100000 ) && !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 )
|
||||
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86356
|
||||
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) || BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, != 0 )
|
||||
|
||||
template<class... T> using mp_any = mp_bool<(static_cast<bool>(T::value) || ...)>;
|
||||
template<class... T> using mp_any = mp_bool< mp_count_if< mp_list<T...>, mp_to_bool >::value != 0 >;
|
||||
|
||||
#else
|
||||
|
||||
template<class... T> using mp_any = mp_bool< mp_count_if< mp_list<T...>, mp_to_bool >::value != 0 >;
|
||||
template<class... T> using mp_any = mp_bool< mp_count< mp_list<mp_to_bool<T>...>, mp_true >::value != 0 >;
|
||||
|
||||
#endif
|
||||
|
||||
@ -148,7 +146,7 @@ template<> struct mp_same_impl<>
|
||||
|
||||
template<class T1, class... T> struct mp_same_impl<T1, T...>
|
||||
{
|
||||
using type = mp_all<std::is_same<T1, T>...>;
|
||||
using type = mp_bool< mp_count<mp_list<T...>, T1>::value == sizeof...(T) >;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
@ -186,6 +184,11 @@ template<template<class...> class L, class... T1, class... T2> struct mp_similar
|
||||
using type = mp_true;
|
||||
};
|
||||
|
||||
template<template<class...> class L, class... T> struct mp_similar_impl<L<T...>, L<T...>>
|
||||
{
|
||||
using type = mp_true;
|
||||
};
|
||||
|
||||
template<class T1, class T2, class T3, class... T> struct mp_similar_impl<T1, T2, T3, T...>
|
||||
{
|
||||
using type = mp_all< typename mp_similar_impl<T1, T2>::type, typename mp_similar_impl<T1, T3>::type, typename mp_similar_impl<T1, T>::type... >;
|
||||
|
@ -12,6 +12,8 @@
|
||||
#include <boost/mp11/detail/mp_list.hpp>
|
||||
#include <boost/mp11/detail/mp_is_list.hpp>
|
||||
#include <boost/mp11/detail/mp_append.hpp>
|
||||
#include <boost/mp11/detail/mp_front.hpp>
|
||||
#include <boost/mp11/detail/mp_rename.hpp>
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
@ -66,23 +68,7 @@ template<class L1, class L2> using mp_assign = typename detail::mp_assign_impl<L
|
||||
template<class L> using mp_clear = mp_assign<L, mp_list<>>;
|
||||
|
||||
// mp_front<L>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L> struct mp_front_impl
|
||||
{
|
||||
// An error "no type named 'type'" here means that the argument to mp_front
|
||||
// is either not a list, or is an empty list
|
||||
};
|
||||
|
||||
template<template<class...> class L, class T1, class... T> struct mp_front_impl<L<T1, T...>>
|
||||
{
|
||||
using type = T1;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L> using mp_front = typename detail::mp_front_impl<L>::type;
|
||||
// in detail/mp_front.hpp
|
||||
|
||||
// mp_pop_front<L>
|
||||
namespace detail
|
||||
@ -184,26 +170,9 @@ template<template<class...> class L, class... U, class... T> struct mp_push_back
|
||||
template<class L, class... T> using mp_push_back = typename detail::mp_push_back_impl<L, T...>::type;
|
||||
|
||||
// mp_rename<L, B>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class A, template<class...> class B> struct mp_rename_impl
|
||||
{
|
||||
// An error "no type named 'type'" here means that the first argument to mp_rename is not a list
|
||||
};
|
||||
|
||||
template<template<class...> class A, class... T, template<class...> class B> struct mp_rename_impl<A<T...>, B>
|
||||
{
|
||||
using type = B<T...>;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class A, template<class...> class B> using mp_rename = typename detail::mp_rename_impl<A, B>::type;
|
||||
|
||||
template<template<class...> class F, class L> using mp_apply = typename detail::mp_rename_impl<L, F>::type;
|
||||
|
||||
template<class Q, class L> using mp_apply_q = typename detail::mp_rename_impl<L, Q::template fn>::type;
|
||||
// mp_apply<F, L>
|
||||
// mp_apply_q<Q, L>
|
||||
// in detail/mp_rename.hpp
|
||||
|
||||
// mp_replace_front<L, T>
|
||||
namespace detail
|
||||
|
@ -1,175 +1,14 @@
|
||||
#ifndef BOOST_MP11_MPL_HPP_INCLUDED
|
||||
#define BOOST_MP11_MPL_HPP_INCLUDED
|
||||
|
||||
// Copyright 2017 Peter Dimov.
|
||||
// Copyright 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 <boost/mp11/list.hpp>
|
||||
#include <boost/mp11/algorithm.hpp>
|
||||
#include <tuple>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mpl
|
||||
{
|
||||
|
||||
struct forward_iterator_tag;
|
||||
|
||||
namespace aux
|
||||
{
|
||||
|
||||
struct mp11_tag {};
|
||||
|
||||
template<class L> struct mp11_iterator
|
||||
{
|
||||
using category = forward_iterator_tag;
|
||||
|
||||
using type = mp11::mp_first<L>;
|
||||
using next = mp11_iterator<mp11::mp_rest<L>>;
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
// at
|
||||
|
||||
template< typename Tag > struct at_impl;
|
||||
|
||||
template<> struct at_impl<aux::mp11_tag>
|
||||
{
|
||||
template<class L, class I> struct apply
|
||||
{
|
||||
using type = mp11::mp_at<L, I>;
|
||||
};
|
||||
};
|
||||
|
||||
// back
|
||||
|
||||
template< typename Tag > struct back_impl;
|
||||
|
||||
template<> struct back_impl<aux::mp11_tag>
|
||||
{
|
||||
template<class L> struct apply
|
||||
{
|
||||
using N = mp11::mp_size<L>;
|
||||
using type = mp11::mp_at_c<L, N::value - 1>;
|
||||
};
|
||||
};
|
||||
|
||||
// begin
|
||||
|
||||
template< typename Tag > struct begin_impl;
|
||||
|
||||
template<> struct begin_impl<aux::mp11_tag>
|
||||
{
|
||||
template<class L> struct apply
|
||||
{
|
||||
using type = aux::mp11_iterator<L>;
|
||||
};
|
||||
};
|
||||
|
||||
// clear
|
||||
|
||||
template< typename Tag > struct clear_impl;
|
||||
|
||||
template<> struct clear_impl<aux::mp11_tag>
|
||||
{
|
||||
template<class L> struct apply
|
||||
{
|
||||
using type = mp11::mp_clear<L>;
|
||||
};
|
||||
};
|
||||
|
||||
// end
|
||||
|
||||
template< typename Tag > struct end_impl;
|
||||
|
||||
template<> struct end_impl<aux::mp11_tag>
|
||||
{
|
||||
template<class L> struct apply
|
||||
{
|
||||
using type = aux::mp11_iterator<mp11::mp_clear<L>>;
|
||||
};
|
||||
};
|
||||
|
||||
// front
|
||||
|
||||
template< typename Tag > struct front_impl;
|
||||
|
||||
template<> struct front_impl<aux::mp11_tag>
|
||||
{
|
||||
template<class L> struct apply
|
||||
{
|
||||
using type = mp11::mp_front<L>;
|
||||
};
|
||||
};
|
||||
|
||||
// pop_front
|
||||
|
||||
template< typename Tag > struct pop_front_impl;
|
||||
|
||||
template<> struct pop_front_impl<aux::mp11_tag>
|
||||
{
|
||||
template<class L> struct apply
|
||||
{
|
||||
using type = mp11::mp_pop_front<L>;
|
||||
};
|
||||
};
|
||||
|
||||
// push_back
|
||||
|
||||
template< typename Tag > struct push_back_impl;
|
||||
|
||||
template<> struct push_back_impl<aux::mp11_tag>
|
||||
{
|
||||
template<class L, class T> struct apply
|
||||
{
|
||||
using type = mp11::mp_push_back<L, T>;
|
||||
};
|
||||
};
|
||||
|
||||
// push_front
|
||||
|
||||
template< typename Tag > struct push_front_impl;
|
||||
|
||||
template<> struct push_front_impl<aux::mp11_tag>
|
||||
{
|
||||
template<class L, class T> struct apply
|
||||
{
|
||||
using type = mp11::mp_push_front<L, T>;
|
||||
};
|
||||
};
|
||||
|
||||
// sequence_tag
|
||||
|
||||
template< typename Sequence > struct sequence_tag;
|
||||
|
||||
template<class... T> struct sequence_tag<mp11::mp_list<T...>>
|
||||
{
|
||||
using type = aux::mp11_tag;
|
||||
};
|
||||
|
||||
template<class... T> struct sequence_tag<std::tuple<T...>>
|
||||
{
|
||||
using type = aux::mp11_tag;
|
||||
};
|
||||
|
||||
// size
|
||||
|
||||
template< typename Tag > struct size_impl;
|
||||
|
||||
template<> struct size_impl<aux::mp11_tag>
|
||||
{
|
||||
template<class L> struct apply
|
||||
{
|
||||
using type = mp11::mp_size<L>;
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace mpl
|
||||
} // namespace boost
|
||||
#include <boost/mp11/mpl_list.hpp>
|
||||
#include <boost/mp11/mpl_tuple.hpp>
|
||||
|
||||
#endif // #ifndef BOOST_MP11_MPL_HPP_INCLUDED
|
||||
|
28
include/boost/mp11/mpl_list.hpp
Normal file
28
include/boost/mp11/mpl_list.hpp
Normal file
@ -0,0 +1,28 @@
|
||||
#ifndef BOOST_MP11_MPL_LIST_HPP_INCLUDED
|
||||
#define BOOST_MP11_MPL_LIST_HPP_INCLUDED
|
||||
|
||||
// Copyright 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 <boost/mp11/detail/mpl_common.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mpl
|
||||
{
|
||||
|
||||
template< typename Sequence > struct sequence_tag;
|
||||
|
||||
template<class... T> struct sequence_tag<mp11::mp_list<T...>>
|
||||
{
|
||||
using type = aux::mp11_tag;
|
||||
};
|
||||
|
||||
} // namespace mpl
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_MPL_LIST_HPP_INCLUDED
|
29
include/boost/mp11/mpl_tuple.hpp
Normal file
29
include/boost/mp11/mpl_tuple.hpp
Normal file
@ -0,0 +1,29 @@
|
||||
#ifndef BOOST_MP11_MPL_TUPLE_HPP_INCLUDED
|
||||
#define BOOST_MP11_MPL_TUPLE_HPP_INCLUDED
|
||||
|
||||
// Copyright 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 <boost/mp11/detail/mpl_common.hpp>
|
||||
#include <tuple>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mpl
|
||||
{
|
||||
|
||||
template< typename Sequence > struct sequence_tag;
|
||||
|
||||
template<class... T> struct sequence_tag<std::tuple<T...>>
|
||||
{
|
||||
using type = aux::mp11_tag;
|
||||
};
|
||||
|
||||
} // namespace mpl
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_MPL_TUPLE_HPP_INCLUDED
|
@ -1,7 +1,7 @@
|
||||
#ifndef BOOST_MP11_TUPLE_HPP_INCLUDED
|
||||
#define BOOST_MP11_TUPLE_HPP_INCLUDED
|
||||
|
||||
// Copyright 2015, 2017 Peter Dimov.
|
||||
// Copyright 2015-2020 Peter Dimov.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
@ -9,6 +9,8 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/integer_sequence.hpp>
|
||||
#include <boost/mp11/list.hpp>
|
||||
#include <boost/mp11/function.hpp>
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
@ -29,10 +31,12 @@ namespace mp11
|
||||
namespace detail
|
||||
{
|
||||
|
||||
using std::get;
|
||||
|
||||
template<class F, class Tp, std::size_t... J> BOOST_MP11_CONSTEXPR auto tuple_apply_impl( F && f, Tp && tp, integer_sequence<std::size_t, J...> )
|
||||
-> decltype( std::forward<F>(f)( std::get<J>(std::forward<Tp>(tp))... ) )
|
||||
-> decltype( std::forward<F>(f)( get<J>(std::forward<Tp>(tp))... ) )
|
||||
{
|
||||
return std::forward<F>(f)( std::get<J>(std::forward<Tp>(tp))... );
|
||||
return std::forward<F>(f)( get<J>(std::forward<Tp>(tp))... );
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
@ -51,7 +55,7 @@ namespace detail
|
||||
|
||||
template<class T, class Tp, std::size_t... J> BOOST_MP11_CONSTEXPR T construct_from_tuple_impl( Tp && tp, integer_sequence<std::size_t, J...> )
|
||||
{
|
||||
return T( std::get<J>(std::forward<Tp>(tp))... );
|
||||
return T( get<J>(std::forward<Tp>(tp))... );
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
@ -70,7 +74,7 @@ namespace detail
|
||||
template<class Tp, std::size_t... J, class F> BOOST_MP11_CONSTEXPR F tuple_for_each_impl( Tp && tp, integer_sequence<std::size_t, J...>, F && f )
|
||||
{
|
||||
using A = int[sizeof...(J)];
|
||||
return (void)A{ ((void)f(std::get<J>(std::forward<Tp>(tp))), 0)... }, std::forward<F>(f);
|
||||
return (void)A{ ((void)f(get<J>(std::forward<Tp>(tp))), 0)... }, std::forward<F>(f);
|
||||
}
|
||||
|
||||
template<class Tp, class F> BOOST_MP11_CONSTEXPR F tuple_for_each_impl( Tp && /*tp*/, integer_sequence<std::size_t>, F && f )
|
||||
@ -86,6 +90,89 @@ template<class Tp, class F> BOOST_MP11_CONSTEXPR F tuple_for_each( Tp && tp, F &
|
||||
return detail::tuple_for_each_impl( std::forward<Tp>(tp), seq(), std::forward<F>(f) );
|
||||
}
|
||||
|
||||
// tuple_transform
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
// std::forward_as_tuple is not constexpr in C++11 or libstdc++ 5.x
|
||||
template<class... T> BOOST_MP11_CONSTEXPR auto tp_forward_r( T&&... t ) -> std::tuple<T&&...>
|
||||
{
|
||||
return std::tuple<T&&...>( std::forward<T>( t )... );
|
||||
}
|
||||
|
||||
template<class... T> BOOST_MP11_CONSTEXPR auto tp_forward_v( T&&... t ) -> std::tuple<T...>
|
||||
{
|
||||
return std::tuple<T...>( std::forward<T>( t )... );
|
||||
}
|
||||
|
||||
template<std::size_t J, class... Tp>
|
||||
BOOST_MP11_CONSTEXPR auto tp_extract( Tp&&... tp )
|
||||
-> decltype( tp_forward_r( get<J>( std::forward<Tp>( tp ) )... ) )
|
||||
{
|
||||
return tp_forward_r( get<J>( std::forward<Tp>( tp ) )... );
|
||||
}
|
||||
|
||||
#if !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1900 )
|
||||
|
||||
template<class F, class... Tp, std::size_t... J>
|
||||
BOOST_MP11_CONSTEXPR auto tuple_transform_impl( integer_sequence<std::size_t, J...>, F const& f, Tp&&... tp )
|
||||
-> decltype( tp_forward_v( tuple_apply( f, tp_extract<J>( std::forward<Tp>(tp)... ) )... ) )
|
||||
{
|
||||
return tp_forward_v( tuple_apply( f, tp_extract<J>( std::forward<Tp>(tp)... ) )... );
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
template<class F, class Tp1, std::size_t... J>
|
||||
BOOST_MP11_CONSTEXPR auto tuple_transform_impl( integer_sequence<std::size_t, J...>, F const& f, Tp1&& tp1 )
|
||||
-> decltype( tp_forward_v( f( get<J>( std::forward<Tp1>(tp1) ) )... ) )
|
||||
{
|
||||
return tp_forward_v( f( get<J>( std::forward<Tp1>(tp1) ) )... );
|
||||
}
|
||||
|
||||
template<class F, class Tp1, class Tp2, std::size_t... J>
|
||||
BOOST_MP11_CONSTEXPR auto tuple_transform_impl( integer_sequence<std::size_t, J...>, F const& f, Tp1&& tp1, Tp2&& tp2 )
|
||||
-> decltype( tp_forward_v( f( get<J>( std::forward<Tp1>(tp1) ), get<J>( std::forward<Tp2>(tp2) ) )... ) )
|
||||
{
|
||||
return tp_forward_v( f( get<J>( std::forward<Tp1>(tp1) ), get<J>( std::forward<Tp2>(tp2) ) )... );
|
||||
}
|
||||
|
||||
template<class F, class Tp1, class Tp2, class Tp3, std::size_t... J>
|
||||
BOOST_MP11_CONSTEXPR auto tuple_transform_impl( integer_sequence<std::size_t, J...>, F const& f, Tp1&& tp1, Tp2&& tp2, Tp3&& tp3 )
|
||||
-> decltype( tp_forward_v( f( get<J>( std::forward<Tp1>(tp1) ), get<J>( std::forward<Tp2>(tp2) ), get<J>( std::forward<Tp3>(tp3) ) )... ) )
|
||||
{
|
||||
return tp_forward_v( f( get<J>( std::forward<Tp1>(tp1) ), get<J>( std::forward<Tp2>(tp2) ), get<J>( std::forward<Tp3>(tp3) ) )... );
|
||||
}
|
||||
|
||||
#endif // !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1900 )
|
||||
|
||||
} // namespace detail
|
||||
|
||||
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1910 )
|
||||
|
||||
template<class F, class Tp1, class... Tp,
|
||||
class Seq = make_index_sequence<std::tuple_size<typename std::remove_reference<Tp1>::type>::value>>
|
||||
BOOST_MP11_CONSTEXPR auto tuple_transform( F const& f, Tp1&& tp1, Tp&&... tp )
|
||||
-> decltype( detail::tuple_transform_impl( Seq(), f, std::forward<Tp1>(tp1), std::forward<Tp>(tp)... ) )
|
||||
{
|
||||
return detail::tuple_transform_impl( Seq(), f, std::forward<Tp1>(tp1), std::forward<Tp>(tp)... );
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
template<class F, class... Tp,
|
||||
class Z = mp_list<mp_size_t<std::tuple_size<typename std::remove_reference<Tp>::type>::value>...>,
|
||||
class E = mp_if<mp_apply<mp_same, Z>, mp_front<Z>>,
|
||||
class Seq = make_index_sequence<E::value>>
|
||||
BOOST_MP11_CONSTEXPR auto tuple_transform( F const& f, Tp&&... tp )
|
||||
-> decltype( detail::tuple_transform_impl( Seq(), f, std::forward<Tp>(tp)... ) )
|
||||
{
|
||||
return detail::tuple_transform_impl( Seq(), f, std::forward<Tp>(tp)... );
|
||||
}
|
||||
|
||||
#endif // BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1910 )
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef BOOST_MP11_UTILITY_HPP_INCLUDED
|
||||
#define BOOST_MP11_UTILITY_HPP_INCLUDED
|
||||
|
||||
// Copyright 2015, 2017, 2019 Peter Dimov.
|
||||
// Copyright 2015-2020 Peter Dimov.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
@ -9,6 +9,10 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/integral.hpp>
|
||||
#include <boost/mp11/detail/mp_list.hpp>
|
||||
#include <boost/mp11/detail/mp_fold.hpp>
|
||||
#include <boost/mp11/detail/mp_front.hpp>
|
||||
#include <boost/mp11/detail/mp_rename.hpp>
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
|
||||
namespace boost
|
||||
@ -157,6 +161,10 @@ template<class C, class T, class Q, class... U> using mp_eval_if_not_q = mp_eval
|
||||
template<class T, template<class...> class F, class... U> using mp_eval_or = mp_eval_if_not<mp_valid<F, U...>, T, F, U...>;
|
||||
template<class T, class Q, class... U> using mp_eval_or_q = mp_eval_or<T, Q::template fn, U...>;
|
||||
|
||||
// mp_valid_and_true
|
||||
template<template<class...> class F, class... T> using mp_valid_and_true = mp_eval_or<mp_false, F, T...>;
|
||||
template<class Q, class... T> using mp_valid_and_true_q = mp_valid_and_true<Q::template fn, T...>;
|
||||
|
||||
// mp_cond
|
||||
|
||||
// so elegant; so doesn't work
|
||||
@ -219,9 +227,6 @@ template<class Q, class... T> using mp_invoke_q = typename Q::template fn<T...>;
|
||||
|
||||
#endif
|
||||
|
||||
// old name for mp_invoke_q retained for compatibility, but deprecated
|
||||
template<class Q, class... T> using mp_invoke BOOST_MP11_DEPRECATED("please use mp_invoke_q") = mp_invoke_q<Q, T...>;
|
||||
|
||||
// mp_not_fn<P>
|
||||
template<template<class...> class P> struct mp_not_fn
|
||||
{
|
||||
@ -230,6 +235,28 @@ template<template<class...> class P> struct mp_not_fn
|
||||
|
||||
template<class Q> using mp_not_fn_q = mp_not_fn<Q::template fn>;
|
||||
|
||||
// mp_compose
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L, class Q> using mp_compose_helper = mp_list< mp_apply_q<Q, L> >;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
#if !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1900 )
|
||||
|
||||
template<template<class...> class... F> struct mp_compose
|
||||
{
|
||||
template<class... T> using fn = mp_front< mp_fold<mp_list<mp_quote<F>...>, mp_list<T...>, detail::mp_compose_helper> >;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
template<class... Q> struct mp_compose_q
|
||||
{
|
||||
template<class... T> using fn = mp_front< mp_fold<mp_list<Q...>, mp_list<T...>, detail::mp_compose_helper> >;
|
||||
};
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
|
@ -11,6 +11,6 @@
|
||||
// Same format as BOOST_VERSION:
|
||||
// major * 100000 + minor * 100 + patch
|
||||
|
||||
#define BOOST_MP11_VERSION 107000
|
||||
#define BOOST_MP11_VERSION 108000
|
||||
|
||||
#endif // #ifndef BOOST_MP11_VERSION_HPP_INCLUDED
|
||||
|
@ -5,10 +5,11 @@
|
||||
"Peter Dimov"
|
||||
],
|
||||
"maintainers": [
|
||||
"Peter Dimov <pdimov -at- pdimov.com>"
|
||||
"Peter Dimov <pdimov -at- gmail.com>"
|
||||
],
|
||||
"description": "A C++11 metaprogramming library.",
|
||||
"category": [
|
||||
"Metaprogramming"
|
||||
]
|
||||
],
|
||||
"cxxstd": "11"
|
||||
}
|
||||
|
@ -2,5 +2,11 @@
|
||||
# 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
|
||||
|
||||
boost_test_jamfile(FILE Jamfile LIBRARIES Boost::mp11 Boost::core)
|
||||
boost_test(SOURCES check_cmake_version.cpp ARGUMENTS ${PROJECT_VERSION} LIBRARIES Boost::core Boost::config)
|
||||
include(BoostTestJamfile OPTIONAL RESULT_VARIABLE HAVE_BOOST_TEST)
|
||||
|
||||
if(HAVE_BOOST_TEST)
|
||||
|
||||
boost_test_jamfile(FILE Jamfile LINK_LIBRARIES Boost::mp11 Boost::core)
|
||||
boost_test(SOURCES check_cmake_version.cpp ARGUMENTS ${PROJECT_VERSION} LINK_LIBRARIES Boost::core Boost::config)
|
||||
|
||||
endif()
|
||||
|
31
test/Jamfile
31
test/Jamfile
@ -14,11 +14,10 @@ project
|
||||
|
||||
[ requires cxx11_variadic_templates cxx11_template_aliases cxx11_decltype cxx11_hdr_tuple ]
|
||||
|
||||
<toolset>msvc:<warnings>all # /W4
|
||||
<warnings>extra
|
||||
|
||||
<toolset>msvc:<warnings-as-errors>on
|
||||
|
||||
<toolset>gcc:<warnings-as-errors>on
|
||||
|
||||
<toolset>clang:<warnings-as-errors>on
|
||||
;
|
||||
|
||||
@ -69,7 +68,7 @@ run mp_product.cpp ;
|
||||
run mp_drop.cpp ;
|
||||
run mp_iota.cpp ;
|
||||
run mp_at.cpp ;
|
||||
run mp_at_sf.cpp ;
|
||||
run mp_at_sf.cpp : : : <toolset>gcc-4.7:<warnings>all ;
|
||||
run mp_take.cpp ;
|
||||
run mp_replace.cpp ;
|
||||
run mp_replace_if.cpp ;
|
||||
@ -92,6 +91,8 @@ run mp_fold_q.cpp ;
|
||||
run mp_reverse_fold.cpp ;
|
||||
run mp_reverse_fold_q.cpp ;
|
||||
run mp_unique.cpp ;
|
||||
run mp_unique_if.cpp ;
|
||||
run mp_unique_if_q.cpp ;
|
||||
run mp_all_of.cpp ;
|
||||
run mp_all_of_q.cpp ;
|
||||
run mp_any_of.cpp ;
|
||||
@ -114,6 +115,17 @@ run mp_nth_element.cpp ;
|
||||
run mp_nth_element_q.cpp ;
|
||||
run mp_back.cpp ;
|
||||
run mp_pop_back.cpp ;
|
||||
run mp_flatten.cpp ;
|
||||
run mp_rotate_left.cpp ;
|
||||
run mp_rotate_right.cpp ;
|
||||
run mp_power_set.cpp ;
|
||||
run mp_partial_sum.cpp ;
|
||||
run mp_iterate.cpp ;
|
||||
run mp_pairwise_fold.cpp ;
|
||||
run mp_pairwise_fold_q.cpp ;
|
||||
run mp_intersperse.cpp ;
|
||||
run mp_split.cpp ;
|
||||
run mp_join.cpp ;
|
||||
|
||||
# integral
|
||||
run integral.cpp ;
|
||||
@ -136,6 +148,8 @@ run mp_cond_sf.cpp ;
|
||||
run mp_not_fn.cpp ;
|
||||
run mp_eval_if_not.cpp ;
|
||||
run mp_eval_or.cpp ;
|
||||
run mp_compose.cpp ;
|
||||
run mp_valid_and_true.cpp ;
|
||||
|
||||
# integer_sequence
|
||||
run integer_sequence.cpp ;
|
||||
@ -147,6 +161,9 @@ run tuple_apply.cpp ;
|
||||
compile tuple_apply_cx.cpp ;
|
||||
run construct_from_tuple.cpp ;
|
||||
compile construct_from_tuple_cx.cpp ;
|
||||
run tuple_transform.cpp ;
|
||||
run tuple_transform_2.cpp ;
|
||||
compile tuple_transform_cx.cpp ;
|
||||
|
||||
# set
|
||||
run mp_set_contains.cpp ;
|
||||
@ -162,8 +179,10 @@ run mp_set_intersection_sf.cpp ;
|
||||
|
||||
# function
|
||||
run mp_all.cpp ;
|
||||
run mp_all_2.cpp ;
|
||||
run mp_and.cpp ;
|
||||
run mp_any.cpp ;
|
||||
run mp_any_2.cpp ;
|
||||
run mp_or.cpp ;
|
||||
run mp_same.cpp ;
|
||||
run mp_plus.cpp ;
|
||||
@ -174,6 +193,8 @@ run mp_similar.cpp ;
|
||||
|
||||
# map
|
||||
run mp_map_find.cpp ;
|
||||
run mp_map_find_2.cpp ;
|
||||
run mp_map_find_3.cpp ;
|
||||
run mp_map_contains.cpp ;
|
||||
run mp_map_insert.cpp ;
|
||||
run mp_map_replace.cpp ;
|
||||
@ -191,6 +212,8 @@ run mp_bind_back.cpp ;
|
||||
|
||||
# mpl
|
||||
run mpl.cpp : ;
|
||||
run mpl_list.cpp : ;
|
||||
run mpl_tuple.cpp : ;
|
||||
|
||||
# version
|
||||
run version.cpp ;
|
||||
|
@ -2,11 +2,11 @@
|
||||
# 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
|
||||
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
cmake_minimum_required(VERSION 3.5...3.16)
|
||||
|
||||
project(cmake_install_test LANGUAGES CXX)
|
||||
|
||||
find_package(BoostMp11 REQUIRED)
|
||||
find_package(boost_mp11 REQUIRED)
|
||||
|
||||
add_executable(main main.cpp)
|
||||
target_link_libraries(main Boost::mp11)
|
||||
|
@ -1,3 +1,7 @@
|
||||
// Copyright 2018 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11.hpp>
|
||||
using namespace boost::mp11;
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
# 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
|
||||
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
cmake_minimum_required(VERSION 3.5...3.16)
|
||||
|
||||
project(cmake_subdir_test LANGUAGES CXX)
|
||||
|
||||
|
@ -1,3 +1,7 @@
|
||||
// Copyright 2018 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11.hpp>
|
||||
using namespace boost::mp11;
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
// Technically std::tuple isn't constexpr enabled in C++11, but it works with libstdc++
|
||||
|
||||
#if defined( BOOST_MP11_NO_CONSTEXPR ) || ( !defined( __GLIBCXX__ ) && __cplusplus < 201400L )
|
||||
#if defined( BOOST_MP11_NO_CONSTEXPR ) || ( !defined(_MSC_VER) && !defined( __GLIBCXX__ ) && __cplusplus < 201400L )
|
||||
|
||||
int main() {}
|
||||
|
||||
|
42
test/mp_all_2.cpp
Normal file
42
test/mp_all_2.cpp
Normal file
@ -0,0 +1,42 @@
|
||||
// Copyright 2021 Peter Dimov.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
|
||||
#if BOOST_MP11_MSVC
|
||||
# pragma warning( disable: 4503 ) // decorated name length exceeded
|
||||
#endif
|
||||
|
||||
#include <boost/mp11/function.hpp>
|
||||
#include <boost/mp11/integral.hpp>
|
||||
#include <boost/mp11/algorithm.hpp>
|
||||
#include <boost/core/lightweight_test_trait.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
int main()
|
||||
{
|
||||
using boost::mp11::mp_all;
|
||||
|
||||
using boost::mp11::mp_list;
|
||||
using boost::mp11::mp_apply;
|
||||
using boost::mp11::mp_true;
|
||||
using boost::mp11::mp_false;
|
||||
|
||||
using boost::mp11::mp_repeat_c;
|
||||
using boost::mp11::mp_push_back;
|
||||
|
||||
int const N = 1089;
|
||||
|
||||
using L1 = mp_repeat_c<mp_list<mp_true>, N>;
|
||||
using R1 = mp_apply<mp_all, L1>;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<R1, mp_true>));
|
||||
|
||||
using L2 = mp_push_back<L1, mp_false>;
|
||||
using R2 = mp_apply<mp_all, L2>;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<R2, mp_false>));
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
@ -6,6 +6,11 @@
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
|
||||
#if BOOST_MP11_MSVC
|
||||
# pragma warning( disable: 4503 ) // decorated name length exceeded
|
||||
#endif
|
||||
|
||||
#include <boost/mp11/algorithm.hpp>
|
||||
#include <boost/mp11/list.hpp>
|
||||
@ -53,5 +58,23 @@ int main()
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_all_of<L2, std::is_const>, mp_true>));
|
||||
}
|
||||
|
||||
{
|
||||
using boost::mp11::mp_repeat_c;
|
||||
using boost::mp11::mp_to_bool;
|
||||
using boost::mp11::mp_push_back;
|
||||
|
||||
int const N = 1089;
|
||||
|
||||
using L1 = mp_repeat_c<mp_list<mp_true>, N>;
|
||||
using R1 = mp_all_of<L1, mp_to_bool>;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<R1, mp_true>));
|
||||
|
||||
using L2 = mp_push_back<L1, mp_false>;
|
||||
using R2 = mp_all_of<L2, mp_to_bool>;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<R2, mp_false>));
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
42
test/mp_any_2.cpp
Normal file
42
test/mp_any_2.cpp
Normal file
@ -0,0 +1,42 @@
|
||||
// Copyright 2021 Peter Dimov.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
|
||||
#if BOOST_MP11_MSVC
|
||||
# pragma warning( disable: 4503 ) // decorated name length exceeded
|
||||
#endif
|
||||
|
||||
#include <boost/mp11/function.hpp>
|
||||
#include <boost/mp11/integral.hpp>
|
||||
#include <boost/mp11/algorithm.hpp>
|
||||
#include <boost/core/lightweight_test_trait.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
int main()
|
||||
{
|
||||
using boost::mp11::mp_any;
|
||||
|
||||
using boost::mp11::mp_list;
|
||||
using boost::mp11::mp_apply;
|
||||
using boost::mp11::mp_true;
|
||||
using boost::mp11::mp_false;
|
||||
|
||||
using boost::mp11::mp_repeat_c;
|
||||
using boost::mp11::mp_push_back;
|
||||
|
||||
int const N = 1089;
|
||||
|
||||
using L1 = mp_repeat_c<mp_list<mp_false>, N>;
|
||||
using R1 = mp_apply<mp_any, L1>;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<R1, mp_false>));
|
||||
|
||||
using L2 = mp_push_back<L1, mp_true>;
|
||||
using R2 = mp_apply<mp_any, L2>;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<R2, mp_true>));
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
@ -6,6 +6,11 @@
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
|
||||
#if BOOST_MP11_MSVC
|
||||
# pragma warning( disable: 4503 ) // decorated name length exceeded
|
||||
#endif
|
||||
|
||||
#include <boost/mp11/algorithm.hpp>
|
||||
#include <boost/mp11/list.hpp>
|
||||
@ -68,5 +73,23 @@ int main()
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_any_of<L3, std::is_const>, mp_true>));
|
||||
}
|
||||
|
||||
{
|
||||
using boost::mp11::mp_repeat_c;
|
||||
using boost::mp11::mp_to_bool;
|
||||
using boost::mp11::mp_push_back;
|
||||
|
||||
int const N = 1089;
|
||||
|
||||
using L1 = mp_repeat_c<mp_list<mp_false>, N>;
|
||||
using R1 = mp_any_of<L1, mp_to_bool>;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<R1, mp_false>));
|
||||
|
||||
using L2 = mp_push_back<L1, mp_true>;
|
||||
using R2 = mp_any_of<L2, mp_to_bool>;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<R2, mp_true>));
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
70
test/mp_compose.cpp
Normal file
70
test/mp_compose.cpp
Normal file
@ -0,0 +1,70 @@
|
||||
|
||||
// Copyright 2017, 2020 Peter Dimov.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/utility.hpp>
|
||||
#include <boost/core/lightweight_test_trait.hpp>
|
||||
|
||||
template<class T> struct F1 {};
|
||||
template<class T> struct F2 {};
|
||||
template<class T> struct F3 {};
|
||||
|
||||
template<class T> using G1 = F1<T>;
|
||||
template<class T> using G2 = F2<T>;
|
||||
template<class T> using G3 = F3<T>;
|
||||
|
||||
template<class... T> struct H {};
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost::mp11;
|
||||
|
||||
#if !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1900 )
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_compose<>::fn<void>, void>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_compose<F1>::fn<void>, F1<void>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_compose<G1>::fn<void>, F1<void>>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_compose<F1, F2>::fn<void>, F2<F1<void>>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_compose<G1, G2>::fn<void>, F2<F1<void>>>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_compose<F1, F2, F3>::fn<void>, F3<F2<F1<void>>>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_compose<G1, G2, G3>::fn<void>, F3<F2<F1<void>>>>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_compose<H>::fn<int, char>, H<int, char>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_compose<H, F1>::fn<void, float>, F1<H<void, float>>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_compose<H, F1, G1>::fn<void, float>, G1<F1<H<void, float>>>>));
|
||||
|
||||
#endif
|
||||
|
||||
using QF1 = mp_quote<F1>;
|
||||
using QF2 = mp_quote<F2>;
|
||||
using QF3 = mp_quote<F3>;
|
||||
|
||||
using QG1 = mp_quote<G1>;
|
||||
using QG2 = mp_quote<G2>;
|
||||
using QG3 = mp_quote<G3>;
|
||||
|
||||
using QH = mp_quote<H>;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_compose_q<>::fn<void>, void>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_compose_q<QF1>::fn<void>, F1<void>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_compose_q<QG1>::fn<void>, F1<void>>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_compose_q<QF1, QF2>::fn<void>, F2<F1<void>>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_compose_q<QG1, QG2>::fn<void>, F2<F1<void>>>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_compose_q<QF1, QF2, QF3>::fn<void>, F3<F2<F1<void>>>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_compose_q<QG1, QG2, QG3>::fn<void>, F3<F2<F1<void>>>>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_compose_q<QH>::fn<int, char>, H<int, char>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_compose_q<QH, QF1>::fn<void, float>, F1<H<void, float>>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_compose_q<QH, QF1, QG1>::fn<void, float>, G1<F1<H<void, float>>>>));
|
||||
|
||||
//
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
@ -7,6 +7,12 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
|
||||
#if BOOST_MP11_MSVC
|
||||
# pragma warning( disable: 4503 ) // decorated name length exceeded
|
||||
#endif
|
||||
|
||||
#include <boost/mp11/algorithm.hpp>
|
||||
#include <boost/mp11/list.hpp>
|
||||
#include <boost/mp11/integral.hpp>
|
||||
@ -59,5 +65,16 @@ int main()
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_count<L5, X2>, mp_size_t<1>>));
|
||||
}
|
||||
|
||||
{
|
||||
using boost::mp11::mp_repeat_c;
|
||||
|
||||
int const N = 1089;
|
||||
|
||||
using L = mp_repeat_c<mp_list<void>, N>;
|
||||
using R = mp_count<L, void>;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<R, mp_size_t<N>>));
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
@ -6,6 +6,11 @@
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
|
||||
#if BOOST_MP11_MSVC
|
||||
# pragma warning( disable: 4503 ) // decorated name length exceeded
|
||||
#endif
|
||||
|
||||
#include <boost/mp11/algorithm.hpp>
|
||||
#include <boost/mp11/list.hpp>
|
||||
@ -17,6 +22,10 @@
|
||||
|
||||
struct X1 {};
|
||||
|
||||
using boost::mp11::mp_bool;
|
||||
|
||||
template<class T> using is_even = mp_bool< T::value % 2 == 0 >;
|
||||
|
||||
int main()
|
||||
{
|
||||
using boost::mp11::mp_list;
|
||||
@ -55,5 +64,16 @@ int main()
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_count_if<L2, std::is_pointer>, mp_size_t<1>>));
|
||||
}
|
||||
|
||||
{
|
||||
using boost::mp11::mp_iota_c;
|
||||
|
||||
int const N = 1089;
|
||||
|
||||
using L = mp_iota_c<N>;
|
||||
using R = mp_count_if<L, is_even>;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<R, mp_size_t<(N + 1) / 2>>));
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
101
test/mp_flatten.cpp
Normal file
101
test/mp_flatten.cpp
Normal file
@ -0,0 +1,101 @@
|
||||
|
||||
// Copyright 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 <boost/mp11/algorithm.hpp>
|
||||
#include <boost/mp11/list.hpp>
|
||||
#include <boost/core/lightweight_test_trait.hpp>
|
||||
#include <type_traits>
|
||||
#include <tuple>
|
||||
|
||||
int main()
|
||||
{
|
||||
using boost::mp11::mp_list;
|
||||
using boost::mp11::mp_flatten;
|
||||
using boost::mp11::mp_transform;
|
||||
|
||||
{
|
||||
using L1 = mp_list<>;
|
||||
using L2 = mp_list<void>;
|
||||
using L3 = mp_list<void, void>;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_flatten<L1>, L1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_flatten<L2>, L2>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_flatten<L3>, L3>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_flatten<L1, L1>, L1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_flatten<L2, L2>, L2>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_flatten<L3, L3>, L3>));
|
||||
|
||||
using L4 = mp_transform<mp_list, L3>;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_flatten<L4>, L3>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_flatten<L4, mp_list<>>, L3>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_flatten<L4, std::tuple<>>, L4>));
|
||||
|
||||
using L5 = mp_transform<std::tuple, L3>;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_flatten<L5>, L5>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_flatten<L5, mp_list<>>, L5>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_flatten<L5, std::tuple<>>, L3>));
|
||||
}
|
||||
|
||||
{
|
||||
using L1 = std::tuple<>;
|
||||
using L2 = std::tuple<void>;
|
||||
using L3 = std::tuple<void, void>;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_flatten<L1>, L1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_flatten<L2>, L2>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_flatten<L3>, L3>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_flatten<L1, L1>, L1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_flatten<L2, L2>, L2>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_flatten<L3, L3>, L3>));
|
||||
|
||||
using L4 = mp_transform<mp_list, L3>;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_flatten<L4>, L4>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_flatten<L4, mp_list<>>, L3>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_flatten<L4, std::tuple<>>, L4>));
|
||||
|
||||
using L5 = mp_transform<std::tuple, L3>;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_flatten<L5>, L3>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_flatten<L5, mp_list<>>, L5>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_flatten<L5, std::tuple<>>, L3>));
|
||||
}
|
||||
|
||||
{
|
||||
using L1 = mp_list<std::tuple<>, int, mp_list<>, void, mp_list<char, double>, std::pair<int, void>>;
|
||||
|
||||
using R1 = mp_flatten<L1>;
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<R1, mp_list<std::tuple<>, int, void, char, double, std::pair<int, void>>>));
|
||||
|
||||
using R2 = mp_flatten<L1, std::pair<void, void>>;
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<R2, mp_list<std::tuple<>, int, mp_list<>, void, mp_list<char, double>, int, void>>));
|
||||
|
||||
using R3 = mp_flatten<L1, std::tuple<>>;
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<R3, mp_list<int, mp_list<>, void, mp_list<char, double>, std::pair<int, void>>>));
|
||||
}
|
||||
|
||||
{
|
||||
using L1 = std::tuple<std::tuple<>, int, mp_list<>, void, mp_list<char, double>, std::pair<int, void>>;
|
||||
|
||||
using R1 = mp_flatten<L1, mp_list<void, void, void, void>>;
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<R1, std::tuple<std::tuple<>, int, void, char, double, std::pair<int, void>>>));
|
||||
|
||||
using R2 = mp_flatten<L1, std::pair<void, void>>;
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<R2, std::tuple<std::tuple<>, int, mp_list<>, void, mp_list<char, double>, int, void>>));
|
||||
|
||||
using R3 = mp_flatten<L1>;
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<R3, std::tuple<int, mp_list<>, void, mp_list<char, double>, std::pair<int, void>>>));
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
|
||||
// Copyright 2017 Peter Dimov.
|
||||
// Copyright 2017 Peter Dimov.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
@ -10,6 +10,9 @@
|
||||
|
||||
#if BOOST_MP11_MSVC
|
||||
# pragma warning( disable: 4503 ) // decorated name length exceeded
|
||||
# pragma warning( disable: 4307 ) // '*': integral constant overflow
|
||||
# pragma warning( disable: 4244 ) // conversion from size_t to uint32_t
|
||||
# pragma warning( disable: 4267 ) // conversion from size_t to uint32_t
|
||||
#endif
|
||||
|
||||
#include <boost/mp11/algorithm.hpp>
|
||||
@ -73,7 +76,7 @@ int main()
|
||||
|
||||
#endif
|
||||
|
||||
#if defined( BOOST_MP11_NO_CONSTEXPR ) || ( !defined( __GLIBCXX__ ) && __cplusplus < 201400L )
|
||||
#if defined( BOOST_MP11_NO_CONSTEXPR ) || ( !defined(_MSC_VER) && !defined( __GLIBCXX__ ) && __cplusplus < 201400L )
|
||||
#else
|
||||
|
||||
static_assert( mp_for_each<mp_list<>>( 11 ) == 11, "mp_for_each<mp_list<>>( 11 ) == 11" );
|
||||
|
38
test/mp_intersperse.cpp
Normal file
38
test/mp_intersperse.cpp
Normal file
@ -0,0 +1,38 @@
|
||||
// Copyright 2021 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/algorithm.hpp>
|
||||
#include <boost/mp11/list.hpp>
|
||||
#include <boost/core/lightweight_test_trait.hpp>
|
||||
#include <type_traits>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
struct X1 {};
|
||||
struct X2 {};
|
||||
struct X3 {};
|
||||
struct X4 {};
|
||||
struct X5 {};
|
||||
|
||||
int main()
|
||||
{
|
||||
using boost::mp11::mp_list;
|
||||
using boost::mp11::mp_intersperse;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_intersperse<mp_list<>, void>, mp_list<>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_intersperse<mp_list<X1>, void>, mp_list<X1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_intersperse<mp_list<X1, X2>, void>, mp_list<X1, void, X2>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_intersperse<mp_list<X1, X2, X3>, void>, mp_list<X1, void, X2, void, X3>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_intersperse<mp_list<X1, X2, X3, X4>, void>, mp_list<X1, void, X2, void, X3, void, X4>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_intersperse<mp_list<X1, X2, X3, X4, X5>, void>, mp_list<X1, void, X2, void, X3, void, X4, void, X5>>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_intersperse<std::tuple<>, void>, std::tuple<>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_intersperse<std::tuple<X1>, void>, std::tuple<X1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_intersperse<std::tuple<X1, X2>, void>, std::tuple<X1, void, X2>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_intersperse<std::tuple<X1, X2, X3>, void>, std::tuple<X1, void, X2, void, X3>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_intersperse<std::tuple<X1, X2, X3, X4>, void>, std::tuple<X1, void, X2, void, X3, void, X4>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_intersperse<std::tuple<X1, X2, X3, X4, X5>, void>, std::tuple<X1, void, X2, void, X3, void, X4, void, X5>>));
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
68
test/mp_iterate.cpp
Normal file
68
test/mp_iterate.cpp
Normal file
@ -0,0 +1,68 @@
|
||||
// Copyright 2020 Peter Dimov.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/algorithm.hpp>
|
||||
#include <boost/mp11/list.hpp>
|
||||
#include <boost/core/lightweight_test_trait.hpp>
|
||||
#include <type_traits>
|
||||
#include <tuple>
|
||||
#include <cstddef>
|
||||
|
||||
struct X1 {};
|
||||
struct X2 { using first_type = double; using next_type = X1; };
|
||||
struct X3 { using first_type = float; using next_type = X2; };
|
||||
struct X4 { using first_type = int; using next_type = X3; };
|
||||
|
||||
template<class T> using first_type = typename T::first_type;
|
||||
template<class T> using next_type = typename T::next_type;
|
||||
|
||||
template<class T1, class T2> struct cons {};
|
||||
|
||||
template<class T1, class T2> struct cons2
|
||||
{
|
||||
using first_type = T1;
|
||||
using next_type = T2;
|
||||
};
|
||||
|
||||
using boost::mp11::mp_reverse_fold;
|
||||
using boost::mp11::mp_iterate;
|
||||
using boost::mp11::mp_first;
|
||||
using boost::mp11::mp_second;
|
||||
using boost::mp11::mp_rest;
|
||||
|
||||
template<class L1> void test()
|
||||
{
|
||||
using R1 = mp_iterate<L1, mp_first, mp_rest>;
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<L1, R1>));
|
||||
|
||||
using V2 = mp_reverse_fold<L1, void, cons>;
|
||||
using R2 = mp_iterate<V2, mp_first, mp_second>;
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<L1, R2>));
|
||||
|
||||
#if !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1900 )
|
||||
|
||||
using V3 = mp_reverse_fold<L1, void, cons2>;
|
||||
using R3 = mp_iterate<V3, first_type, next_type>;
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<L1, R3>));
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
using boost::mp11::mp_list;
|
||||
|
||||
test< mp_list<> >();
|
||||
test< mp_list<int> >();
|
||||
test< mp_list<int, void> >();
|
||||
test< mp_list<int, void, float> >();
|
||||
test< mp_list<int, void, float, double> >();
|
||||
|
||||
using boost::mp11::mp_identity_t;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_iterate<X4, mp_identity_t, next_type>, mp_list<X4, X3, X2, X1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_iterate<X4, first_type, next_type>, mp_list<int, float, double>>));
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
51
test/mp_join.cpp
Normal file
51
test/mp_join.cpp
Normal file
@ -0,0 +1,51 @@
|
||||
// Copyright 2021 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/algorithm.hpp>
|
||||
#include <boost/mp11/list.hpp>
|
||||
#include <boost/core/lightweight_test_trait.hpp>
|
||||
#include <type_traits>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
struct X1 {};
|
||||
struct X2 {};
|
||||
struct X3 {};
|
||||
struct X4 {};
|
||||
|
||||
struct S {};
|
||||
|
||||
int main()
|
||||
{
|
||||
using boost::mp11::mp_list;
|
||||
using boost::mp11::mp_join;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_join<mp_list<mp_list<>>, S>, mp_list<>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_join<mp_list<mp_list<X1>>, S>, mp_list<X1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_join<mp_list<mp_list<X1, X2>>, S>, mp_list<X1, X2>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_join<mp_list<mp_list<X1, X2, X3>>, S>, mp_list<X1, X2, X3>>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_join<mp_list<mp_list<>, mp_list<>>, S>, mp_list<S>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_join<mp_list<mp_list<>, mp_list<>, mp_list<>>, S>, mp_list<S, S>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_join<mp_list<mp_list<>, mp_list<>, mp_list<>, mp_list<>>, S>, mp_list<S, S, S>>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_join<mp_list<mp_list<X1>, mp_list<X2>>, S>, mp_list<X1, S, X2>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_join<mp_list<mp_list<X1, X2>, mp_list<X3, X4>>, S>, mp_list<X1, X2, S, X3, X4>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_join<mp_list<mp_list<>, mp_list<X1, X2>, mp_list<>, mp_list<X3, X4>, mp_list<>>, S>, mp_list<S, X1, X2, S, S, X3, X4, S>>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_join<std::tuple<std::tuple<>>, S>, std::tuple<>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_join<std::tuple<std::tuple<X1>>, S>, std::tuple<X1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_join<std::tuple<std::tuple<X1, X2>>, S>, std::tuple<X1, X2>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_join<std::tuple<std::tuple<X1, X2, X3>>, S>, std::tuple<X1, X2, X3>>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_join<std::tuple<std::tuple<>, std::tuple<>>, S>, std::tuple<S>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_join<std::tuple<std::tuple<>, std::tuple<>, std::tuple<>>, S>, std::tuple<S, S>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_join<std::tuple<std::tuple<>, std::tuple<>, std::tuple<>, std::tuple<>>, S>, std::tuple<S, S, S>>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_join<std::tuple<std::tuple<X1>, std::tuple<X2>>, S>, std::tuple<X1, S, X2>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_join<std::tuple<std::tuple<X1, X2>, std::tuple<X3, X4>>, S>, std::tuple<X1, X2, S, X3, X4>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_join<std::tuple<std::tuple<>, std::tuple<X1, X2>, std::tuple<>, std::tuple<X3, X4>, std::tuple<>>, S>, std::tuple<S, X1, X2, S, S, X3, X4, S>>));
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
33
test/mp_map_find_2.cpp
Normal file
33
test/mp_map_find_2.cpp
Normal file
@ -0,0 +1,33 @@
|
||||
|
||||
// Copyright 2016, 2020 Peter Dimov.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
|
||||
#include <boost/mp11/map.hpp>
|
||||
#include <boost/core/lightweight_test_trait.hpp>
|
||||
#include <tuple>
|
||||
|
||||
struct X {};
|
||||
struct Y {};
|
||||
|
||||
int main()
|
||||
{
|
||||
using boost::mp11::mp_map_find;
|
||||
|
||||
using L1 = std::tuple<std::tuple<int, int>, std::tuple<long, long>, std::tuple<bool, X>, std::tuple<X, bool>>;
|
||||
|
||||
BOOST_TEST_TRAIT_SAME( mp_map_find<L1, int>, std::tuple<int, int> );
|
||||
BOOST_TEST_TRAIT_SAME( mp_map_find<L1, bool>, std::tuple<bool, X> );
|
||||
BOOST_TEST_TRAIT_SAME( mp_map_find<L1, X>, std::tuple<X, bool> );
|
||||
|
||||
using L2 = std::tuple<std::tuple<X, Y>, std::tuple<Y, X>>;
|
||||
|
||||
BOOST_TEST_TRAIT_SAME( mp_map_find<L2, X>, std::tuple<X, Y> );
|
||||
BOOST_TEST_TRAIT_SAME( mp_map_find<L2, Y>, std::tuple<Y, X> );
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
34
test/mp_map_find_3.cpp
Normal file
34
test/mp_map_find_3.cpp
Normal file
@ -0,0 +1,34 @@
|
||||
|
||||
// Copyright 2016, 2020 Peter Dimov.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
// Same as mp_map_find_2.cpp, but with includes reversed
|
||||
|
||||
#include <tuple>
|
||||
#include <boost/mp11/map.hpp>
|
||||
#include <boost/core/lightweight_test_trait.hpp>
|
||||
|
||||
struct X {};
|
||||
struct Y {};
|
||||
|
||||
int main()
|
||||
{
|
||||
using boost::mp11::mp_map_find;
|
||||
|
||||
using L1 = std::tuple<std::tuple<int, int>, std::tuple<long, long>, std::tuple<bool, X>, std::tuple<X, bool>>;
|
||||
|
||||
BOOST_TEST_TRAIT_SAME( mp_map_find<L1, int>, std::tuple<int, int> );
|
||||
BOOST_TEST_TRAIT_SAME( mp_map_find<L1, bool>, std::tuple<bool, X> );
|
||||
BOOST_TEST_TRAIT_SAME( mp_map_find<L1, X>, std::tuple<X, bool> );
|
||||
|
||||
using L2 = std::tuple<std::tuple<X, Y>, std::tuple<Y, X>>;
|
||||
|
||||
BOOST_TEST_TRAIT_SAME( mp_map_find<L2, X>, std::tuple<X, Y> );
|
||||
BOOST_TEST_TRAIT_SAME( mp_map_find<L2, Y>, std::tuple<Y, X> );
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
@ -6,6 +6,11 @@
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
|
||||
#if BOOST_MP11_MSVC
|
||||
# pragma warning( disable: 4503 ) // decorated name length exceeded
|
||||
#endif
|
||||
|
||||
#include <boost/mp11/algorithm.hpp>
|
||||
#include <boost/mp11/list.hpp>
|
||||
@ -68,5 +73,23 @@ int main()
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_none_of<L3, std::is_const>, mp_false>));
|
||||
}
|
||||
|
||||
{
|
||||
using boost::mp11::mp_repeat_c;
|
||||
using boost::mp11::mp_to_bool;
|
||||
using boost::mp11::mp_push_back;
|
||||
|
||||
int const N = 1089;
|
||||
|
||||
using L1 = mp_repeat_c<mp_list<mp_false>, N>;
|
||||
using R1 = mp_none_of<L1, mp_to_bool>;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<R1, mp_true>));
|
||||
|
||||
using L2 = mp_push_back<L1, mp_true>;
|
||||
using R2 = mp_none_of<L2, mp_to_bool>;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<R2, mp_false>));
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
49
test/mp_pairwise_fold.cpp
Normal file
49
test/mp_pairwise_fold.cpp
Normal file
@ -0,0 +1,49 @@
|
||||
// Copyright 2020 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/algorithm.hpp>
|
||||
#include <boost/mp11/list.hpp>
|
||||
#include <boost/core/lightweight_test_trait.hpp>
|
||||
#include <type_traits>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
struct X1 {};
|
||||
struct X2 {};
|
||||
struct X3 {};
|
||||
struct X4 {};
|
||||
|
||||
template<class T, class U> using is_same = typename std::is_same<T, U>::type;
|
||||
|
||||
int main()
|
||||
{
|
||||
using boost::mp11::mp_list;
|
||||
using boost::mp11::mp_pairwise_fold;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_pairwise_fold<mp_list<>, mp_list>, mp_list<>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_pairwise_fold<mp_list<X1>, mp_list>, mp_list<>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_pairwise_fold<mp_list<X1, X2>, mp_list>, mp_list<mp_list<X1, X2>>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_pairwise_fold<mp_list<X1, X2, X3>, mp_list>, mp_list<mp_list<X1, X2>, mp_list<X2, X3>>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_pairwise_fold<mp_list<X1, X2, X3, X4>, mp_list>, mp_list<mp_list<X1, X2>, mp_list<X2, X3>, mp_list<X3, X4>>>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_pairwise_fold<mp_list<>, std::pair>, mp_list<>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_pairwise_fold<mp_list<X1>, std::pair>, mp_list<>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_pairwise_fold<mp_list<X1, X2>, std::pair>, mp_list<std::pair<X1, X2>>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_pairwise_fold<mp_list<X1, X2, X3>, std::pair>, mp_list<std::pair<X1, X2>, std::pair<X2, X3>>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_pairwise_fold<mp_list<X1, X2, X3, X4>, std::pair>, mp_list<std::pair<X1, X2>, std::pair<X2, X3>, std::pair<X3, X4>>>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_pairwise_fold<std::tuple<>, std::pair>, std::tuple<>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_pairwise_fold<std::tuple<X1>, std::pair>, std::tuple<>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_pairwise_fold<std::tuple<X1, X2>, std::pair>, std::tuple<std::pair<X1, X2>>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_pairwise_fold<std::tuple<X1, X2, X3>, std::pair>, std::tuple<std::pair<X1, X2>, std::pair<X2, X3>>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_pairwise_fold<std::tuple<X1, X2, X3, X4>, std::pair>, std::tuple<std::pair<X1, X2>, std::pair<X2, X3>, std::pair<X3, X4>>>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_pairwise_fold<std::tuple<>, is_same>, std::tuple<>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_pairwise_fold<std::tuple<X1>, is_same>, std::tuple<>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_pairwise_fold<std::tuple<X1, X2>, is_same>, std::tuple<is_same<X1, X2>>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_pairwise_fold<std::tuple<X1, X2, X2>, is_same>, std::tuple<is_same<X1, X2>, is_same<X2, X2>>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_pairwise_fold<std::tuple<X1, X2, X2, X1>, is_same>, std::tuple<is_same<X1, X2>, is_same<X2, X2>, is_same<X2, X1>>>));
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
18
test/mp_pairwise_fold_q.cpp
Normal file
18
test/mp_pairwise_fold_q.cpp
Normal file
@ -0,0 +1,18 @@
|
||||
// Copyright 2020 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11.hpp>
|
||||
#include <boost/core/lightweight_test_trait.hpp>
|
||||
|
||||
using namespace boost::mp11;
|
||||
|
||||
template<class L, template<class...> class P> using is_sorted = mp_none_of<mp_pairwise_fold_q<L, mp_bind<P, _2, _1>>, mp_to_bool>;
|
||||
|
||||
int main()
|
||||
{
|
||||
BOOST_TEST_TRAIT_TRUE((is_sorted<mp_list<mp_int<0>, mp_int<0>, mp_int<1>, mp_int<3>, mp_int<3>, mp_int<7>>, mp_less>));
|
||||
BOOST_TEST_TRAIT_FALSE((is_sorted<mp_list<mp_int<0>, mp_int<0>, mp_int<1>, mp_int<3>, mp_int<3>, mp_int<2>>, mp_less>));
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
88
test/mp_partial_sum.cpp
Normal file
88
test/mp_partial_sum.cpp
Normal file
@ -0,0 +1,88 @@
|
||||
// Copyright 2020 Peter Dimov.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/algorithm.hpp>
|
||||
#include <boost/mp11/list.hpp>
|
||||
#include <boost/mp11/integral.hpp>
|
||||
#include <boost/mp11/function.hpp>
|
||||
#include <boost/core/lightweight_test_trait.hpp>
|
||||
#include <type_traits>
|
||||
#include <tuple>
|
||||
#include <cstddef>
|
||||
|
||||
struct X1 {};
|
||||
struct X2 {};
|
||||
struct X3 {};
|
||||
|
||||
template<class T1, class T2> struct F {};
|
||||
|
||||
struct Q
|
||||
{
|
||||
template<class T1, class T2> struct fn {};
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
using boost::mp11::mp_partial_sum;
|
||||
using boost::mp11::mp_list;
|
||||
using boost::mp11::mp_list_c;
|
||||
using boost::mp11::mp_int;
|
||||
using boost::mp11::mp_size_t;
|
||||
using boost::mp11::mp_plus;
|
||||
using boost::mp11::mp_rename;
|
||||
using boost::mp11::mp_partial_sum_q;
|
||||
using boost::mp11::mp_quote;
|
||||
|
||||
{
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same< mp_partial_sum< mp_list<>, void, F >, mp_list<> >));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same< mp_partial_sum< mp_list<X1>, void, F >, mp_list< F<void, X1> > >));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same< mp_partial_sum< mp_list<X1, X2>, void, F >, mp_list< F<void, X1>, F<F<void, X1>, X2> > >));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same< mp_partial_sum< mp_list<X1, X2, X3>, void, F >, mp_list< F<void, X1>, F<F<void, X1>, X2>, F<F<F<void, X1>, X2>, X3> > >));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same< mp_partial_sum< mp_list_c<int, 7, 7, 2>, mp_int<0>, mp_plus >, mp_list< mp_int<7>, mp_int<14>, mp_int<16> > >));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same< mp_partial_sum< mp_list_c<std::size_t, 7, 7, 2>, mp_size_t<0>, mp_plus >, mp_list< mp_size_t<7>, mp_size_t<14>, mp_size_t<16> > >));
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same< mp_partial_sum_q< mp_list<>, void, mp_quote<F> >, mp_list<> >));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same< mp_partial_sum_q< mp_list<X1>, void, mp_quote<F> >, mp_list< F<void, X1> > >));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same< mp_partial_sum_q< mp_list<X1, X2>, void, mp_quote<F> >, mp_list< F<void, X1>, F<F<void, X1>, X2> > >));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same< mp_partial_sum_q< mp_list<X1, X2, X3>, void, mp_quote<F> >, mp_list< F<void, X1>, F<F<void, X1>, X2>, F<F<F<void, X1>, X2>, X3> > >));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same< mp_partial_sum_q< mp_list<>, void, Q >, mp_list<> >));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same< mp_partial_sum_q< mp_list<X1>, void, Q >, mp_list< Q::fn<void, X1> > >));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same< mp_partial_sum_q< mp_list<X1, X2>, void, Q >, mp_list< Q::fn<void, X1>, Q::fn<Q::fn<void, X1>, X2> > >));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same< mp_partial_sum_q< mp_list<X1, X2, X3>, void, Q >, mp_list< Q::fn<void, X1>, Q::fn<Q::fn<void, X1>, X2>, Q::fn<Q::fn<Q::fn<void, X1>, X2>, X3> > >));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same< mp_partial_sum_q< mp_list_c<int, 7, 7, 2>, mp_int<0>, mp_quote<mp_plus> >, mp_list< mp_int<7>, mp_int<14>, mp_int<16> > >));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same< mp_partial_sum_q< mp_list_c<std::size_t, 7, 7, 2>, mp_size_t<0>, mp_quote<mp_plus> >, mp_list< mp_size_t<7>, mp_size_t<14>, mp_size_t<16> > >));
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same< mp_partial_sum< std::tuple<>, void, F >, std::tuple<> >));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same< mp_partial_sum< std::tuple<X1>, void, F >, std::tuple< F<void, X1> > >));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same< mp_partial_sum< std::tuple<X1, X2>, void, F >, std::tuple< F<void, X1>, F<F<void, X1>, X2> > >));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same< mp_partial_sum< std::tuple<X1, X2, X3>, void, F >, std::tuple< F<void, X1>, F<F<void, X1>, X2>, F<F<F<void, X1>, X2>, X3> > >));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same< mp_partial_sum< mp_rename<mp_list_c<int, 7, 7, 2>, std::tuple>, mp_int<0>, mp_plus >, std::tuple< mp_int<7>, mp_int<14>, mp_int<16> > >));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same< mp_partial_sum< mp_rename<mp_list_c<std::size_t, 7, 7, 2>, std::tuple>, mp_size_t<0>, mp_plus >, std::tuple< mp_size_t<7>, mp_size_t<14>, mp_size_t<16> > >));
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same< mp_partial_sum_q< std::tuple<>, void, mp_quote<F> >, std::tuple<> >));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same< mp_partial_sum_q< std::tuple<X1>, void, mp_quote<F> >, std::tuple< F<void, X1> > >));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same< mp_partial_sum_q< std::tuple<X1, X2>, void, mp_quote<F> >, std::tuple< F<void, X1>, F<F<void, X1>, X2> > >));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same< mp_partial_sum_q< std::tuple<X1, X2, X3>, void, mp_quote<F> >, std::tuple< F<void, X1>, F<F<void, X1>, X2>, F<F<F<void, X1>, X2>, X3> > >));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same< mp_partial_sum_q< std::tuple<>, void, Q >, std::tuple<> >));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same< mp_partial_sum_q< std::tuple<X1>, void, Q >, std::tuple< Q::fn<void, X1> > >));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same< mp_partial_sum_q< std::tuple<X1, X2>, void, Q >, std::tuple< Q::fn<void, X1>, Q::fn<Q::fn<void, X1>, X2> > >));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same< mp_partial_sum_q< std::tuple<X1, X2, X3>, void, Q >, std::tuple< Q::fn<void, X1>, Q::fn<Q::fn<void, X1>, X2>, Q::fn<Q::fn<Q::fn<void, X1>, X2>, X3> > >));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same< mp_partial_sum_q< mp_rename<mp_list_c<int, 7, 7, 2>, std::tuple>, mp_int<0>, mp_quote<mp_plus> >, std::tuple< mp_int<7>, mp_int<14>, mp_int<16> > >));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same< mp_partial_sum_q< mp_rename<mp_list_c<std::size_t, 7, 7, 2>, std::tuple>, mp_size_t<0>, mp_quote<mp_plus> >, std::tuple< mp_size_t<7>, mp_size_t<14>, mp_size_t<16> > >));
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
33
test/mp_power_set.cpp
Normal file
33
test/mp_power_set.cpp
Normal file
@ -0,0 +1,33 @@
|
||||
// Copyright 2020 Peter Dimov.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/algorithm.hpp>
|
||||
#include <boost/mp11/list.hpp>
|
||||
#include <boost/core/lightweight_test_trait.hpp>
|
||||
#include <type_traits>
|
||||
#include <tuple>
|
||||
|
||||
struct X1 {};
|
||||
struct X2 {};
|
||||
struct X3 {};
|
||||
|
||||
int main()
|
||||
{
|
||||
using boost::mp11::mp_list;
|
||||
using boost::mp11::mp_power_set;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same< mp_power_set< mp_list<> >, mp_list<mp_list<>> >));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same< mp_power_set< mp_list<X1> >, mp_list< mp_list<>, mp_list<X1> > >));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same< mp_power_set< mp_list<X2, X1> >, mp_list< mp_list<>, mp_list<X1>, mp_list<X2>, mp_list<X2, X1> > >));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same< mp_power_set< mp_list<X1, X1> >, mp_list< mp_list<>, mp_list<X1>, mp_list<X1>, mp_list<X1, X1> > >));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same< mp_power_set< mp_list<X3, X2, X1> >, mp_list< mp_list<>, mp_list<X1>, mp_list<X2>, mp_list<X2, X1>, mp_list<X3>, mp_list<X3, X1>, mp_list<X3, X2>, mp_list<X3, X2, X1> > >));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same< mp_power_set< std::tuple<> >, std::tuple<std::tuple<>> >));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same< mp_power_set< std::tuple<X1> >, std::tuple< std::tuple<>, std::tuple<X1> > >));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same< mp_power_set< std::tuple<X2, X1> >, std::tuple< std::tuple<>, std::tuple<X1>, std::tuple<X2>, std::tuple<X2, X1> > >));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same< mp_power_set< std::tuple<X1, X1> >, std::tuple< std::tuple<>, std::tuple<X1>, std::tuple<X1>, std::tuple<X1, X1> > >));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same< mp_power_set< std::tuple<X3, X2, X1> >, std::tuple< std::tuple<>, std::tuple<X1>, std::tuple<X2>, std::tuple<X2, X1>, std::tuple<X3>, std::tuple<X3, X1>, std::tuple<X3, X2>, std::tuple<X3, X2, X1> > >));
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
@ -24,9 +24,10 @@ struct Y1 {};
|
||||
struct Z1 {};
|
||||
struct Z2 {};
|
||||
|
||||
template<class T1, class T2, class T3> struct F {};
|
||||
|
||||
template<class T> struct F1 {};
|
||||
template<class T1, class T2, class T3> struct F3 {};
|
||||
|
||||
template<class...> struct F {};
|
||||
|
||||
int main()
|
||||
{
|
||||
@ -40,8 +41,8 @@ int main()
|
||||
using L2 = mp_list<Y1>;
|
||||
using L3 = std::pair<Z1, Z2>;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_product<F, L1, L2, L3>, std::tuple<F<X1, Y1, Z1>, F<X1, Y1, Z2>, F<X2, Y1, Z1>, F<X2, Y1, Z2>, F<X3, Y1, Z1>, F<X3, Y1, Z2>>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_product_q<mp_quote<F>, L1, L2, L3>, std::tuple<F<X1, Y1, Z1>, F<X1, Y1, Z2>, F<X2, Y1, Z1>, F<X2, Y1, Z2>, F<X3, Y1, Z1>, F<X3, Y1, Z2>>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_product<F3, L1, L2, L3>, std::tuple<F3<X1, Y1, Z1>, F3<X1, Y1, Z2>, F3<X2, Y1, Z1>, F3<X2, Y1, Z2>, F3<X3, Y1, Z1>, F3<X3, Y1, Z2>>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_product_q<mp_quote<F3>, L1, L2, L3>, std::tuple<F3<X1, Y1, Z1>, F3<X1, Y1, Z2>, F3<X2, Y1, Z1>, F3<X2, Y1, Z2>, F3<X3, Y1, Z1>, F3<X3, Y1, Z2>>>));
|
||||
}
|
||||
|
||||
{
|
||||
@ -49,8 +50,8 @@ int main()
|
||||
using L2 = mp_list<>;
|
||||
using L3 = std::pair<Z1, Z2>;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_product<F, L1, L2, L3>, std::tuple<>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_product_q<mp_quote<F>, L1, L2, L3>, std::tuple<>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_product<F3, L1, L2, L3>, std::tuple<>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_product_q<mp_quote<F3>, L1, L2, L3>, std::tuple<>>));
|
||||
}
|
||||
|
||||
{
|
||||
@ -64,5 +65,10 @@ int main()
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_product_q<mp_quote<F1>, L2>, mp_list<F1<X1>, F1<X2>, F1<X3>>>));
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_product<F>, mp_list<F<>>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_product_q<mp_quote<F>>, mp_list<F<>>>));
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
136
test/mp_rotate_left.cpp
Normal file
136
test/mp_rotate_left.cpp
Normal file
@ -0,0 +1,136 @@
|
||||
|
||||
// Copyright 2015 Peter Dimov.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
|
||||
#include <boost/mp11/algorithm.hpp>
|
||||
#include <boost/mp11/list.hpp>
|
||||
#include <boost/mp11/integral.hpp>
|
||||
#include <boost/core/lightweight_test_trait.hpp>
|
||||
#include <type_traits>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
struct X1 {};
|
||||
struct X2 {};
|
||||
struct X3 {};
|
||||
struct X4 {};
|
||||
struct X5 {};
|
||||
|
||||
int main()
|
||||
{
|
||||
using boost::mp11::mp_list;
|
||||
using boost::mp11::mp_rotate_left;
|
||||
using boost::mp11::mp_rotate_left_c;
|
||||
using boost::mp11::mp_size_t;
|
||||
|
||||
{
|
||||
using L1 = mp_list<>;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left_c<L1, 0>, L1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left_c<L1, 1>, L1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left_c<L1, 2>, L1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left_c<L1, 3>, L1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left_c<L1, 4>, L1>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left<L1, mp_size_t<0>>, L1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left<L1, mp_size_t<1>>, L1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left<L1, mp_size_t<2>>, L1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left<L1, mp_size_t<3>>, L1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left<L1, mp_size_t<4>>, L1>));
|
||||
|
||||
using L2 = mp_list<X1, X2, X3, X4, X5>;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left_c<L2, 0>, mp_list<X1, X2, X3, X4, X5>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left_c<L2, 1>, mp_list<X2, X3, X4, X5, X1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left_c<L2, 2>, mp_list<X3, X4, X5, X1, X2>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left_c<L2, 3>, mp_list<X4, X5, X1, X2, X3>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left_c<L2, 4>, mp_list<X5, X1, X2, X3, X4>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left_c<L2, 5>, mp_list<X1, X2, X3, X4, X5>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left_c<L2, 6>, mp_list<X2, X3, X4, X5, X1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left_c<L2, 7>, mp_list<X3, X4, X5, X1, X2>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left_c<L2, 8>, mp_list<X4, X5, X1, X2, X3>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left_c<L2, 9>, mp_list<X5, X1, X2, X3, X4>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left_c<L2, 10>, mp_list<X1, X2, X3, X4, X5>>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left<L2, mp_size_t<0>>, mp_list<X1, X2, X3, X4, X5>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left<L2, mp_size_t<1>>, mp_list<X2, X3, X4, X5, X1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left<L2, mp_size_t<2>>, mp_list<X3, X4, X5, X1, X2>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left<L2, mp_size_t<3>>, mp_list<X4, X5, X1, X2, X3>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left<L2, mp_size_t<4>>, mp_list<X5, X1, X2, X3, X4>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left<L2, mp_size_t<5>>, mp_list<X1, X2, X3, X4, X5>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left<L2, mp_size_t<6>>, mp_list<X2, X3, X4, X5, X1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left<L2, mp_size_t<7>>, mp_list<X3, X4, X5, X1, X2>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left<L2, mp_size_t<8>>, mp_list<X4, X5, X1, X2, X3>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left<L2, mp_size_t<9>>, mp_list<X5, X1, X2, X3, X4>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left<L2, mp_size_t<10>>, mp_list<X1, X2, X3, X4, X5>>));
|
||||
}
|
||||
|
||||
{
|
||||
using L1 = std::tuple<>;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left_c<L1, 0>, L1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left_c<L1, 1>, L1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left_c<L1, 2>, L1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left_c<L1, 3>, L1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left_c<L1, 4>, L1>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left<L1, mp_size_t<0>>, L1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left<L1, mp_size_t<1>>, L1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left<L1, mp_size_t<2>>, L1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left<L1, mp_size_t<3>>, L1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left<L1, mp_size_t<4>>, L1>));
|
||||
|
||||
using L2 = std::tuple<X1, X2, X3, X4, X5>;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left_c<L2, 0>, std::tuple<X1, X2, X3, X4, X5>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left_c<L2, 1>, std::tuple<X2, X3, X4, X5, X1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left_c<L2, 2>, std::tuple<X3, X4, X5, X1, X2>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left_c<L2, 3>, std::tuple<X4, X5, X1, X2, X3>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left_c<L2, 4>, std::tuple<X5, X1, X2, X3, X4>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left_c<L2, 5>, std::tuple<X1, X2, X3, X4, X5>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left_c<L2, 6>, std::tuple<X2, X3, X4, X5, X1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left_c<L2, 7>, std::tuple<X3, X4, X5, X1, X2>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left_c<L2, 8>, std::tuple<X4, X5, X1, X2, X3>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left_c<L2, 9>, std::tuple<X5, X1, X2, X3, X4>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left_c<L2, 10>, std::tuple<X1, X2, X3, X4, X5>>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left<L2, mp_size_t<0>>, std::tuple<X1, X2, X3, X4, X5>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left<L2, mp_size_t<1>>, std::tuple<X2, X3, X4, X5, X1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left<L2, mp_size_t<2>>, std::tuple<X3, X4, X5, X1, X2>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left<L2, mp_size_t<3>>, std::tuple<X4, X5, X1, X2, X3>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left<L2, mp_size_t<4>>, std::tuple<X5, X1, X2, X3, X4>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left<L2, mp_size_t<5>>, std::tuple<X1, X2, X3, X4, X5>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left<L2, mp_size_t<6>>, std::tuple<X2, X3, X4, X5, X1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left<L2, mp_size_t<7>>, std::tuple<X3, X4, X5, X1, X2>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left<L2, mp_size_t<8>>, std::tuple<X4, X5, X1, X2, X3>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left<L2, mp_size_t<9>>, std::tuple<X5, X1, X2, X3, X4>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left<L2, mp_size_t<10>>, std::tuple<X1, X2, X3, X4, X5>>));
|
||||
}
|
||||
|
||||
{
|
||||
using L1 = std::pair<X1, X2>;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left_c<L1, 0>, L1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left_c<L1, 2>, L1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left_c<L1, 4>, L1>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left_c<L1, 1>, std::pair<X2, X1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left_c<L1, 3>, std::pair<X2, X1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left_c<L1, 5>, std::pair<X2, X1>>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left<L1, mp_size_t<0>>, L1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left<L1, mp_size_t<2>>, L1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left<L1, mp_size_t<4>>, L1>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left<L1, mp_size_t<1>>, std::pair<X2, X1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left<L1, mp_size_t<3>>, std::pair<X2, X1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_left<L1, mp_size_t<5>>, std::pair<X2, X1>>));
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
136
test/mp_rotate_right.cpp
Normal file
136
test/mp_rotate_right.cpp
Normal file
@ -0,0 +1,136 @@
|
||||
|
||||
// Copyright 2015 Peter Dimov.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
|
||||
#include <boost/mp11/algorithm.hpp>
|
||||
#include <boost/mp11/list.hpp>
|
||||
#include <boost/mp11/integral.hpp>
|
||||
#include <boost/core/lightweight_test_trait.hpp>
|
||||
#include <type_traits>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
struct X1 {};
|
||||
struct X2 {};
|
||||
struct X3 {};
|
||||
struct X4 {};
|
||||
struct X5 {};
|
||||
|
||||
int main()
|
||||
{
|
||||
using boost::mp11::mp_list;
|
||||
using boost::mp11::mp_rotate_right;
|
||||
using boost::mp11::mp_rotate_right_c;
|
||||
using boost::mp11::mp_size_t;
|
||||
|
||||
{
|
||||
using L1 = mp_list<>;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right_c<L1, 0>, L1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right_c<L1, 1>, L1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right_c<L1, 2>, L1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right_c<L1, 3>, L1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right_c<L1, 4>, L1>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right<L1, mp_size_t<0>>, L1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right<L1, mp_size_t<1>>, L1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right<L1, mp_size_t<2>>, L1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right<L1, mp_size_t<3>>, L1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right<L1, mp_size_t<4>>, L1>));
|
||||
|
||||
using L2 = mp_list<X1, X2, X3, X4, X5>;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right_c<L2, 0>, mp_list<X1, X2, X3, X4, X5>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right_c<L2, 1>, mp_list<X5, X1, X2, X3, X4>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right_c<L2, 2>, mp_list<X4, X5, X1, X2, X3>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right_c<L2, 3>, mp_list<X3, X4, X5, X1, X2>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right_c<L2, 4>, mp_list<X2, X3, X4, X5, X1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right_c<L2, 5>, mp_list<X1, X2, X3, X4, X5>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right_c<L2, 6>, mp_list<X5, X1, X2, X3, X4>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right_c<L2, 7>, mp_list<X4, X5, X1, X2, X3>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right_c<L2, 8>, mp_list<X3, X4, X5, X1, X2>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right_c<L2, 9>, mp_list<X2, X3, X4, X5, X1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right_c<L2, 10>, mp_list<X1, X2, X3, X4, X5>>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right<L2, mp_size_t<0>>, mp_list<X1, X2, X3, X4, X5>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right<L2, mp_size_t<1>>, mp_list<X5, X1, X2, X3, X4>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right<L2, mp_size_t<2>>, mp_list<X4, X5, X1, X2, X3>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right<L2, mp_size_t<3>>, mp_list<X3, X4, X5, X1, X2>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right<L2, mp_size_t<4>>, mp_list<X2, X3, X4, X5, X1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right<L2, mp_size_t<5>>, mp_list<X1, X2, X3, X4, X5>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right<L2, mp_size_t<6>>, mp_list<X5, X1, X2, X3, X4>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right<L2, mp_size_t<7>>, mp_list<X4, X5, X1, X2, X3>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right<L2, mp_size_t<8>>, mp_list<X3, X4, X5, X1, X2>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right<L2, mp_size_t<9>>, mp_list<X2, X3, X4, X5, X1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right<L2, mp_size_t<10>>, mp_list<X1, X2, X3, X4, X5>>));
|
||||
}
|
||||
|
||||
{
|
||||
using L1 = std::tuple<>;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right_c<L1, 0>, L1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right_c<L1, 1>, L1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right_c<L1, 2>, L1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right_c<L1, 3>, L1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right_c<L1, 4>, L1>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right<L1, mp_size_t<0>>, L1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right<L1, mp_size_t<1>>, L1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right<L1, mp_size_t<2>>, L1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right<L1, mp_size_t<3>>, L1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right<L1, mp_size_t<4>>, L1>));
|
||||
|
||||
using L2 = std::tuple<X1, X2, X3, X4, X5>;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right_c<L2, 0>, std::tuple<X1, X2, X3, X4, X5>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right_c<L2, 1>, std::tuple<X5, X1, X2, X3, X4>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right_c<L2, 2>, std::tuple<X4, X5, X1, X2, X3>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right_c<L2, 3>, std::tuple<X3, X4, X5, X1, X2>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right_c<L2, 4>, std::tuple<X2, X3, X4, X5, X1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right_c<L2, 5>, std::tuple<X1, X2, X3, X4, X5>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right_c<L2, 6>, std::tuple<X5, X1, X2, X3, X4>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right_c<L2, 7>, std::tuple<X4, X5, X1, X2, X3>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right_c<L2, 8>, std::tuple<X3, X4, X5, X1, X2>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right_c<L2, 9>, std::tuple<X2, X3, X4, X5, X1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right_c<L2, 10>, std::tuple<X1, X2, X3, X4, X5>>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right<L2, mp_size_t<0>>, std::tuple<X1, X2, X3, X4, X5>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right<L2, mp_size_t<1>>, std::tuple<X5, X1, X2, X3, X4>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right<L2, mp_size_t<2>>, std::tuple<X4, X5, X1, X2, X3>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right<L2, mp_size_t<3>>, std::tuple<X3, X4, X5, X1, X2>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right<L2, mp_size_t<4>>, std::tuple<X2, X3, X4, X5, X1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right<L2, mp_size_t<5>>, std::tuple<X1, X2, X3, X4, X5>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right<L2, mp_size_t<6>>, std::tuple<X5, X1, X2, X3, X4>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right<L2, mp_size_t<7>>, std::tuple<X4, X5, X1, X2, X3>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right<L2, mp_size_t<8>>, std::tuple<X3, X4, X5, X1, X2>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right<L2, mp_size_t<9>>, std::tuple<X2, X3, X4, X5, X1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right<L2, mp_size_t<10>>, std::tuple<X1, X2, X3, X4, X5>>));
|
||||
}
|
||||
|
||||
{
|
||||
using L1 = std::pair<X1, X2>;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right_c<L1, 0>, L1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right_c<L1, 2>, L1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right_c<L1, 4>, L1>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right_c<L1, 1>, std::pair<X2, X1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right_c<L1, 3>, std::pair<X2, X1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right_c<L1, 5>, std::pair<X2, X1>>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right<L1, mp_size_t<0>>, L1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right<L1, mp_size_t<2>>, L1>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right<L1, mp_size_t<4>>, L1>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right<L1, mp_size_t<1>>, std::pair<X2, X1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right<L1, mp_size_t<3>>, std::pair<X2, X1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rotate_right<L1, mp_size_t<5>>, std::pair<X2, X1>>));
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
@ -40,7 +40,7 @@ int main()
|
||||
using boost::mp11::mp_list;
|
||||
using boost::mp11::mp_apply;
|
||||
|
||||
int const N = 1024;
|
||||
int const N = 1089;
|
||||
|
||||
using L = mp_repeat_c<mp_list<void>, N>;
|
||||
using R = mp_apply<mp_same, L>;
|
||||
|
@ -33,12 +33,17 @@ int main()
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_similar<void, void, void, void, int>, mp_false>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_similar<X<void>>, mp_true>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_similar<X<void>, X<void>>, mp_true>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_similar<X<void>, X<int>>, mp_true>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_similar<X<void>, X<void>, X<void>>, mp_true>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_similar<X<void>, X<int>, X<float>>, mp_true>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_similar<Y<>>, mp_true>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_similar<Y<>, Y<>>, mp_true>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_similar<Y<>, Y<void>>, mp_true>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_similar<Y<>, Y<>, Y<>>, mp_true>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_similar<Y<>, Y<void>, Y<void, void>>, mp_true>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_similar<Y<>, Y<>, Y<>, Y<>>, mp_true>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_similar<Y<>, Y<void>, Y<void, void>, Y<void, void, void>>, mp_true>));
|
||||
|
||||
return boost::report_errors();
|
||||
|
51
test/mp_split.cpp
Normal file
51
test/mp_split.cpp
Normal file
@ -0,0 +1,51 @@
|
||||
// Copyright 2021 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/algorithm.hpp>
|
||||
#include <boost/mp11/list.hpp>
|
||||
#include <boost/core/lightweight_test_trait.hpp>
|
||||
#include <type_traits>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
struct X1 {};
|
||||
struct X2 {};
|
||||
struct X3 {};
|
||||
struct X4 {};
|
||||
|
||||
struct S {};
|
||||
|
||||
int main()
|
||||
{
|
||||
using boost::mp11::mp_list;
|
||||
using boost::mp11::mp_split;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_split<mp_list<>, void>, mp_list<mp_list<>>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_split<mp_list<X1>, void>, mp_list<mp_list<X1>>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_split<mp_list<X1, X2>, void>, mp_list<mp_list<X1, X2>>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_split<mp_list<X1, X2, X3>, void>, mp_list<mp_list<X1, X2, X3>>>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_split<mp_list<S>, S>, mp_list<mp_list<>, mp_list<>>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_split<mp_list<S, S>, S>, mp_list<mp_list<>, mp_list<>, mp_list<>>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_split<mp_list<S, S, S>, S>, mp_list<mp_list<>, mp_list<>, mp_list<>, mp_list<>>>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_split<mp_list<X1, S, X2>, S>, mp_list<mp_list<X1>, mp_list<X2>>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_split<mp_list<X1, X2, S, X3, X4>, S>, mp_list<mp_list<X1, X2>, mp_list<X3, X4>>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_split<mp_list<S, X1, X2, S, S, X3, X4, S>, S>, mp_list<mp_list<>, mp_list<X1, X2>, mp_list<>, mp_list<X3, X4>, mp_list<>>>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_split<std::tuple<>, void>, std::tuple<std::tuple<>>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_split<std::tuple<X1>, void>, std::tuple<std::tuple<X1>>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_split<std::tuple<X1, X2>, void>, std::tuple<std::tuple<X1, X2>>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_split<std::tuple<X1, X2, X3>, void>, std::tuple<std::tuple<X1, X2, X3>>>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_split<std::tuple<S>, S>, std::tuple<std::tuple<>, std::tuple<>>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_split<std::tuple<S, S>, S>, std::tuple<std::tuple<>, std::tuple<>, std::tuple<>>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_split<std::tuple<S, S, S>, S>, std::tuple<std::tuple<>, std::tuple<>, std::tuple<>, std::tuple<>>>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_split<std::tuple<X1, S, X2>, S>, std::tuple<std::tuple<X1>, std::tuple<X2>>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_split<std::tuple<X1, X2, S, X3, X4>, S>, std::tuple<std::tuple<X1, X2>, std::tuple<X3, X4>>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_split<std::tuple<S, X1, X2, S, S, X3, X4, S>, S>, std::tuple<std::tuple<>, std::tuple<X1, X2>, std::tuple<>, std::tuple<X3, X4>, std::tuple<>>>));
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
110
test/mp_unique_if.cpp
Normal file
110
test/mp_unique_if.cpp
Normal file
@ -0,0 +1,110 @@
|
||||
// Copyright 2015 Peter Dimov.
|
||||
// Copyright 2019 Kris Jusiak.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
|
||||
#if BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, < 40800 )
|
||||
# pragma GCC diagnostic ignored "-Wsign-compare"
|
||||
#endif
|
||||
|
||||
#include <boost/mp11/algorithm.hpp>
|
||||
#include <boost/mp11/list.hpp>
|
||||
#include <boost/mp11/integral.hpp>
|
||||
#include <boost/core/lightweight_test_trait.hpp>
|
||||
#include <type_traits>
|
||||
#include <tuple>
|
||||
#include <cstddef>
|
||||
|
||||
using boost::mp11::mp_bool;
|
||||
|
||||
#if !BOOST_MP11_WORKAROUND( BOOST_MSVC, < 1910 )
|
||||
|
||||
template<class T, class U> using Eq1 = mp_bool< T::value == U::value >;
|
||||
template<class T, class U> using Eq2 = mp_bool< sizeof(T) == sizeof(U) >;
|
||||
|
||||
#else
|
||||
|
||||
template<class T, class U> struct Eq1: mp_bool< T::value == U::value > {};
|
||||
template<class T, class U> struct Eq2: mp_bool< sizeof(T) == sizeof(U) > {};
|
||||
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
using boost::mp11::mp_list;
|
||||
using boost::mp11::mp_unique_if;
|
||||
|
||||
{
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_unique_if<mp_list<>, std::is_same>, mp_list<>>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_unique_if<mp_list<void>, std::is_same>, mp_list<void>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_unique_if<mp_list<void, void>, std::is_same>, mp_list<void>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_unique_if<mp_list<void, void, void>, std::is_same>, mp_list<void>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_unique_if<mp_list<void, void, void, void>, std::is_same>, mp_list<void>>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_unique_if<mp_list<void, int>, std::is_same>, mp_list<void, int>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_unique_if<mp_list<void, void, void, int, int, int>, std::is_same>, mp_list<void, int>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_unique_if<mp_list<void, int, void, int, int, void, int, int, int>, std::is_same>, mp_list<void, int>>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_unique_if<mp_list<void, int, char[]>, std::is_same>, mp_list<void, int, char[]>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_unique_if<mp_list<void, int, char[], void, int, char[], void, int, char[]>, std::is_same>, mp_list<void, int, char[]>>));
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_unique_if<std::tuple<>, std::is_same>, std::tuple<>>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_unique_if<std::tuple<void>, std::is_same>, std::tuple<void>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_unique_if<std::tuple<void, void>, std::is_same>, std::tuple<void>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_unique_if<std::tuple<void, void, void>, std::is_same>, std::tuple<void>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_unique_if<std::tuple<void, void, void, void>, std::is_same>, std::tuple<void>>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_unique_if<std::tuple<void, int>, std::is_same>, std::tuple<void, int>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_unique_if<std::tuple<void, void, void, int, int, int>, std::is_same>, std::tuple<void, int>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_unique_if<std::tuple<void, int, void, int, int, void, int, int, int>, std::is_same>, std::tuple<void, int>>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_unique_if<std::tuple<void, int, char[]>, std::is_same>, std::tuple<void, int, char[]>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_unique_if<std::tuple<void, int, char[], void, int, char[], void, int, char[]>, std::is_same>, std::tuple<void, int, char[]>>));
|
||||
}
|
||||
|
||||
{
|
||||
using boost::mp11::mp_iota_c;
|
||||
using boost::mp11::mp_size_t;
|
||||
|
||||
using L1 = mp_iota_c<32>;
|
||||
|
||||
using R1 = mp_unique_if<L1, std::is_same>;
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<R1, L1>));
|
||||
|
||||
using R2 = mp_unique_if<L1, Eq1>;
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<R2, L1>));
|
||||
|
||||
using R3 = mp_unique_if<L1, Eq2>;
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<R3, mp_list<mp_size_t<0>>>));
|
||||
}
|
||||
|
||||
{
|
||||
using boost::mp11::mp_list_c;
|
||||
using boost::mp11::mp_append;
|
||||
using boost::mp11::mp_push_back;
|
||||
using boost::mp11::mp_int;
|
||||
|
||||
using L1 = mp_list_c<std::size_t, 0, 1, 2, 3>;
|
||||
using L2 = mp_list_c<int, 1, 2, 3, 4>;
|
||||
using L3 = mp_list_c<long, 2, 3, 4, 5>;
|
||||
|
||||
using R1 = mp_unique_if<mp_append<L1, L2, L3>, Eq1>;
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<R1, mp_push_back<L1, mp_int<4>, std::integral_constant<long, 5>>>));
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_unique_if<std::tuple<char[1], char[2], char[1], char[2], char[2], char[1], char[2], char[2], char[2]>, Eq2>, std::tuple<char[1], char[2]>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_unique_if<std::tuple<char[1], char[2], char[3], char[1], char[2], char[3], char[1], char[2], char[3]>, Eq2>, std::tuple<char[1], char[2], char[3]>>));
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
93
test/mp_unique_if_q.cpp
Normal file
93
test/mp_unique_if_q.cpp
Normal file
@ -0,0 +1,93 @@
|
||||
// Copyright 2015 Peter Dimov.
|
||||
// Copyright 2019 Kris Jusiak.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
|
||||
#if BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, < 40800 )
|
||||
# pragma GCC diagnostic ignored "-Wsign-compare"
|
||||
#endif
|
||||
|
||||
#include <boost/mp11/algorithm.hpp>
|
||||
#include <boost/mp11/list.hpp>
|
||||
#include <boost/mp11/integral.hpp>
|
||||
#include <boost/mp11/utility.hpp>
|
||||
#include <boost/core/lightweight_test_trait.hpp>
|
||||
#include <type_traits>
|
||||
#include <tuple>
|
||||
|
||||
using boost::mp11::mp_bool;
|
||||
|
||||
#if !BOOST_MP11_WORKAROUND( BOOST_MSVC, < 1910 )
|
||||
|
||||
struct Q1
|
||||
{
|
||||
template<class T, class U> using fn = mp_bool< T::value == U::value >;
|
||||
};
|
||||
|
||||
struct Q2
|
||||
{
|
||||
template<class T, class U> using fn = mp_bool< sizeof(T) == sizeof(U) >;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
struct Q1
|
||||
{
|
||||
template<class T, class U> struct fn: mp_bool< T::value == U::value > {};
|
||||
};
|
||||
|
||||
struct Q2
|
||||
{
|
||||
template<class T, class U> struct fn: mp_bool< sizeof(T) == sizeof(U) > {};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
using boost::mp11::mp_list;
|
||||
using boost::mp11::mp_unique_if_q;
|
||||
using boost::mp11::mp_quote_trait;
|
||||
|
||||
{
|
||||
using boost::mp11::mp_iota_c;
|
||||
using boost::mp11::mp_size_t;
|
||||
|
||||
using L1 = mp_iota_c<32>;
|
||||
|
||||
using R1 = mp_unique_if_q<L1, mp_quote_trait<std::is_same>>;
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<R1, L1>));
|
||||
|
||||
using R2 = mp_unique_if_q<L1, Q1>;
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<R2, L1>));
|
||||
|
||||
using R3 = mp_unique_if_q<L1, Q2>;
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<R3, mp_list<mp_size_t<0>>>));
|
||||
}
|
||||
|
||||
{
|
||||
using boost::mp11::mp_list_c;
|
||||
using boost::mp11::mp_append;
|
||||
using boost::mp11::mp_push_back;
|
||||
using boost::mp11::mp_int;
|
||||
|
||||
using L1 = mp_list_c<std::size_t, 0, 1, 2, 3>;
|
||||
using L2 = mp_list_c<int, 1, 2, 3, 4>;
|
||||
using L3 = mp_list_c<long, 2, 3, 4, 5>;
|
||||
|
||||
using R1 = mp_unique_if_q<mp_append<L1, L2, L3>, Q1>;
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<R1, mp_push_back<L1, mp_int<4>, std::integral_constant<long, 5>>>));
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_unique_if_q<std::tuple<char[1], char[2], char[1], char[2], char[2], char[1], char[2], char[2], char[2]>, Q2>, std::tuple<char[1], char[2]>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_unique_if_q<std::tuple<char[1], char[2], char[3], char[1], char[2], char[3], char[1], char[2], char[3]>, Q2>, std::tuple<char[1], char[2], char[3]>>));
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
48
test/mp_valid_and_true.cpp
Normal file
48
test/mp_valid_and_true.cpp
Normal file
@ -0,0 +1,48 @@
|
||||
// Copyright 2022 Dmitry Arkhipov (grisumbras@gmail.com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
|
||||
#include <boost/mp11/utility.hpp>
|
||||
#include <boost/core/lightweight_test_trait.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
template<class T>
|
||||
using has_size_t_difference_type
|
||||
= std::is_same<typename T::difference_type, std::size_t>;
|
||||
|
||||
struct X
|
||||
{
|
||||
};
|
||||
|
||||
struct Y
|
||||
{
|
||||
using difference_type = int;
|
||||
};
|
||||
|
||||
struct Z
|
||||
{
|
||||
using difference_type = std::size_t;
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
using boost::mp11::mp_valid_and_true;
|
||||
using boost::mp11::mp_valid_and_true_q;
|
||||
using boost::mp11::mp_quote;
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE((mp_valid_and_true<has_size_t_difference_type, X>));
|
||||
BOOST_TEST_TRAIT_FALSE((mp_valid_and_true<has_size_t_difference_type, Y>));
|
||||
BOOST_TEST_TRAIT_TRUE((mp_valid_and_true<has_size_t_difference_type, Z>));
|
||||
|
||||
using Q_size_t_diff = mp_quote<has_size_t_difference_type>;
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE((mp_valid_and_true_q<Q_size_t_diff, X>));
|
||||
BOOST_TEST_TRAIT_FALSE((mp_valid_and_true_q<Q_size_t_diff, Y>));
|
||||
BOOST_TEST_TRAIT_TRUE((mp_valid_and_true_q<Q_size_t_diff, Z>));
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
|
||||
// Copyright 2017 Peter Dimov.
|
||||
// Copyright 2017 Peter Dimov.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
@ -7,6 +7,12 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
|
||||
#if BOOST_MP11_MSVC
|
||||
# pragma warning( disable: 4503 ) // decorated name length exceeded
|
||||
#endif
|
||||
|
||||
#include <boost/mp11/algorithm.hpp>
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
36
test/mpl_list.cpp
Normal file
36
test/mpl_list.cpp
Normal file
@ -0,0 +1,36 @@
|
||||
|
||||
// Copyright 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 <boost/mp11/mpl_list.hpp>
|
||||
#include <boost/mp11/list.hpp>
|
||||
|
||||
#include <boost/mpl/at.hpp>
|
||||
#include <boost/mpl/size.hpp>
|
||||
|
||||
#include <boost/core/lightweight_test_trait.hpp>
|
||||
|
||||
int main()
|
||||
{
|
||||
namespace mpl = boost::mpl;
|
||||
using namespace boost::mp11;
|
||||
|
||||
using L1 = mp_list<void, int, float>;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<typename mpl::at<L1, mpl::int_<0>>::type, mp_at_c<L1, 0>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<typename mpl::at<L1, mpl::int_<1>>::type, mp_at_c<L1, 1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<typename mpl::at<L1, mpl::int_<2>>::type, mp_at_c<L1, 2>>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<typename mpl::at_c<L1, 0>::type, mp_at_c<L1, 0>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<typename mpl::at_c<L1, 1>::type, mp_at_c<L1, 1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<typename mpl::at_c<L1, 2>::type, mp_at_c<L1, 2>>));
|
||||
|
||||
BOOST_TEST_EQ((mpl::size<L1>::type::value), mp_size<L1>::value);
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
36
test/mpl_tuple.cpp
Normal file
36
test/mpl_tuple.cpp
Normal file
@ -0,0 +1,36 @@
|
||||
|
||||
// Copyright 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 <boost/mp11/mpl_tuple.hpp>
|
||||
#include <tuple>
|
||||
|
||||
#include <boost/mpl/at.hpp>
|
||||
#include <boost/mpl/size.hpp>
|
||||
|
||||
#include <boost/core/lightweight_test_trait.hpp>
|
||||
|
||||
int main()
|
||||
{
|
||||
namespace mpl = boost::mpl;
|
||||
using namespace boost::mp11;
|
||||
|
||||
using L1 = std::tuple<char, int, float>;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<typename mpl::at<L1, mpl::int_<0>>::type, mp_at_c<L1, 0>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<typename mpl::at<L1, mpl::int_<1>>::type, mp_at_c<L1, 1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<typename mpl::at<L1, mpl::int_<2>>::type, mp_at_c<L1, 2>>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<typename mpl::at_c<L1, 0>::type, mp_at_c<L1, 0>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<typename mpl::at_c<L1, 1>::type, mp_at_c<L1, 1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<typename mpl::at_c<L1, 2>::type, mp_at_c<L1, 2>>));
|
||||
|
||||
BOOST_TEST_EQ((mpl::size<L1>::type::value), mp_size<L1>::value);
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
@ -16,7 +16,7 @@
|
||||
|
||||
// Technically std::tuple isn't constexpr enabled in C++11, but it works with libstdc++
|
||||
|
||||
#if defined( BOOST_MP11_NO_CONSTEXPR ) || ( !defined( __GLIBCXX__ ) && __cplusplus < 201400L )
|
||||
#if defined( BOOST_MP11_NO_CONSTEXPR ) || ( !defined(_MSC_VER) && !defined( __GLIBCXX__ ) && __cplusplus < 201400L )
|
||||
|
||||
int main() {}
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
// Technically std::tuple isn't constexpr enabled in C++11, but it works with libstdc++
|
||||
|
||||
#if defined( BOOST_MP11_NO_CONSTEXPR ) || ( !defined( __GLIBCXX__ ) && __cplusplus < 201400L )
|
||||
#if defined( BOOST_MP11_NO_CONSTEXPR ) || ( !defined(_MSC_VER) && !defined( __GLIBCXX__ ) && __cplusplus < 201400L )
|
||||
|
||||
int main() {}
|
||||
|
||||
|
190
test/tuple_transform.cpp
Normal file
190
test/tuple_transform.cpp
Normal file
@ -0,0 +1,190 @@
|
||||
|
||||
// Copyright 2020 Hans Dembinski.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/tuple.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/core/lightweight_test_trait.hpp>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
#include <iosfwd>
|
||||
|
||||
// family of test types with state
|
||||
template <int N>
|
||||
struct T {
|
||||
int value;
|
||||
T() : value{N} {};
|
||||
explicit T(int n) : value{n} {}
|
||||
};
|
||||
|
||||
template <int N>
|
||||
std::ostream& operator<<( std::ostream& os, T<N> const& t )
|
||||
{
|
||||
os << t.value;
|
||||
return os;
|
||||
}
|
||||
|
||||
// test function changes type and value
|
||||
struct F {
|
||||
template<int N, int M=1> T<N+M> operator()( T<N> a, T<M> b={} ) const
|
||||
{
|
||||
return T<N+M>{a.value + b.value + 1};
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
using boost::mp11::tuple_transform;
|
||||
|
||||
{
|
||||
std::tuple<T<1>, T<2>, T<3>> tp;
|
||||
std::tuple<T<4>, T<5>, T<6>> tp2;
|
||||
|
||||
{
|
||||
std::tuple<T<2>, T<3>, T<4>> s = tuple_transform( F{}, tp );
|
||||
BOOST_TEST_EQ( std::get<0>(s).value, 3 );
|
||||
BOOST_TEST_EQ( std::get<1>(s).value, 4 );
|
||||
BOOST_TEST_EQ( std::get<2>(s).value, 5 );
|
||||
}
|
||||
|
||||
{
|
||||
std::tuple<T<2>, T<3>, T<4>> s = tuple_transform( F{}, std::move(tp) );
|
||||
BOOST_TEST_EQ( std::get<0>(s).value, 3 );
|
||||
BOOST_TEST_EQ( std::get<1>(s).value, 4 );
|
||||
BOOST_TEST_EQ( std::get<2>(s).value, 5 );
|
||||
}
|
||||
|
||||
{
|
||||
std::tuple<T<5>, T<7>, T<9>> s = tuple_transform( F{}, tp, tp2 );
|
||||
BOOST_TEST_EQ( std::get<0>(s).value, 6 );
|
||||
BOOST_TEST_EQ( std::get<1>(s).value, 8 );
|
||||
BOOST_TEST_EQ( std::get<2>(s).value, 10 );
|
||||
}
|
||||
|
||||
{
|
||||
std::tuple<T<5>, T<7>, T<9>> s = tuple_transform(
|
||||
F{}, std::move(tp), std::move(tp2)
|
||||
);
|
||||
BOOST_TEST_EQ( std::get<0>(s).value, 6 );
|
||||
BOOST_TEST_EQ( std::get<1>(s).value, 8 );
|
||||
BOOST_TEST_EQ( std::get<2>(s).value, 10 );
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
std::tuple<T<1>, T<2>, T<3>> const tp;
|
||||
std::tuple<T<4>, T<5>, T<6>> const tp2;
|
||||
|
||||
{
|
||||
std::tuple<T<2>, T<3>, T<4>> s = tuple_transform( F{}, tp );
|
||||
BOOST_TEST_EQ( std::get<0>(s).value, 3 );
|
||||
BOOST_TEST_EQ( std::get<1>(s).value, 4 );
|
||||
BOOST_TEST_EQ( std::get<2>(s).value, 5 );
|
||||
}
|
||||
|
||||
{
|
||||
std::tuple<T<2>, T<3>, T<4>> s = tuple_transform( F{}, std::move(tp) );
|
||||
BOOST_TEST_EQ( std::get<0>(s).value, 3 );
|
||||
BOOST_TEST_EQ( std::get<1>(s).value, 4 );
|
||||
BOOST_TEST_EQ( std::get<2>(s).value, 5 );
|
||||
}
|
||||
|
||||
{
|
||||
std::tuple<T<5>, T<7>, T<9>> s = tuple_transform( F{}, tp, tp2 );
|
||||
BOOST_TEST_EQ( std::get<0>(s).value, 6 );
|
||||
BOOST_TEST_EQ( std::get<1>(s).value, 8 );
|
||||
BOOST_TEST_EQ( std::get<2>(s).value, 10 );
|
||||
}
|
||||
|
||||
{
|
||||
std::tuple<T<5>, T<7>, T<9>> s = tuple_transform(
|
||||
F{}, std::move(tp), std::move(tp2)
|
||||
);
|
||||
BOOST_TEST_EQ( std::get<0>(s).value, 6 );
|
||||
BOOST_TEST_EQ( std::get<1>(s).value, 8 );
|
||||
BOOST_TEST_EQ( std::get<2>(s).value, 10 );
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
std::pair<T<1>, T<2>> tp;
|
||||
std::pair<T<3>, T<4>> tp2;
|
||||
|
||||
{
|
||||
std::tuple<T<2>, T<3>> s = tuple_transform( F{}, tp );
|
||||
BOOST_TEST_EQ( std::get<0>(s).value, 3 );
|
||||
BOOST_TEST_EQ( std::get<1>(s).value, 4 );
|
||||
}
|
||||
|
||||
{
|
||||
std::tuple<T<2>, T<3>> s = tuple_transform( F{}, std::move(tp) );
|
||||
BOOST_TEST_EQ( std::get<0>(s).value, 3 );
|
||||
BOOST_TEST_EQ( std::get<1>(s).value, 4 );
|
||||
}
|
||||
|
||||
{
|
||||
std::tuple<T<4>, T<6>> s = tuple_transform( F{}, tp, tp2 );
|
||||
BOOST_TEST_EQ( std::get<0>(s).value, 5 );
|
||||
BOOST_TEST_EQ( std::get<1>(s).value, 7 );
|
||||
}
|
||||
|
||||
{
|
||||
std::tuple<T<4>, T<6>> s = tuple_transform(
|
||||
F{}, std::move(tp), std::move(tp2)
|
||||
);
|
||||
BOOST_TEST_EQ( std::get<0>(s).value, 5 );
|
||||
BOOST_TEST_EQ( std::get<1>(s).value, 7 );
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
std::pair<T<1>, T<2>> const tp;
|
||||
std::pair<T<3>, T<4>> const tp2;
|
||||
|
||||
{
|
||||
std::tuple<T<2>, T<3>> s = tuple_transform( F{}, tp );
|
||||
BOOST_TEST_EQ( std::get<0>(s).value, 3 );
|
||||
BOOST_TEST_EQ( std::get<1>(s).value, 4 );
|
||||
}
|
||||
|
||||
{
|
||||
std::tuple<T<2>, T<3>> s = tuple_transform( F{}, std::move(tp) );
|
||||
BOOST_TEST_EQ( std::get<0>(s).value, 3 );
|
||||
BOOST_TEST_EQ( std::get<1>(s).value, 4 );
|
||||
}
|
||||
|
||||
{
|
||||
std::tuple<T<4>, T<6>> s = tuple_transform( F{}, tp, tp2 );
|
||||
BOOST_TEST_EQ( std::get<0>(s).value, 5 );
|
||||
BOOST_TEST_EQ( std::get<1>(s).value, 7 );
|
||||
}
|
||||
|
||||
{
|
||||
std::tuple<T<4>, T<6>> s = tuple_transform(
|
||||
F{}, std::move(tp), std::move(tp2)
|
||||
);
|
||||
BOOST_TEST_EQ( std::get<0>(s).value, 5 );
|
||||
BOOST_TEST_EQ( std::get<1>(s).value, 7 );
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
std::tuple<> tp;
|
||||
|
||||
{
|
||||
auto s = tuple_transform( F{}, tp );
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(s), std::tuple<>>));
|
||||
}
|
||||
|
||||
{
|
||||
auto s = tuple_transform( F{}, std::move(tp) );
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<decltype(s), std::tuple<>>));
|
||||
}
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
166
test/tuple_transform_2.cpp
Normal file
166
test/tuple_transform_2.cpp
Normal file
@ -0,0 +1,166 @@
|
||||
// Copyright 2020 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/tuple.hpp>
|
||||
#include <boost/mp11/algorithm.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
|
||||
int f( int x )
|
||||
{
|
||||
return x + 1;
|
||||
}
|
||||
|
||||
int g( int x, int y )
|
||||
{
|
||||
return x + y;
|
||||
}
|
||||
|
||||
int h( int x, int y, int z )
|
||||
{
|
||||
return x + y + z;
|
||||
}
|
||||
|
||||
int q( int x, int y, int z, int v )
|
||||
{
|
||||
return x + y + z + v;
|
||||
}
|
||||
|
||||
template<class T1, class... T> std::array<T1, 1 + sizeof...(T)> make_array( T1 t1, T... t )
|
||||
{
|
||||
return { { t1, t... } };
|
||||
}
|
||||
|
||||
template<class Tp> struct test_element
|
||||
{
|
||||
Tp& tp;
|
||||
|
||||
template<int I> void operator()( boost::mp11::mp_int<I> ) const
|
||||
{
|
||||
BOOST_TEST_EQ( std::get<I>( tp ), q( I, I, I, I ) );
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
using boost::mp11::tuple_transform;
|
||||
|
||||
//
|
||||
|
||||
{
|
||||
std::tuple<int> r = tuple_transform( f, std::make_tuple( 1 ) );
|
||||
|
||||
BOOST_TEST_EQ( std::get<0>( r ), 2 );
|
||||
}
|
||||
|
||||
{
|
||||
std::tuple<int> r = tuple_transform( f, ::make_array( 1 ) );
|
||||
|
||||
BOOST_TEST_EQ( std::get<0>( r ), 2 );
|
||||
}
|
||||
|
||||
{
|
||||
std::tuple<int> r = tuple_transform( g, ::make_array( 1 ), std::make_tuple( 2 ) );
|
||||
|
||||
BOOST_TEST_EQ( std::get<0>( r ), 3 );
|
||||
}
|
||||
|
||||
{
|
||||
std::tuple<int> r = tuple_transform( h, ::make_array( 1 ), std::make_tuple( 2 ), ::make_array( 3 ) );
|
||||
|
||||
BOOST_TEST_EQ( std::get<0>( r ), 6 );
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
{
|
||||
std::tuple<int, int> r = tuple_transform( f, std::make_tuple( 1, 2 ) );
|
||||
|
||||
BOOST_TEST_EQ( std::get<0>( r ), 2 );
|
||||
BOOST_TEST_EQ( std::get<1>( r ), 3 );
|
||||
}
|
||||
|
||||
{
|
||||
std::tuple<int, int> r = tuple_transform( f, std::make_pair( 1, 2 ) );
|
||||
|
||||
BOOST_TEST_EQ( std::get<0>( r ), 2 );
|
||||
BOOST_TEST_EQ( std::get<1>( r ), 3 );
|
||||
}
|
||||
|
||||
{
|
||||
std::tuple<int, int> r = tuple_transform( f, ::make_array( 1, 2 ) );
|
||||
|
||||
BOOST_TEST_EQ( std::get<0>( r ), 2 );
|
||||
BOOST_TEST_EQ( std::get<1>( r ), 3 );
|
||||
}
|
||||
|
||||
{
|
||||
std::tuple<int, int> r = tuple_transform( g, ::make_array( 1, 2 ), std::make_pair( 3, 4 ) );
|
||||
|
||||
BOOST_TEST_EQ( std::get<0>( r ), 4 );
|
||||
BOOST_TEST_EQ( std::get<1>( r ), 6 );
|
||||
}
|
||||
|
||||
{
|
||||
std::tuple<int, int> r = tuple_transform( h, ::make_array( 1, 2 ), std::make_pair( 3, 4 ), std::make_tuple( 5, 6 ) );
|
||||
|
||||
BOOST_TEST_EQ( std::get<0>( r ), 9 );
|
||||
BOOST_TEST_EQ( std::get<1>( r ), 12 );
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
{
|
||||
std::tuple<int, int, int> r = tuple_transform( f, std::make_tuple( 1, 2, 3 ) );
|
||||
|
||||
BOOST_TEST_EQ( std::get<0>( r ), 2 );
|
||||
BOOST_TEST_EQ( std::get<1>( r ), 3 );
|
||||
BOOST_TEST_EQ( std::get<2>( r ), 4 );
|
||||
}
|
||||
|
||||
{
|
||||
std::tuple<int, int, int> r = tuple_transform( f, ::make_array( 1, 2, 3 ) );
|
||||
|
||||
BOOST_TEST_EQ( std::get<0>( r ), 2 );
|
||||
BOOST_TEST_EQ( std::get<1>( r ), 3 );
|
||||
BOOST_TEST_EQ( std::get<2>( r ), 4 );
|
||||
}
|
||||
|
||||
{
|
||||
std::tuple<int, int, int> r = tuple_transform( g, ::make_array( 1, 2, 3 ), std::make_tuple( 4, 5, 6 ) );
|
||||
|
||||
BOOST_TEST_EQ( std::get<0>( r ), 5 );
|
||||
BOOST_TEST_EQ( std::get<1>( r ), 7 );
|
||||
BOOST_TEST_EQ( std::get<2>( r ), 9 );
|
||||
}
|
||||
|
||||
{
|
||||
std::tuple<int, int, int> r = tuple_transform( h, ::make_array( 1, 2, 3 ), std::make_tuple( 4, 5, 6 ), ::make_array( 7, 8, 9 ) );
|
||||
|
||||
BOOST_TEST_EQ( std::get<0>( r ), 12 );
|
||||
BOOST_TEST_EQ( std::get<1>( r ), 15 );
|
||||
BOOST_TEST_EQ( std::get<2>( r ), 18 );
|
||||
}
|
||||
|
||||
#if !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1900 )
|
||||
|
||||
{
|
||||
using namespace boost::mp11;
|
||||
|
||||
int const N = 12;
|
||||
|
||||
using Tp = mp_rename<mp_iota< mp_int<N> >, std::tuple>;
|
||||
|
||||
auto const r = tuple_transform( q, Tp(), Tp(), Tp(), Tp() );
|
||||
|
||||
mp_for_each<Tp>( test_element<decltype(r)>{ r } );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
65
test/tuple_transform_cx.cpp
Normal file
65
test/tuple_transform_cx.cpp
Normal file
@ -0,0 +1,65 @@
|
||||
// Copyright 2015, 2020 Peter Dimov
|
||||
// Copyright 2020 Hans Dembinski
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/tuple.hpp>
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
|
||||
// Technically std::tuple isn't constexpr enabled in C++11, but it works with libstdc++
|
||||
|
||||
#if defined( BOOST_MP11_NO_CONSTEXPR ) || ( !defined(_MSC_VER) && !defined( __GLIBCXX__ ) && __cplusplus < 201400L ) || BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, < 40800 )
|
||||
|
||||
int main() {}
|
||||
|
||||
#else
|
||||
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
constexpr int f( int x )
|
||||
{
|
||||
return x + 1;
|
||||
}
|
||||
|
||||
constexpr int g( int x, int y )
|
||||
{
|
||||
return x + y + 1;
|
||||
}
|
||||
|
||||
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
constexpr std::tuple<int, int, int> tp( 1, 2, 3 );
|
||||
|
||||
constexpr auto r = boost::mp11::tuple_transform( f, tp );
|
||||
|
||||
STATIC_ASSERT( r == std::make_tuple( 2, 3, 4 ) );
|
||||
}
|
||||
|
||||
{
|
||||
constexpr std::tuple<int, int> tp1( 1, 2 );
|
||||
constexpr std::pair<int, int> tp2( 3, 4 );
|
||||
|
||||
constexpr auto r = boost::mp11::tuple_transform( g, tp1, tp2 );
|
||||
|
||||
STATIC_ASSERT( r == std::make_tuple( 5, 7 ) );
|
||||
}
|
||||
|
||||
#if defined( __clang_major__ ) && __clang_major__ == 3 && __clang_minor__ < 9
|
||||
// "error: default initialization of an object of const type 'const std::tuple<>' without a user-provided default constructor"
|
||||
#else
|
||||
|
||||
{
|
||||
constexpr std::tuple<> tp;
|
||||
constexpr std::tuple<> r = boost::mp11::tuple_transform( f, tp );
|
||||
(void)r;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
1
tools/single-header.bat
Normal file
1
tools/single-header.bat
Normal file
@ -0,0 +1 @@
|
||||
python2.7 tools\single-header.py > include\boost\mp11_single.hpp
|
54
tools/single-header.py
Normal file
54
tools/single-header.py
Normal file
@ -0,0 +1,54 @@
|
||||
|
||||
# Copyright 2017 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
|
||||
|
||||
import os.path
|
||||
import re
|
||||
import sys
|
||||
|
||||
included = []
|
||||
|
||||
def scan_header( prefix, dir, fn ):
|
||||
|
||||
path = os.path.join( prefix, dir, fn )
|
||||
|
||||
if path in included:
|
||||
|
||||
return
|
||||
|
||||
included.append( path )
|
||||
|
||||
with open( path, 'r' ) as header:
|
||||
|
||||
for line in header:
|
||||
|
||||
m = re.match( '[ \t]*#[ \t]*include[ \t]*(["<])([^">]*)[">]', line )
|
||||
|
||||
r = False
|
||||
|
||||
if m:
|
||||
|
||||
h = m.group( 2 )
|
||||
|
||||
hfn1 = os.path.join( prefix, h )
|
||||
hfn2 = os.path.join( prefix, dir, h )
|
||||
|
||||
if m.group( 1 ) == '"' and os.path.exists( hfn2 ):
|
||||
|
||||
scan_header( prefix, os.path.join( dir, os.path.dirname( hfn2 ) ), os.path.basename( hfn2 ) )
|
||||
r = True
|
||||
|
||||
elif os.path.exists( hfn1 ):
|
||||
|
||||
scan_header( prefix, os.path.dirname( h ), os.path.basename( h ) )
|
||||
r = True
|
||||
|
||||
if not r:
|
||||
|
||||
sys.stdout.write( line )
|
||||
|
||||
scan_header( 'include', 'boost', 'mp11.hpp' )
|
Reference in New Issue
Block a user