Compare commits

...

237 Commits

Author SHA1 Message Date
fb8490e37c glob headers 2022-07-05 10:48:23 +02:00
015adf50a6 Rework as esp-idf component 2022-07-04 19:41:47 +02:00
590df5e0bc Remove msvc-14.1 from GHA; add clang-win 2022-04-14 16:16:37 +03:00
8faca18e01 Update ci.yml 2022-04-14 14:23:57 +03:00
4ce658d221 Update version 2022-04-14 14:14:13 +03:00
8b8c569cb9 Update version 2022-04-14 13:43:44 +03:00
7bc4e1ae9b Merge pull request #71 from grisumbras/feature/mp_valid_and_true
implement mp_valid_and_true
2022-02-17 00:12:05 +02:00
1336c4f9c3 implement mp_valid_and_true 2022-02-16 20:48:26 +03:00
28036d0bdb Update appveyor.yml 2021-12-22 20:35:47 +02:00
44ca553edb Remove msvc-14.0 from GHA, fails with 'out of heap space' 2021-12-22 07:54:58 +02:00
219c8c1027 Add msvc-14.0 to GHA 2021-12-22 07:04:24 +02:00
edba135739 Use unqualified get<I> instead of std::get<I> (refs #69) 2021-12-14 20:20:44 +02:00
df5e51c667 Update version 2021-12-09 04:51:01 +02:00
40a25aab6b Update version 2021-12-09 04:06:57 +02:00
d15c63c0a6 Merge branch 'feature/gha-cuda' into feature/issue-68 2021-11-18 22:18:07 +02:00
a1e6106e89 Update ci.yml 2021-11-18 22:17:56 +02:00
ae1bb087cb Merge branch 'feature/gha-cuda' into feature/issue-68 2021-11-18 19:52:57 +02:00
f471bf4997 Update ci.yml 2021-11-18 19:52:17 +02:00
4db9263091 Merge branch 'feature/gha-cuda' into feature/issue-68 2021-11-18 19:51:16 +02:00
8e883ae9e7 Update ci.yml 2021-11-18 19:34:11 +02:00
e364f2575e Merge branch 'feature/gha-cuda' into feature/issue-68 2021-11-18 18:49:49 +02:00
86121bb76b Update ci.yml 2021-11-18 18:23:03 +02:00
de09706e79 Update ci.yml 2021-11-18 18:03:53 +02:00
a01908774a Update ci.yml 2021-11-18 15:56:27 +02:00
8bece6d0a6 Update ci.yml 2021-11-18 15:45:33 +02:00
6781db002b Update ci.yml 2021-11-18 15:29:25 +02:00
754af95379 Update ci.yml 2021-11-18 15:18:37 +02:00
b2365dd68d Add cuda-linux, cuda-windows jobs to ci.yml 2021-11-18 14:23:03 +02:00
a4d7c46670 Define host compiler macro when using CUDA (refs #68) 2021-11-18 14:08:33 +02:00
df1cb655be Fetch static_assert and throw_exception when testing standalone 2021-10-28 22:35:00 +03:00
91ac80468e Add msvc-14.3 to ci.yml 2021-10-28 21:56:29 +03:00
c32d86f224 Enable syntax highlighting 2021-10-28 21:55:12 +03:00
2ae1c458a6 Update example caption 2021-10-28 21:53:20 +03:00
151bf2aa2a Merge pull request #66 from bernhardmgruber/mpl
Document how to convert an MPL sequence into an mp_list
2021-10-28 21:48:18 +03:00
48f5b642aa Update appveyor.yml 2021-10-08 18:14:34 +03:00
c8bff426ec Do not use -DBOOST_INCLUDE_LIBRARIES in standalone ci.yml jobs 2021-10-08 17:02:45 +03:00
8cee5a4ce0 Add standalone CMake jobs to ci.yml 2021-10-08 16:29:58 +03:00
294fc9335e Set BUILD_TESTING to OFF by default 2021-10-08 16:29:40 +03:00
c4e2259c8f Move BoostInstall call inside the root project section 2021-10-08 16:22:09 +03:00
fc1a347d57 Add CMake jobs to ci.yml 2021-10-08 07:43:54 +03:00
891b4ddd88 document how to convert an MPL sequence into an mp_list 2021-09-14 21:36:40 +02:00
28a9ff62f1 Update README.md 2021-09-11 15:24:50 +03:00
cfdda0378b Remove ubuntu-16.04 from ci.yml 2021-09-11 15:21:45 +03:00
758d51b4c0 Remove unnecessary include 2021-08-21 15:10:07 +03:00
f8206aa37d Remove unnecessary includes 2021-08-21 15:08:21 +03:00
ce1046f007 Remove unnecessary include 2021-08-21 15:06:10 +03:00
3d8901bf8b Merge branch 'feature/nary-compose' of https://github.com/grisumbras/mp11 into feature/pr-64 2021-08-21 15:01:02 +03:00
f081f3e516 Update ci.yml 2021-08-17 15:49:42 +03:00
5954168980 Update version 2021-08-17 15:14:34 +03:00
f4b3414e62 Add support for n-ary functions to mp_compose 2021-07-27 08:39:01 +03:00
8cd25cc950 Put mp_rename, mp_apply into their own file 2021-07-27 08:38:29 +03:00
7b854477f8 Put mp_front into its own file 2021-07-27 08:33:01 +03:00
9d43d1f696 Update appveyor.yml 2021-06-13 18:17:13 +03:00
20aa0f9dcd Update ci.yml 2021-06-13 02:52:14 +03:00
c3aed9a44f Update ci.yml 2021-06-13 02:03:19 +03:00
ab2ed40371 Update .travis.yml 2021-06-13 01:16:58 +03:00
ec581685d8 Update GHA ci.yml 2021-04-17 20:12:42 +03:00
03fbf117f3 Update version 2021-04-17 19:47:34 +03:00
575b858a9b Update version 2021-04-17 19:14:14 +03:00
7694815d7b Switch msvc-14.0 to VS2017 image 2021-03-25 06:17:23 +02:00
b7295ee2c3 Add xcode 11.6, 12.2 to Travis 2021-03-24 21:29:58 +02:00
680d5e6396 Disable g++-4.7 warning 2021-03-24 19:10:53 +02:00
6fdfb5bde8 Avoid g++-10 warning about < 0 compare 2021-03-24 18:59:09 +02:00
531a8d173e Enable -Wextra in test/Jamfile 2021-03-24 18:14:50 +02:00
091648424d Split msvc-12.0 and msvc-14.0 in appveyor.yml 2021-03-23 16:09:38 +02:00
9215c68d35 Implement mp_any in terms of mp_count 2021-03-23 03:11:03 +02:00
ae4c83c8a6 Implement mp_all in terms of mp_count 2021-03-23 02:55:45 +02:00
598a40644e Change mp_same to use mp_count instead of mp_all 2021-03-23 00:29:57 +02:00
76f68d09a0 Test mp_any with N=1089 2021-03-22 20:04:10 +02:00
a07cc9062f Test mp_all with N=1089 2021-03-22 20:00:46 +02:00
2132bae540 Test mp_none_of with N=1089 2021-03-22 19:51:02 +02:00
e893d535f1 Test mp_any_of with N=1089 2021-03-22 19:44:51 +02:00
7749432254 Test mp_all_of with N=1089 2021-03-22 19:42:08 +02:00
c92d2d0b6f No longer use fold expressions for mp_count_if to avoid compiler limits 2021-03-22 19:17:44 +02:00
0348adbed9 No longer use fold expressions for mp_count to avoid compiler limits 2021-03-22 18:37:46 +02:00
b6451c4ae4 Add -DBUILD_TESTING=ON to .yml files; it's not default anymore 2021-03-19 04:12:10 +02:00
085980c876 Update revision history 2021-03-12 19:21:15 +02:00
47cf2e9a5f Merge branch 'feature/travis-clang-bionic' into develop 2021-03-12 19:18:21 +02:00
b08452c21c Switch failing clangs to bionic 2021-03-12 08:05:30 +02:00
50382f0127 Merge branch 'feature/mp_intersperse' into feature/mp_split 2021-03-12 07:11:01 +02:00
5babdec063 Fix typo in VS2013 workaround 2021-03-12 07:10:41 +02:00
c7dbff81e5 Document mp_join 2021-03-12 06:41:59 +02:00
e7f2e7a45d Add mp_join 2021-03-12 06:35:11 +02:00
d669ed844c Document mp_split 2021-03-12 06:25:43 +02:00
0837acfde1 Add mp_split (refs #59) 2021-03-12 06:18:45 +02:00
4a1f343dbc Add VS2013 workaround 2021-03-12 04:55:25 +02:00
0075288002 Document mp_intersperse 2021-03-12 04:34:42 +02:00
080c3437ed Add mp_intersperse 2021-03-12 04:27:50 +02:00
0dea2f1a2b Expand mp_for_each note slightly 2021-03-04 20:15:30 +02:00
a0658d7797 Merge pull request #58 from bernhardmgruber/foreach
Add a note to mp_for_each for lists with elements which are not default-constructible
2021-03-04 20:12:23 +02:00
09780a6df8 Add a note to mp_for_each for lists with elements which are not default-constructible 2021-03-04 12:46:48 +01:00
2d709e5639 Update ci.yml 2020-12-23 07:13:43 +02:00
bfeef9e50e Merge pull request #57 from eldiener/develop
Add "cxxstd" json field. The "cxxstd" json field is being added to ea…
2020-12-16 18:44:41 +02:00
f257a448a4 Add "cxxstd" json field. The "cxxstd" json field is being added to each Boost library's meta json information for libraries whose minumum C++ standard compilation level is C++11 on up. The value of this field matches one of the values for 'cxxstd' in Boost.Build. The purpose of doing this is to provide information for the Boost website documentation for each library which will specify the minimum C++ standard compilation that an end-user must employ in order to use the particular library. This will aid end-users who want to know if they can successfully use a Boost library based on their C++ compiler's compilation level, without having to search the library's documentation to find this out. 2020-12-15 21:51:31 -05:00
e81291318c Update version 2020-12-14 03:34:16 +02:00
586a485325 Update maintainer e-mail 2020-12-12 01:03:32 +02:00
6d51a12e57 Remove -std=c++1z from clang 3.x 2020-11-26 03:34:52 +02:00
1524f2587b Add Clang palette to GHA 2020-11-26 03:21:58 +02:00
064e9d415b mp_count: do not use fold expressions on msvc because of parser stack limit 2020-11-26 02:14:59 +02:00
37adad6624 test/mp_count: test N=1089 2020-11-26 01:22:15 +02:00
6bb260ff65 mp_count_if: do not use fold expressions on msvc-14.2 because of parser stack limit 2020-11-26 00:23:13 +02:00
90f40dd999 Add a test for mp_count_if with N=1089 2020-11-25 22:22:24 +02:00
4349457f84 Increase N to 1089 in test/mp_same 2020-11-25 22:22:24 +02:00
bbb73a9025 Add .github/workflows 2020-11-25 21:46:14 +02:00
21cace4e57 Remove mp_invoke 2020-10-20 00:08:11 +03:00
727ecfc0cf Update mp_pairwise_fold_q test and example 2020-10-17 16:54:06 +03:00
28a736954f Update revision history 2020-10-13 21:32:40 +03:00
8a2e945417 Document mp_pairwise_fold 2020-10-13 17:53:12 +03:00
02d185fce9 Split msvc-14.2,clang-win to avoid timeout 2020-10-13 05:04:09 +03:00
e4f789b0cc Use embed-manifest-via=linker 2020-10-13 04:47:00 +03:00
697e3e40a3 Add cxxstd=latest, toolset=clang-win to VS2019 2020-10-13 03:25:40 +03:00
db78dc101c Add mp_pairwise_fold 2020-10-12 22:12:42 +03:00
0a12995d9d Make links release-independent 2020-09-14 00:46:52 +03:00
2b0b900938 Updated README.md - Fixed broken links (#56) 2020-09-14 00:44:53 +03:00
a069fdcce6 Update version.hpp 2020-08-22 19:59:26 +03:00
3f316ae626 Update version in CMakeLists.txt 2020-08-22 19:34:28 +03:00
4515938bbd Work around std::tuple MSVC issue with mp_map_find (fixes #52) 2020-07-25 01:56:00 +03:00
637c586e02 Add test/mp_map_find_3 2020-07-25 01:54:49 +03:00
4fb4837f92 Add mp_map_find_test_2 (refs #52) 2020-07-21 20:23:36 +03:00
29764aad48 Remove trailing whitespace 2020-06-11 16:40:34 +03:00
10ba80acb9 Add support for mp_product<F> 2020-06-03 15:08:49 +03:00
d709610087 Re-remove mp11_single.hpp 2020-05-24 18:52:49 +03:00
f26810ef47 Revert "Remove single header"
This reverts commit f24d1ca5df.
2020-05-24 18:52:08 +03:00
645c90b11d Enable constexpr tests on msvc-14.2 (where __cplusplus is still 199711L) 2020-05-24 06:55:02 +03:00
44be76e9b6 Disable test/tuple_transform_cx on g++ 4.7 2020-05-24 06:50:02 +03:00
1ffb98882d Lower N further in test/tuple_transform_2 for clang++ 3.x 2020-05-24 06:43:43 +03:00
49afe16b55 Lower N in test/tuple_transform_2 for g++ 4.9 2020-05-24 06:15:35 +03:00
e653eb3e8b Use an internal forward_from_tuple as the std:: one isn't constexpr in C++11 or libstdc++ 5 2020-05-24 06:14:18 +03:00
588bc4458a Update documentation of tuple_for_each 2020-05-24 04:36:29 +03:00
cad3c61045 Update documentation of tuple_transform 2020-05-24 04:35:32 +03:00
348166471e Update changelog 2020-05-24 03:06:47 +03:00
a0ea1055d2 Support up to three tuples in tuple_transform under msvc-12.0 2020-05-24 01:14:46 +03:00
917ac15ee1 Restrict msvc-12.0 to one tuple in tuple_transform 2020-05-24 00:56:43 +03:00
857ba905e4 Merge branch 'develop' into feature/tuple-transform 2020-05-23 22:07:27 +03:00
3427d716c6 Update examples.adoc 2020-05-23 22:05:51 +03:00
35a86da178 Revert "for std::decay fix, anchor and cross-reference tuple-cat fix more accurately"
This reverts commit 742980e533.
2020-05-23 21:48:41 +03:00
b3fa2c4de0 Merge branch 'develop' of https://github.com/slymz/mp11 into feature/pr-48 2020-05-23 21:47:50 +03:00
9349a82e6b Add test/tuple_transform_2.cpp 2020-05-23 21:13:35 +03:00
0ee00ee64a Check that all arguments to tuple_transform are of the same size 2020-05-23 20:42:57 +03:00
a8f6fa891f Update test/tuple_transform_cx 2020-05-23 20:12:27 +03:00
c51f83c25a Replace implementation of tuple_transform 2020-05-23 20:00:12 +03:00
dcf0d7ebdf Squash-merge PR #50 2020-05-23 19:16:07 +03:00
b07eb08a2f Update revision history 2020-05-10 14:20:19 +03:00
13c36a793c Improve compilation performance of mp_with_index<N> for large N 2020-05-09 17:32:03 +03:00
0198b6e5a7 Add gcc-10, clang-10 to Travis 2020-05-09 05:17:21 +03:00
742980e533 for std::decay fix, anchor and cross-reference tuple-cat fix more accurately 2020-05-06 18:27:35 -04:00
2e6c2abcde Updated docs "Computing Return Types"
- Suggests `std::invoke_result` as an in place modern alternative for `Qret`.
- Fixes a bug with `const` variant types using `std::decay_t` instead of `std::remove_reference_t`.
2020-05-06 18:15:28 -04:00
6c1628b713 Update Mp11 version 2020-05-01 01:27:26 +03:00
e984111860 Update Boost version 2020-04-30 18:30:34 +03:00
7debd787dd Document mp_iterate 2020-03-23 02:59:00 +02:00
91c6f556cd Merge branch 'develop' into feature/mp_iterate 2020-03-23 02:30:09 +02:00
cb2705df26 Override the default BoostInstall layout on Windows when standalone 2020-03-22 20:17:39 +02:00
984da7f1a1 Add mp_iterate 2020-03-22 18:50:55 +02:00
20ea61df94 Remove time-consuming inessential Appveyor jobs 2020-03-20 01:40:59 +02:00
59d8f1b3d7 Add more Appveyor configurations temporarily to evaluate how much time they take 2020-03-19 21:50:55 +02:00
5267548813 Document mp_partial_sum 2020-03-19 19:35:02 +02:00
e9684a1f66 Apply a workaround for msvc-12.0, msvc-14.0 2020-03-19 17:36:20 +02:00
6bc2682936 Add mp_partial_sum 2020-03-19 17:25:03 +02:00
a7a2c97383 Document mp_power_set 2020-03-19 16:31:52 +02:00
2c8ce53efb Apply a workaround for msvc-12.0 2020-03-19 16:11:39 +02:00
64b9c1f874 Add mp_power_set 2020-03-19 15:04:52 +02:00
0851643af5 Change mp_invoke on Clang to use a struct, because deprecated alias templates never warn 2020-03-09 19:59:19 +02:00
c806f70b73 Prefer __attribute__((deprecated)) on all g++-compatible compilers (f.ex. Intel) 2020-03-08 18:14:01 +02:00
c89fd0b7e0 Update documentation of mp_compose_q 2020-03-08 07:05:22 +02:00
03c221f2d5 Do not use Q::template fn... because it breaks g++ < 7 and nvcc 2020-03-08 06:43:48 +02:00
de026d8322 Document mp_compose 2020-03-08 02:44:09 +02:00
5d25ec4ad8 Add mp_compose 2020-03-08 02:33:56 +02:00
1f634c7071 Do not use __builtin_unreachable() when not on g++ or clang. Fixes #46. 2020-03-01 01:19:58 +02:00
f321b05926 Update revision history 2020-01-31 15:35:10 +02:00
66681de1ed Added fix for Sun Studio compilations. (#45)
* Added fix for Sun Studio compilations.

* Update config.hpp
2020-01-28 15:28:18 -08:00
2b0d107844 Document mp_rotate_* 2020-01-18 20:25:08 +02:00
4e177f73ae Simplify mp_rotate_impl 2020-01-18 20:15:05 +02:00
8ef7658518 Implement mp_rotate_right in terms of mp_rotate_left 2020-01-18 18:44:43 +02:00
d3f0738bf4 mp_rotate_*: remove default rotation count 2020-01-18 18:31:06 +02:00
03f6096230 Merge branch 'feature/add-rotate-algorithms' of https://github.com/D-Barber/mp11 into feature/mp_rotate 2020-01-18 18:18:03 +02:00
f5dbff1379 Update README 2020-01-05 14:24:10 +02:00
b0b33a4fcf Change Travis labels 2019-12-29 20:46:35 +02:00
392151cdc9 Use -DBOOST_INCLUDE_LIBRARIES=mp11 2019-12-29 19:16:10 +02:00
64b2e12971 Use LINK_LIBRARIES instead of LIBRARIES 2019-12-29 18:44:21 +02:00
7ff533876c Switch Travis to Xenial 2019-12-28 00:01:27 +02:00
2d65367919 Add subdir, install CMake tests to Appveyor 2019-12-27 06:56:37 +02:00
3f07d53041 Update CMakeLists.txt 2019-12-27 03:50:12 +02:00
87ab394510 Fetch BoostFetch.cmake from boostorg/cmake 2019-12-27 03:46:56 +02:00
22fc4198e5 Add missing copyright/license preambles 2019-12-27 00:46:51 +02:00
d48d5c8708 Install the include/ directory separately 2019-12-22 08:33:53 +02:00
bbb6f3aa84 Fetch tools/cmake from develop 2019-12-22 03:59:24 +02:00
3afdb0e876 Fetch tools/cmake instead of having a duplicate 2019-12-22 03:08:58 +02:00
054f576d14 Add mp_rotate_left and mp_rotate_right 2019-12-21 22:21:47 +00:00
2deeac36b4 Update BoostMessage.cmake 2019-12-21 21:49:03 +02:00
2afc07f189 Update copyright 2019-12-21 16:28:12 +02:00
6b2b305117 Update .cmake files 2019-12-21 15:50:29 +02:00
219cf35ea8 Simplify CMake Appveyor jobs 2019-12-21 05:01:02 +02:00
33bf90a050 Add superproject CMake tests to Travis and Appveyor 2019-12-21 01:57:01 +02:00
bf655dd4c9 Update test CMakeLists files 2019-12-21 01:31:28 +02:00
868dcae683 Use the local BoostFetch 2019-12-21 01:29:25 +02:00
3b4814a91c Add EXCLUDE_FROM_ALL option to boost_fetch 2019-12-21 01:26:11 +02:00
e73693b588 Add BoostFetch.cmake 2019-12-21 01:20:45 +02:00
d5e4dda1b4 Update CMakeLists.txt acc. to latest superproject fashion 2019-12-21 01:18:26 +02:00
ea37a24f98 Disable warnings exposed by address-model=64 2019-12-18 01:00:11 +02:00
49edfceea2 Add msvc-14.2, clang-win, address-model=32,64, variant=debug,release to Appveyor 2019-12-18 00:30:47 +02:00
85fb466414 Update version to 1.73.0 2019-12-12 21:28:41 +02:00
b53bab4b7d Fix mp_transform examples 2019-12-08 05:44:33 +02:00
a1ada99d10 Fix mp_invoke_q examples 2019-12-08 05:28:07 +02:00
3425d6bb00 Fix mp_eval_if_c example; add one for mp_eval_or 2019-12-08 05:22:04 +02:00
25cbde3f91 Update revision history 2019-12-08 03:21:56 +02:00
cd2c492be7 Document mp_flatten 2019-12-08 03:20:59 +02:00
b24d2285a6 Add mp_flatten 2019-12-08 02:08:26 +02:00
f14309e92d Fix ambiguity in mp_similar<Y<>, Y<>> 2019-12-08 02:07:17 +02:00
4a8a049a3e Update revision history 2019-12-07 22:01:57 +02:00
3efbc9d3cd Suppress -Wsign-compare on g++ 4.7 more forcefully 2019-12-07 21:58:51 +02:00
76442f9120 Add clang-9 to Travis 2019-12-07 21:08:57 +02:00
4f91ee2e96 Suppress -Wsign-compare on g++ 4.7 2019-12-07 21:01:25 +02:00
523c23619c Use a better msvc-12/14 workaround in test/mp_unique_if.cpp 2019-12-07 20:52:18 +02:00
6a2e8e8384 Update test/mp_unique_if_q.cpp 2019-12-07 20:33:37 +02:00
d151f9a712 Update test/mp_unique_if.cpp 2019-12-07 20:32:16 +02:00
409147714c Reformat mp_unique_if 2019-12-07 19:13:02 +02:00
1542a0c388 Fix documentation of mp_unique_if, mp_unique_if_q 2019-12-07 19:05:21 +02:00
aa11577812 🆕 [mp_unique_if] Support for mp_unique with a predicate
Problem:
- `mp_unique` doesn't support custom predicates.

Solution:
- Add `mp_unique_if` and `mp_unique_if_q` which allow to remove duplicates elements with a predicate.
2019-12-03 15:12:55 -07:00
f64bc319c0 Update version in CMakeLists.txt 2019-08-24 01:45:38 +03:00
ed5dc75e18 Update BOOST_MP11_VERSION 2019-08-24 00:46:26 +03:00
8b0ab6130d Update footer for Asciidoctor 2 2019-08-23 21:02:55 +03:00
900a0c842e Update documentation for mpl.hpp 2019-08-23 21:02:37 +03:00
0ca69d98c9 Add test/mpl_tuple.cpp 2019-08-23 20:51:13 +03:00
85a2099874 Add test/mpl_list.cpp 2019-08-23 20:49:51 +03:00
164aa375f2 Split mpl.hpp into mpl_list.hpp and mpl_tuple.hpp 2019-08-23 20:02:00 +03:00
b23b97856c Add gcc9, clang8 to Travis 2019-06-18 11:53:48 +03:00
9bd902c1c9 Add dist: trusty to .travis.yml 2019-06-18 11:52:22 +03:00
d0e6e29abb Fix mp_with_index example 2019-06-02 17:52:04 +03:00
bf6f3e0221 Clang 3.3 can't parse __attribute__((deprecated)) on aliases 2019-05-25 03:40:23 +03:00
23a1432e8d Use __attribute__((deprecated)) on Clang because of -pedantic 2019-05-25 02:24:47 +03:00
45cc05a298 Merge pull request #35 from foonathan/patch-2
Fix GCC sign conversion warning
2019-05-22 06:19:56 -07:00
bba027610f Fix GCC sign conversion warning
The conversion bool -> int -> std::size_t triggers GCC sign conversion warning.
2019-05-22 11:03:50 +02:00
cb15f6b94e Update GCC workarounds 2019-05-10 18:42:54 +03:00
d03c53a693 Update project version in CMakeLists.txt 2019-04-19 00:35:25 +03:00
417e0db55a test/mp_for_each: Disable warning 4307 on MSVC 2019-04-18 09:49:00 +03:00
f1ededad7a Update BOOST_MP11_VERSION 2019-04-18 09:48:18 +03:00
fd1b8081b7 Switch Appveyor to 2015 image 2019-04-14 18:26:35 +03:00
75 changed files with 3867 additions and 409 deletions

502
.github/workflows/ci.yml vendored Normal file
View 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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -15,6 +15,8 @@ Peter Dimov
:listing-caption: Code Example
:table-caption: Illustration
:docinfo: private-footer
:source-highlighter: rouge
:source-language: c++
:leveloffset: +1

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View 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

View File

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

View 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

View File

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

View 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

View File

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

View File

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

View File

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

View 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

View 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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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
View 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();
}

View File

@ -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
View 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();
}

View File

@ -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
View 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();
}

View File

@ -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();
}

View File

@ -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
View 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();
}

View File

@ -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
View 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
View 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
View 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
View 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
View 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();
}

View File

@ -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
View 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();
}

View 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
View 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
View 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();
}

View File

@ -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
View 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
View 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();
}

View File

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

View File

@ -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
View 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
View 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
View 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();
}

View 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();
}

View File

@ -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
View 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
View 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();
}

View File

@ -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() {}

View File

@ -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
View 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
View 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();
}

View 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
View File

@ -0,0 +1 @@
python2.7 tools\single-header.py > include\boost\mp11_single.hpp

54
tools/single-header.py Normal file
View 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' )