├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ ├── documentation.yml │ ├── integration.yml │ └── main.yml ├── .gitignore ├── CMakeLists.txt ├── LICENSE.md ├── README.md ├── cmake ├── compiler.cmake ├── dependencies.cmake ├── kumi-config.cmake └── run_wasm.sh ├── doc ├── .nojekyll ├── Doxyfile ├── base.html ├── changelog.md ├── color.css ├── index.hpp ├── layout.xml ├── licence.md ├── logo.png └── setup.hpp ├── include └── kumi │ ├── algorithm.hpp │ ├── algorithm │ ├── back-front.hpp │ ├── cartesian_product.hpp │ ├── cat.hpp │ ├── convert.hpp │ ├── extract.hpp │ ├── find.hpp │ ├── flatten.hpp │ ├── fold.hpp │ ├── generate.hpp │ ├── inner_product.hpp │ ├── map.hpp │ ├── minmax.hpp │ ├── partition.hpp │ ├── predicates.hpp │ ├── push_pop.hpp │ ├── reduce.hpp │ ├── reorder.hpp │ ├── reverse.hpp │ ├── traits.hpp │ ├── transpose.hpp │ └── zip.hpp │ ├── detail │ ├── abi.hpp │ ├── binder.hpp │ ├── concepts.hpp │ ├── optimized.hpp │ └── stdfix.hpp │ ├── tuple.hpp │ ├── utils.hpp │ └── utils │ ├── apply.hpp │ ├── concepts.hpp │ ├── ct_helpers.hpp │ ├── for_each.hpp │ ├── pp_helpers.hpp │ ├── std.hpp │ └── traits.hpp ├── standalone └── kumi │ └── tuple.hpp └── test ├── CMakeLists.txt ├── doc ├── adapt.cpp ├── all_of.cpp ├── any_of.cpp ├── apply.cpp ├── as_flat_ptr.cpp ├── as_tuple.cpp ├── back-front.cpp ├── bit_and.cpp ├── bit_or.cpp ├── cartesian_product.cpp ├── cast.cpp ├── cat.cpp ├── count.cpp ├── count_if.cpp ├── extract.cpp ├── fill.cpp ├── flatten.cpp ├── flatten_all.cpp ├── fold_left.cpp ├── fold_right.cpp ├── for_each.cpp ├── for_each_index.cpp ├── forward_as_tuple.cpp ├── from_tuple.cpp ├── generate.cpp ├── get.cpp ├── index.cpp ├── inner_product.cpp ├── iota.cpp ├── locate.cpp ├── make_tuple.cpp ├── map.cpp ├── map_index.cpp ├── max.cpp ├── max_flat.cpp ├── min.cpp ├── min_flat.cpp ├── none_of.cpp ├── partition.cpp ├── pop_back.cpp ├── pop_front.cpp ├── prod.cpp ├── push_back.cpp ├── push_front.cpp ├── reorder.cpp ├── reverse.cpp ├── split.cpp ├── subscript.cpp ├── sum.cpp ├── tie.cpp ├── to_ref.cpp ├── to_tuple.cpp ├── transpose.cpp └── zip.cpp ├── integration ├── cpm-test │ ├── CMakeLists.txt │ └── cpm.cmake ├── fetch-test │ └── CMakeLists.txt ├── install-test │ └── CMakeLists.txt └── main.cpp └── unit ├── access.cpp ├── adapt.cpp ├── aggregate_ctor.cpp ├── apply.cpp ├── apply_traits.cpp ├── as_flat_ptr.cpp ├── back_front.cpp ├── cartesian_product.cpp ├── cat.cpp ├── common_reference.cpp ├── concepts.cpp ├── convert.cpp ├── extract.cpp ├── fill.cpp ├── flatten.cpp ├── fold.cpp ├── for_each.cpp ├── forward_as_tuple.cpp ├── generate.cpp ├── inner_product.cpp ├── iota.cpp ├── is_homogeneous.cpp ├── locate.cpp ├── make_tuple.cpp ├── map.cpp ├── map_index.cpp ├── map_traits.cpp ├── max.cpp ├── min.cpp ├── partition.cpp ├── predicates.cpp ├── push_pop.cpp ├── reduce.cpp ├── reorder.cpp ├── reverse.cpp ├── split.cpp ├── tie.cpp ├── to_ref.cpp ├── transpose.cpp └── zip.cpp /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: "[BUG]" 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior. A Compiler Explorer link is the preferred way to transfer buggy code fragment. Code must be as small as possible while still exhibiting the bug. 15 | 16 | **Expected behavior** 17 | A clear and concise description of what you expected to happen. 18 | 19 | **Setup:** 20 | - Compiler and compiler's version: [e.g. g++ 10] 21 | - OS: [e.g. Arch Linux] 22 | 23 | **Additional context** 24 | Add any other context about the problem here. 25 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: "[FEATURE]" 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/workflows/documentation.yml: -------------------------------------------------------------------------------- 1 | ##====================================================================================================================== 2 | ## KUMI - Compact C++20 Tuple Toolbox 3 | ## Copyright : KUMI Project Contributors 4 | ## SPDX-License-Identifier: BSL-1.0 5 | ##====================================================================================================================== 6 | name: KUMI Documentation Generation 7 | on: 8 | push: 9 | branches: 10 | - main 11 | 12 | jobs: 13 | generate-doc: 14 | runs-on: ubuntu-latest 15 | container: 16 | image: ghcr.io/jfalcou/compilers:v9 17 | strategy: 18 | fail-fast: false 19 | steps: 20 | - name: Fetch current branch 21 | uses: actions/checkout@v4.1.1 22 | - name: Prepare KUMI 23 | run: | 24 | mkdir build && cd build 25 | cmake .. -G Ninja -DKUMI_BUILD_TEST=OFF -DKUMI_BUILD_DOCUMENTATION=ON 26 | 27 | - name: Generate Doxygen 28 | run: | 29 | cd build 30 | ninja kumi-doxygen 31 | 32 | - name: Deploy to gh-pages 33 | uses: peaceiris/actions-gh-pages@v3 34 | with: 35 | github_token: ${{ secrets.GITHUB_TOKEN }} 36 | publish_dir: ./build/doc 37 | -------------------------------------------------------------------------------- /.github/workflows/integration.yml: -------------------------------------------------------------------------------- 1 | ##====================================================================================================================== 2 | ## KUMI - Compact C++20 Tuple Toolbox 3 | ## Copyright : KUMI Project Contributors 4 | ## SPDX-License-Identifier: BSL-1.0 5 | ##====================================================================================================================== 6 | name: KUMI Integration Tests 7 | on: 8 | push: 9 | branches: 10 | - main 11 | 12 | concurrency: 13 | group: kumi-integration-${{ github.ref }} 14 | cancel-in-progress: true 15 | 16 | jobs: 17 | 18 | install: 19 | runs-on: [ubuntu-latest] 20 | container: 21 | image: ghcr.io/jfalcou/compilers:v9 22 | strategy: 23 | fail-fast: false 24 | 25 | steps: 26 | - name: Fetch current branch 27 | uses: actions/checkout@v4.1.1 28 | - name: Install KUMI from checkout 29 | run: | 30 | mkdir build && cd build 31 | cmake -G Ninja .. -DKUMI_BUILD_TEST=OFF -DCMAKE_CXX_COMPILER=clang++ 32 | ninja install 33 | - name: Run Sample CMake 34 | run: | 35 | mkdir install && cd install 36 | cmake ../test/integration/install-test -G Ninja 37 | ninja && ctest --verbose 38 | 39 | fetch-content: 40 | env: 41 | BRANCH_NAME: ${{ github.head_ref || github.ref_name }} 42 | runs-on: [ubuntu-latest] 43 | container: 44 | image: ghcr.io/jfalcou/compilers:v9 45 | strategy: 46 | fail-fast: false 47 | 48 | steps: 49 | - name: Fetch current branch 50 | uses: actions/checkout@v4.1.1 51 | - name: Compile using FetchContent 52 | run: | 53 | git config --global --add safe.directory /__w/kumi/kumi 54 | mkdir install && cd install 55 | cmake ../test/integration/fetch-test -G Ninja -DGIT_BRANCH=${BRANCH_NAME} -DKUMI_BUILD_TEST=OFF -DCMAKE_CXX_COMPILER=clang++ 56 | ninja && ctest --verbose 57 | 58 | cpm: 59 | env: 60 | BRANCH_NAME: ${{ github.head_ref || github.ref_name }} 61 | runs-on: [ubuntu-latest] 62 | container: 63 | image: ghcr.io/jfalcou/compilers:v9 64 | strategy: 65 | fail-fast: false 66 | 67 | steps: 68 | - name: Fetch current branch 69 | uses: actions/checkout@v4.1.1 70 | - name: Compile using CPM 71 | run: | 72 | git config --global --add safe.directory /__w/kumi/kumi 73 | mkdir install && cd install 74 | cmake ../test/integration/cpm-test -G Ninja -DGIT_BRANCH=${BRANCH_NAME} -DCMAKE_CXX_COMPILER=clang++ -DKUMI_BUILD_TEST=OFF 75 | ninja && ctest --verbose 76 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | 34 | # Dev Env 35 | build/* 36 | .vscode/* 37 | compile_commands.json 38 | .cache 39 | .idea/* 40 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ##====================================================================================================================== 2 | ## KUMI - Compact C++20 Tuple Toolbox 3 | ## Copyright : KUMI Project Contributors 4 | ## SPDX-License-Identifier: BSL-1.0 5 | ##====================================================================================================================== 6 | cmake_minimum_required(VERSION 3.22) 7 | project(kumi LANGUAGES CXX) 8 | 9 | ##====================================================================================================================== 10 | option( KUMI_BUILD_TEST "Build tests for Kumi" ON ) 11 | option( KUMI_BUILD_DOCUMENTATION "Build Doxygen for Kumi" OFF ) 12 | 13 | ##====================================================================================================================== 14 | include(${PROJECT_SOURCE_DIR}/cmake/dependencies.cmake) 15 | 16 | if(KUMI_BUILD_TEST) 17 | include(${PROJECT_SOURCE_DIR}/cmake/compiler.cmake) 18 | endif() 19 | 20 | ##====================================================================================================================== 21 | ## Project setup via copacabana 22 | ##====================================================================================================================== 23 | set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake ${COPACABANA_SOURCE_DIR}/copacabana/cmake) 24 | include(${COPACABANA_SOURCE_DIR}/copacabana/cmake/copacabana.cmake) 25 | copa_project_version(MAJOR 3 MINOR 1 PATCH 0) 26 | 27 | ##====================================================================================================================== 28 | ## Summary Display 29 | ##====================================================================================================================== 30 | if(NOT KUMI_QUIET) 31 | if(CMAKE_BUILD_TYPE) 32 | message(STATUS "[${PROJECT_NAME}] - Building in ${CMAKE_BUILD_TYPE} mode") 33 | endif() 34 | message(STATUS "[${PROJECT_NAME}] - Unit tests : ${KUMI_BUILD_TEST} (via KUMI_BUILD_TEST)") 35 | message(STATUS "[${PROJECT_NAME}] - Doxygen : ${KUMI_BUILD_DOCUMENTATION} (via KUMI_BUILD_DOCUMENTATION)") 36 | set(QUIET_OPTION "") 37 | else() 38 | set(QUIET_OPTION "QUIET") 39 | endif() 40 | 41 | ##====================================================================================================================== 42 | ## Install Process setup 43 | ##====================================================================================================================== 44 | copa_setup_install( LIBRARY kumi 45 | FEATURES cxx_std_20 46 | DOC ${PROJECT_SOURCE_DIR}/LICENSE.md 47 | INCLUDE ${PROJECT_SOURCE_DIR}/include/kumi 48 | ) 49 | 50 | ##====================================================================================================================== 51 | ## Setup doxygen 52 | ##====================================================================================================================== 53 | if(KUMI_BUILD_DOCUMENTATION) 54 | copa_setup_doxygen(${QUIET_OPTION} TARGET kumi-doxygen DESTINATION "${PROJECT_BINARY_DIR}/doc") 55 | endif() 56 | 57 | ##====================================================================================================================== 58 | ## Standalone generation 59 | ##====================================================================================================================== 60 | copa_setup_standalone ( QUIET 61 | FILE tuple.hpp SOURCE include DESTINATION standalone 62 | ROOT kumi TARGET kumi-standalone 63 | ) 64 | 65 | ##====================================================================================================================== 66 | ## Tests setup 67 | ##====================================================================================================================== 68 | if(KUMI_BUILD_TEST) 69 | enable_testing() 70 | add_custom_target(kumi-unit) 71 | add_subdirectory(test) 72 | endif() 73 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Boost Software License 1.0 2 | 3 | Copyright : KUMI Project Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the 6 | software and accompanying documentation covered by this license (the "Software") to use, reproduce, 7 | display, distribute, execute, and transmit the Software, and to prepare derivative works of the 8 | Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the 9 | following: 10 | 11 | The copyright notices in the Software and this entire statement, including the above license grant, 12 | this restriction and the following disclaimer, must be included in all copies of the Software, in 13 | whole or in part, and all derivative works of the Software, unless such copies or derivative works 14 | are solely in the form of machine-executable object code generated by a source language processor. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT 17 | NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND 18 | NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE 19 | BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING 20 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | KUMI Logo : s tack of triangles of variabel shades of purple 2 | 3 | # KUMI - C++20 Compact Tuple Tools 4 | 5 | ## Summary 6 | 7 | **KUMI** is a fancy C++20 implementation of a tuple-like class. It tries to be as close to 8 | `std::tuple` as possible but also wants to compile faster, uses a better C++20 oriented interface, 9 | and new features like: 10 | 11 | - a fast to compile tuple implementation 12 | - quality of life improvement over the standard tuple implementation 13 | - algorithm on tuples 14 | 15 | ## A Short Example 16 | 17 | [See it live on Compiler Explorer](https://godbolt.org/z/cWKd47sT9) 18 | 19 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ c++ 20 | #include 21 | #include 22 | 23 | auto get_student(int id) 24 | { 25 | if (id == 0) return kumi::make_tuple(3.8, 'A', "Lisa Simpson"); 26 | else if (id == 1) return kumi::make_tuple(2.9, 'C', "Milhouse Van Houten"); 27 | else if (id == 2) return kumi::make_tuple(1.7, 'D', "Ralph Wiggum"); 28 | else return kumi::make_tuple(0., 'F', "Unknown"); 29 | } 30 | 31 | int main() 32 | { 33 | auto student0 = get_student(0); 34 | 35 | std::cout << "ID: 0, " 36 | << "GPA: " << kumi::get<0>(student0) << ", " 37 | << "grade: " << kumi::get<1>(student0) << ", " 38 | << "name: " << kumi::get<2>(student0) << '\n'; 39 | 40 | auto [ gpa1, grade1, name1 ] = get_student(1); 41 | std::cout << "ID: 1, " 42 | << "GPA: " << gpa1 << ", " 43 | << "grade: " << grade1 << ", " 44 | << "name: " << name1 << '\n'; 45 | std::cout << "\n"; 46 | 47 | auto all_students = kumi::make_tuple(get_student(0),get_student(1),get_student(2)); 48 | 49 | kumi::for_each_index( [](auto i, auto const& m) { std::cout << "Data #" << i << " : " << m << "\n";} 50 | , all_students 51 | ); 52 | std::cout << "\n"; 53 | 54 | auto grades = kumi::get<0>(kumi::transpose(all_students)); 55 | std::cout << grades << "\n"; 56 | } 57 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 58 | 59 | ## Licence 60 | 61 | This library is licensed under the [Boost Software License](https://opensource.org/licenses/BSL-1.0): 62 | 63 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ none 64 | Copyright : KUMI Project Contributors 65 | 66 | Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the 67 | software and accompanying documentation covered by this license (the "Software") to use, reproduce, 68 | display, distribute, execute, and transmit the Software, and to prepare derivative works of the 69 | Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the 70 | following: 71 | 72 | The copyright notices in the Software and this entire statement, including the above license grant, 73 | this restriction and the following disclaimer, must be included in all copies of the Software, in 74 | whole or in part, and all derivative works of the Software, unless such copies or derivative works 75 | are solely in the form of machine-executable object code generated by a source language processor. 76 | 77 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT 78 | NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND 79 | NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE 80 | BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING 81 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 82 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 83 | -------------------------------------------------------------------------------- /cmake/compiler.cmake: -------------------------------------------------------------------------------- 1 | ##====================================================================================================================== 2 | ## KUMI - Compact C++20 Tuple Toolbox 3 | ## Copyright : KUMI Project Contributors 4 | ## SPDX-License-Identifier: BSL-1.0 5 | ##====================================================================================================================== 6 | 7 | ##====================================================================================================================== 8 | ## Compiler options for Doc Tests 9 | ##====================================================================================================================== 10 | add_library(kumi_docs INTERFACE) 11 | 12 | target_compile_features ( kumi_docs INTERFACE cxx_std_20 ) 13 | 14 | if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") 15 | if(CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC") 16 | target_compile_options( kumi_docs INTERFACE /W3 /EHsc ) 17 | else() 18 | target_compile_options( kumi_docs INTERFACE -Wshadow -Werror -Wall -Wextra -Wunused-variable -Wdocumentation) 19 | endif() 20 | elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") 21 | target_compile_options( kumi_docs INTERFACE /W3 /EHsc /Zc:preprocessor) 22 | else() 23 | target_compile_options( kumi_docs INTERFACE -Wshadow -Werror -Wall -Wextra -Wunused-variable) 24 | endif() 25 | 26 | target_include_directories( kumi_docs INTERFACE 27 | ${PROJECT_SOURCE_DIR}/test 28 | ${PROJECT_SOURCE_DIR}/include 29 | ) 30 | 31 | ##====================================================================================================================== 32 | ## Compiler options for Unit Tests 33 | ##====================================================================================================================== 34 | add_library(kumi_test INTERFACE) 35 | 36 | target_link_libraries(kumi_test INTERFACE kumi_docs tts::tts) 37 | -------------------------------------------------------------------------------- /cmake/dependencies.cmake: -------------------------------------------------------------------------------- 1 | ##====================================================================================================================== 2 | ## KUMI - Compact C++20 Tuple Toolbox 3 | ## Copyright : KUMI Project Contributors 4 | ## SPDX-License-Identifier: BSL-1.0 5 | ##====================================================================================================================== 6 | 7 | ##====================================================================================================================== 8 | ## Download and setup CPM 9 | ##====================================================================================================================== 10 | set(CPM_DOWNLOAD_VERSION 0.40.8) 11 | 12 | if(CPM_SOURCE_CACHE) 13 | set(CPM_DOWNLOAD_LOCATION "${CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake") 14 | elseif(DEFINED ENV{CPM_SOURCE_CACHE}) 15 | set(CPM_DOWNLOAD_LOCATION "$ENV{CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake") 16 | else() 17 | set(CPM_DOWNLOAD_LOCATION "${CMAKE_BINARY_DIR}/cmake/CPM_${CPM_DOWNLOAD_VERSION}.cmake") 18 | endif() 19 | 20 | if(NOT (EXISTS ${CPM_DOWNLOAD_LOCATION})) 21 | message(STATUS "[${PROJECT_NAME}] Downloading CPM.cmake to ${CPM_DOWNLOAD_LOCATION}") 22 | file(DOWNLOAD 23 | https://github.com/TheLartians/CPM.cmake/releases/download/v${CPM_DOWNLOAD_VERSION}/CPM.cmake 24 | ${CPM_DOWNLOAD_LOCATION} 25 | ) 26 | endif() 27 | 28 | include(${CPM_DOWNLOAD_LOCATION}) 29 | 30 | ##====================================================================================================================== 31 | ## Retrieve dependencies 32 | ##====================================================================================================================== 33 | CPMAddPackage(NAME COPACABANA GITHUB_REPOSITORY jfalcou/copacabana GIT_TAG main) 34 | 35 | if(KUMI_BUILD_TEST) 36 | CPMAddPackage ( NAME TTS GITHUB_REPOSITORY jfalcou/tts 37 | GIT_TAG main 38 | OPTIONS "TTS_BUILD_TEST OFF" 39 | "TTS_BUILD_DOCUMENTATION OFF" 40 | "TTS_QUIET ON" 41 | ) 42 | endif() 43 | -------------------------------------------------------------------------------- /cmake/kumi-config.cmake: -------------------------------------------------------------------------------- 1 | ##====================================================================================================================== 2 | ## KUMI - Compact C++20 Tuple Toolbox 3 | ## Copyright : KUMI Project Contributors 4 | ## SPDX-License-Identifier: BSL-1.0 5 | ##====================================================================================================================== 6 | 7 | ##====================================================================================================================== 8 | ## Reuse install.cmake to preapre package properly 9 | ##====================================================================================================================== 10 | include("${CMAKE_CURRENT_LIST_DIR}/kumi-targets.cmake") 11 | set(KUMI_LIBRARIES kumi::kumi) 12 | -------------------------------------------------------------------------------- /cmake/run_wasm.sh: -------------------------------------------------------------------------------- 1 | ##====================================================================================================================== 2 | ## KUMI - Compact C++20 Tuple Toolbox 3 | ## Copyright : KUMI Project Contributors 4 | ## SPDX-License-Identifier: BSL-1.0 5 | ##====================================================================================================================== 6 | #!/bin/sh 7 | 8 | node $@ 9 | -------------------------------------------------------------------------------- /doc/.nojekyll: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /doc/base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | $projectname: $title 10 | $title 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 27 | $treeview 28 | $search 29 | $mathjax 30 | 31 | $extrastylesheet 32 | 33 | 34 | 35 | 36 |
37 | 38 | 39 | 40 | 42 | 43 |
44 | 45 | 46 |
47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 59 | 60 | 61 | 62 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 |
55 |
$projectname $projectnumber 56 |
57 |
$projectbrief
58 |
63 |
$projectbrief
64 |
$searchbox
76 |
77 | 78 | 79 | -------------------------------------------------------------------------------- /doc/changelog.md: -------------------------------------------------------------------------------- 1 | Change Log {#changelog} 2 | ========== 3 | 4 | # Version 3.1 - Exquisite Epidote 5 | 6 | ## What's Changed 7 | 8 | ### Infrastructure Changes 9 | - Migrate CMake infrastructure to [copacabana](https://github.com/jfalcou/copacabana) 10 | - Integration tests are now run on merge to main. 11 | - Improved warnings setup in Unit Tests 12 | - CI now tests for: 13 | - Android 14 | - ICPX 15 | - Mac OS X 14 16 | - Visual Studio cl.exe 17 | - Visual Studio clang-cl.exe 18 | - WASM 19 | - Documentation is now automatically built on merge to stop polluting PRs. 20 | - People can use https://jfalcou.github.io/kumi/kumi.tag as a Doxygen Tag File in their own documentation. 21 | 22 | ### New Features 23 | - Optimize certain data layout and type computation to reduce symbol length. 24 | - Add KUMI_TRIVIAL macro to ensure inlining of key functionalities. 25 | - Add support for homogeneous tuple detection. 26 | - Implement copy-efficient partition. 27 | - Implement apply_traits that computes the result of a traits being applied to all elements of a product type. 28 | - Add support for `std::invoke`-like calls in `apply`, contributed by **jehelset**. 29 | - Add `std::array` as a product type, contributed by **jehelset**. 30 | - Allow for automatic std adaptation to be disengaged via macro. 31 | 32 | ### Bug Fixes 33 | - Fix #55 - Shortcut to pure fold expression whenever possible in reduction. 34 | - Fix #64 - Adapt kumi::tuple to std::common_reference. 35 | - Fix #69 - Better apply and for_each SFINAE compliance. 36 | - Fix #70 - Sign issue with iota. 37 | - Fix #71 - Support for eductions without init values. 38 | - Fix #77 - Adjust type computation of cat, contributed by **jehelset**. 39 | - Fix as_tuple to work with non-product type value type. 40 | - Fix predicates to work with non-product type. 41 | - Fix sign issue with count. 42 | - Fix SFINAE compliance of comparisons operator when used on tuples with non-comparables elements. 43 | - Fix the definition of the non-empty product type concept. 44 | - Fix unqualified make_tuple calls that ADL clashed with std::make_tuple. 45 | - Remove useless != and fix size related checks on comparisons operators. 46 | 47 | **Full Changelog**: https://github.com/jfalcou/kumi/compare/v3.0...v3.1 48 | 49 | # Version 3.0 - Delicious Datolite 50 | 51 | This Release is an API break release. 52 | 53 | ## What's Changed 54 | 55 | ### API and Infrastructure Changes 56 | - kumi::extract and kumi::split are now free functions (See #40) 57 | - KUMI implementation is now done in split file that get aggregated (See #34) 58 | - Massive documentation revamping (See #27, #28) 59 | - Added proper integration tests (See #35) 60 | 61 | ### New Features 62 | - Implemented kumi::iota and generate (See #23) 63 | - Implemented kumi::cartesian_product (See #26) 64 | - Implemented predicate based operations on tuple (See #25) 65 | - Implemented kumi::inner_product (See #36) 66 | - Implemented kumi::back and kumi::front (See #37) 67 | - Implemented kumi::reverse (See #39) 68 | 69 | ### Bug Fixes 70 | - Fix #18 - Bad interaction with tuple of references (See #19) 71 | - Improve kumi::flatten implementation (See #20) 72 | 73 | ## New Contributors 74 | - **jehelset** made their first contribution in https://github.com/jfalcou/kumi/pull/28 75 | 76 | **Full Changelog**: https://github.com/jfalcou/kumi/compare/v2.1...v3.0 77 | 78 | # Version 2.1 - Charming Chrysoprase 79 | 80 | ## What's Changed 81 | 82 | ### Bug Fixes 83 | - Improve `kumi::cat` implementation to perform `O(N)` copies. 84 | - Use include guards to prevent issue when different project use KUMI concurrently. 85 | 86 | ### New Features 87 | - Added the `kumi::sized_product_type_or_more` concept 88 | - Implements `kumi::to_ref` to construct a tuple of references form a reference to a tuple. 89 | 90 | **Full Changelog**: https://github.com/jfalcou/kumi/compare/v2.0...v2.1 91 | 92 | # Version 2.0 - Bedazzling Beryl 93 | 94 | ## What's Changed 95 | 96 | ### Infrastructure 97 | * #6 - Moved kumi.hpp to tuple/kumi.hpp 98 | 99 | This is a slightly API breaking change but as the library gains traction, I hanged the file to a 100 | less surprising name. 101 | 102 | ### Bug Fixes 103 | * #12 - Make == and != SFINAE friendly 104 | 105 | ### New Features 106 | * #4 - Add map_index 107 | * #5 - Implements pop/push-front/back 108 | * Implement as_flat_ptr to work with tuple as a list of member's pointers 109 | * #7 - `kumi::tuple` supports min and max 110 | 111 | **Full Changelog**: https://github.com/jfalcou/kumi/compare/v1.0...v2.0 112 | 113 | # Version 1.0 - Amazing Amethyst 114 | 115 | ## First autonomous public release. 116 | 117 | **KUMI** (組) is now independent of the OFW repository. 118 | -------------------------------------------------------------------------------- /doc/color.css: -------------------------------------------------------------------------------- 1 | html 2 | { 3 | /* primary theme color. This will affect the entire websites color scheme: links, arrows, labels, ... */ 4 | --primary-dark-color: hsl(293, 40%, 30%); 5 | --primary-color: hsl(293, 40%, 50%); 6 | --primary-light-color: hsl(293, 40%, 70%); 7 | 8 | /* page base colors */ 9 | --page-background-color: white; 10 | --page-foreground-color: hsl(293, 40%, 30%); 11 | --page-secondary-foreground-color: hsl(293, 40%, 50%); 12 | } 13 | -------------------------------------------------------------------------------- /doc/index.hpp: -------------------------------------------------------------------------------- 1 | #error DO NOT INCLUDE - DOCUMENTATION PURPOSE ONLY 2 | 3 | //================================================================================================== 4 | //! \mainpage The C++20 Compact Tuple Tools 5 | //! 6 | //! **KUMI** is a fancy C++20 implementation of a tuple-like class. It tries to be as close to 7 | //! `std::tuple` as possible but also wants to compile faster, uses a better C++20 oriented interface, 8 | //! and new features like: 9 | //! 10 | //! - a fast to compile tuple implementation 11 | //! - quality of life improvement over the standard tuple implementation 12 | //! - a protocol to adapt user-defined type to act as tuples 13 | //! - algorithm on tuples 14 | //! 15 | //! # A Short Example 16 | //! 17 | //! @code 18 | //! #include 19 | //! #include 20 | //! 21 | //! auto get_student(int id) 22 | //! { 23 | //! if (id == 0) return kumi::make_tuple(3.8, 'A', "Lisa Simpson"); 24 | //! else if (id == 1) return kumi::make_tuple(2.9, 'C', "Milhouse Van Houten"); 25 | //! else if (id == 2) return kumi::make_tuple(1.7, 'D', "Ralph Wiggum"); 26 | //! else return kumi::make_tuple(0., 'F', "Unknown"); 27 | //! } 28 | //! 29 | //! int main() 30 | //! { 31 | //! auto student0 = get_student(0); 32 | //! 33 | //! std::cout << "ID: 0, " 34 | //! << "GPA: " << kumi::get<0>(student0) << ", " 35 | //! << "grade: " << kumi::get<1>(student0) << ", " 36 | //! << "name: " << kumi::get<2>(student0) << '\n'; 37 | //! 38 | //! auto [ gpa1, grade1, name1 ] = get_student(1); 39 | //! std::cout << "ID: 1, " 40 | //! << "GPA: " << gpa1 << ", " 41 | //! << "grade: " << grade1 << ", " 42 | //! << "name: " << name1 << '\n'; 43 | //! std::cout << "\n"; 44 | //! 45 | //! auto all_students = kumi::make_tuple(get_student(0),get_student(1),get_student(2)); 46 | //! 47 | //! kumi::for_each_index( [](auto i, auto const& m) { std::cout << "Data #" << i << " : " << m << "\n";} 48 | //! , all_students 49 | //! ); 50 | //! std::cout << "\n"; 51 | //! 52 | //! auto grades = kumi::get<0>(kumi::transpose(all_students)); 53 | //! std::cout << grades << "\n"; 54 | //! } 55 | //! @endcode 56 | //! 57 | //! # Licence 58 | //! 59 | //! This library is licensed under the [Boost Software License](https://opensource.org/licenses/BSL-1.0): 60 | //! 61 | //! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ none 62 | //! Copyright : KUMI Project Contributors 63 | //! 64 | //! Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the 65 | //! software and accompanying documentation covered by this license (the "Software") to use, reproduce, 66 | //! display, distribute, execute, and transmit the Software, and to prepare derivative works of the 67 | //! Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the 68 | //! following: 69 | //! 70 | //! The copyright notices in the Software and this entire statement, including the above license grant, 71 | //! this restriction and the following disclaimer, must be included in all copies of the Software, in 72 | //! whole or in part, and all derivative works of the Software, unless such copies or derivative works 73 | //! are solely in the form of machine-executable object code generated by a source language processor. 74 | //! 75 | //! THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT 76 | //! NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND 77 | //! NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE 78 | //! BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING 79 | //! FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 80 | //! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 81 | //! 82 | //================================================================================================== 83 | -------------------------------------------------------------------------------- /doc/licence.md: -------------------------------------------------------------------------------- 1 | Licence {#licence} 2 | ======= 3 | 4 | This library is licensed under the [Boost Software License](http://opensource.org/licenses/MIT): 5 | 6 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ none 7 | Copyright : KUMI Project Contributors 8 | 9 | Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the 10 | software and accompanying documentation covered by this license (the "Software") to use, reproduce, 11 | display, distribute, execute, and transmit the Software, and to prepare derivative works of the 12 | Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the 13 | following: 14 | 15 | The copyright notices in the Software and this entire statement, including the above license grant, 16 | this restriction and the following disclaimer, must be included in all copies of the Software, in 17 | whole or in part, and all derivative works of the Software, unless such copies or derivative works 18 | are solely in the form of machine-executable object code generated by a source language processor. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT 21 | NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND 22 | NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE 23 | BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING 24 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 | 26 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 27 | -------------------------------------------------------------------------------- /doc/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jfalcou/kumi/a243d8ce23b180a62c9500e9d54fddd88c9b8388/doc/logo.png -------------------------------------------------------------------------------- /doc/setup.hpp: -------------------------------------------------------------------------------- 1 | #error DO NOT INCLUDE - DOCUMENTATION PURPOSE ONLY 2 | 3 | //================================================================================================== 4 | /** 5 | @page setup Setup 6 | 7 | @tableofcontents 8 | 9 | @section setup-source Install from the source 10 | 11 | Code source of **KUMI** is available on GitHub and can be retrieved via the following command: 12 | 13 | @code 14 | $ git clone https://github.com/jfalcou/kumi.git 15 | @endcode 16 | 17 | Once retrieved, you should have a `kumi` folder which contains the whole source code. 18 | 19 | Create a `build` directory here and enter it. Once in the `build` directory, 20 | you can use **CMake** to generate the build system for **KUMI**. We recommend using 21 | Ninja but any build system is fine. 22 | 23 | @code 24 | $ mkdir build 25 | $ cd build 26 | $ cmake .. -G Ninja 27 | @endcode 28 | 29 | Once **CMake** completes, you can use the `install` target to build and install **KUMI**. 30 | By default, the library will be installed in the `/usr/local` directory, thus requiring 31 | root privileges. 32 | 33 | @code 34 | $ sudo ninja install 35 | @endcode 36 | 37 | You can select an alternative installation path by specifying the `CMAKE_INSTALL_PREFIX` 38 | option at configuration time. 39 | 40 | @code 41 | $ cmake .. -G Ninja -DCMAKE_INSTALL_PREFIX=path/to/install 42 | $ ninja install 43 | @endcode 44 | 45 | Once installed, **KUMI** is usable directly by providing the path to its installed files. 46 | 47 | @section setup-standalone Standalone setup 48 | 49 | You can also use **KUMI** via a single standalone file that can be vendored in your own project without 50 | having to deal with **KUMI** as a dependency. 51 | 52 | Simply use `wget` to fetch the latest version and place it where you want: 53 | 54 | @code 55 | wget https://raw.githubusercontent.com/jfalcou/kumi/main/standalone/kumi/kumi.hpp 56 | @endcode 57 | 58 | Use **KUMI** by just compiling your code with the include path pointing to the location of this single file. 59 | 60 | @section setup-fetchcontent CMake FetchContent 61 | 62 | You can also use CMake FetchContent operation and use the `kumi::kumi` library target that our CMake exports. 63 | 64 | @code{cmake} 65 | ##================================================================================================== 66 | ## Your project setup 67 | ##================================================================================================== 68 | cmake_minimum_required(VERSION 3.22) 69 | project(kumi-fetch LANGUAGES CXX) 70 | 71 | include(FetchContent) 72 | FetchContent_Declare(kumi GIT_REPOSITORY "https://github.com/jfalcou/kumi.git" GIT_TAG main) 73 | FetchContent_MakeAvailable(kumi) 74 | 75 | add_executable(test_kumi ../main.cpp) 76 | target_link_libraries(test_kumi PUBLIC kumi::kumi) 77 | @endcode 78 | 79 | @section setup-cpm Setup with CPM 80 | 81 | The **KUMI** library can be setup using [CPM](https://github.com/cpm-cmake/CPM.cmake): 82 | 83 | @code{cmake} 84 | ##================================================================================================== 85 | ## Your project setup 86 | ##================================================================================================== 87 | cmake_minimum_required(VERSION 3.18) 88 | project(kumi-cpm LANGUAGES CXX) 89 | 90 | # Setup CPM - See https://github.com/cpm-cmake/CPM.cmake#adding-cpm 91 | include(cpm.cmake) 92 | 93 | CPMAddPackage ( NAME kumi 94 | GIT_REPOSITORY "https://github.com/jfalcou/kumi.git" 95 | OPTIONS "KUMI_BUILD_TEST OFF" 96 | ) 97 | 98 | add_executable(test_kumi ../main.cpp) 99 | target_link_libraries(test_kumi PUBLIC kumi::kumi) 100 | @endcode 101 | **/ 102 | //================================================================================================== 103 | -------------------------------------------------------------------------------- /include/kumi/algorithm.hpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #pragma once 9 | 10 | namespace kumi 11 | { 12 | //================================================================================================ 13 | //! @defgroup algorithm Tuple Algorithms 14 | //! @brief Algorithms for manipulating kumi::tuple 15 | //! 16 | //! @addtogroup algorithm 17 | //! @{ 18 | //! @defgroup transforms Tuple Transformations 19 | //! @brief Algorithms applying transformation to tuple 20 | //! 21 | //! @defgroup queries Tuple Queries 22 | //! @brief Algorithms querying properties from tuples 23 | //! 24 | //! @defgroup reductions Tuple Generalized Reductions 25 | //! @brief Algorithms performing reductions over tuples 26 | //! 27 | //! @defgroup generators Tuple Generators 28 | //! @brief Algorithms generating tuples 29 | //! @} 30 | //================================================================================================ 31 | } 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | -------------------------------------------------------------------------------- /include/kumi/algorithm/back-front.hpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #pragma once 9 | 10 | #include 11 | 12 | namespace kumi 13 | { 14 | //================================================================================================ 15 | //! @ingroup utility 16 | //! @brief Retrieves the front of a tuple 17 | //! 18 | //! @param t Base tuple 19 | //! @return A reference to the first element of the tuple `t` 20 | //! 21 | //! ## Helper type 22 | //! @code 23 | //! namespace kumi::result 24 | //! { 25 | //! template struct front; 26 | //! 27 | //! template 28 | //! using front_t = typename front::type; 29 | //! } 30 | //! @endcode 31 | //! 32 | //! Computes the return type of a call to kumi::front 33 | //! 34 | //! ## Example 35 | //! @include doc/back-front.cpp 36 | //================================================================================================ 37 | template 38 | KUMI_TRIVIAL_NODISCARD constexpr decltype(auto) front(Tuple&& t) requires( size_v != 0) 39 | { 40 | return get<0>(KUMI_FWD(t)); 41 | } 42 | 43 | //================================================================================================ 44 | //! @ingroup utility 45 | //! @brief Retrieves the back of a tuple 46 | //! 47 | //! @param t Base tuple 48 | //! @return A reference to the last element of the tuple `t` 49 | //! 50 | //! ## Helper type 51 | //! @code 52 | //! namespace kumi::result 53 | //! { 54 | //! template struct back; 55 | //! 56 | //! template 57 | //! using back_t = typename back::type; 58 | //! } 59 | //! @endcode 60 | //! 61 | //! Computes the return type of a call to kumi::back 62 | //! 63 | //! ## Example 64 | //! @include doc/back-front.cpp 65 | //================================================================================================ 66 | template 67 | KUMI_TRIVIAL_NODISCARD constexpr decltype(auto) back(Tuple&& t) requires( size_v != 0) 68 | { 69 | return get-1>(KUMI_FWD(t)); 70 | } 71 | 72 | namespace result 73 | { 74 | template struct front : member<0,Tuple> {}; 75 | template struct back : member-1,Tuple> {}; 76 | 77 | template using front_t = typename front::type; 78 | template using back_t = typename back::type; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /include/kumi/algorithm/cartesian_product.hpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #pragma once 9 | 10 | #include 11 | 12 | namespace kumi 13 | { 14 | 15 | //================================================================================================ 16 | namespace _ 17 | { 18 | template struct digits 19 | { 20 | constexpr auto operator()(std::size_t v) noexcept 21 | { 22 | struct { std::size_t data[N]; } values = {}; 23 | std::size_t shp[N] = {S...}; 24 | std::size_t i = 0; 25 | 26 | while(v != 0) 27 | { 28 | values.data[i] = v % shp[i]; 29 | v /= shp[i++]; 30 | } 31 | 32 | return values; 33 | } 34 | }; 35 | } 36 | // MSVC chokes on the other code for empty calls 37 | #if !defined(KUMI_DOXYGEN_INVOKED) 38 | KUMI_TRIVIAL_NODISCARD constexpr auto cartesian_product() { return kumi::tuple<>{}; } 39 | #endif 40 | 41 | //================================================================================================ 42 | //! @ingroup generators 43 | //! @brief Return the Cartesian Product of all elements of its arguments product types 44 | //! @param ts Tuples to process 45 | //! @return a tuple containing all the tuple build from all combination of all ts' elements 46 | //! 47 | //! ## Helper type 48 | //! @code 49 | //! namespace kumi 50 | //! { 51 | //! template struct cartesian_product; 52 | //! 53 | //! template 54 | //! using cartesian_product_t = typename cartesian_product::type; 55 | //! } 56 | //! @endcode 57 | //! 58 | //! Computes the type returned by a call to kumi::cartesian_product. 59 | //! 60 | //! ## Example: 61 | //! @include doc/cartesian_product.cpp 62 | //================================================================================================ 63 | template 64 | [[nodiscard]] constexpr auto cartesian_product(Ts&&... ts) 65 | { 66 | constexpr auto idx = [&](std::index_sequence) 67 | { 68 | kumi::_::digits...> dgt{}; 69 | using t_t = decltype(dgt(0)); 70 | struct { t_t data[sizeof...(I)]; } that = {dgt(I)...}; 71 | return that; 72 | }(std::make_index_sequence<(kumi::size_v * ...)>{}); 73 | 74 | auto maps = [&](auto k, std::index_sequence) 75 | { 76 | auto tps = kumi::forward_as_tuple(ts...); 77 | using tuple_t = kumi::tuple < std::tuple_element_t< idx.data[k].data[I] 78 | , std::remove_cvref_t> 79 | >... 80 | >; 81 | return tuple_t{kumi::get(kumi::get(tps))...}; 82 | }; 83 | 84 | return [&](std::index_sequence) 85 | { 86 | std::make_index_sequence ids; 87 | return kumi::make_tuple( maps(kumi::index, ids)...); 88 | }(std::make_index_sequence<(kumi::size_v * ...)>{}); 89 | } 90 | 91 | namespace result 92 | { 93 | template struct cartesian_product 94 | { 95 | using type = decltype( kumi::cartesian_product( std::declval()... ) ); 96 | }; 97 | 98 | template using cartesian_product_t = typename cartesian_product::type; 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /include/kumi/algorithm/cat.hpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #pragma once 9 | 10 | namespace kumi 11 | { 12 | //================================================================================================ 13 | //! @ingroup generators 14 | //! @brief Concatenates tuples in a single one 15 | //! 16 | //! @param ts Tuples to concatenate 17 | //! @return A tuple made of all element of all input tuples in order 18 | //! 19 | //! ## Helper type 20 | //! @code 21 | //! namespace kumi::result 22 | //! { 23 | //! template struct cat; 24 | //! 25 | //! template 26 | //! using cat_t = typename cat::type; 27 | //! } 28 | //! @endcode 29 | //! 30 | //! Computes the return type of a call to kumi::cat 31 | //! 32 | //! ## Example 33 | //! @include doc/cat.cpp 34 | //================================================================================================ 35 | template 36 | KUMI_TRIVIAL_NODISCARD constexpr auto cat(Tuples&&... ts) 37 | { 38 | if constexpr(sizeof...(Tuples) == 0) return tuple{}; 39 | else 40 | { 41 | // count is at least 1 so MSVC don't cry when we use a 0-sized array 42 | constexpr auto count = (1ULL + ... + kumi::size::value); 43 | constexpr auto pos = [&]() 44 | { 45 | struct { std::size_t t[count],e[count]; } that{}; 46 | std::size_t k = 0, offset = 0; 47 | 48 | auto locate = [&](std::index_sequence) 49 | { 50 | (((that.t[I+offset] = k),(that.e[I+offset] = I)),...); 51 | offset += sizeof...(I); 52 | k++; 53 | }; 54 | 55 | (locate(std::make_index_sequence::value>{}),...); 56 | 57 | return that; 58 | }(); 59 | 60 | return [&](auto&& tuples, std::index_sequence) 61 | { 62 | using rts = std::remove_cvref_t; 63 | using type = kumi::tuple 64 | < std::tuple_element_t< pos.e[N] 65 | , std::remove_cvref_t> 66 | >... 67 | >; 68 | return type{get(get(KUMI_FWD(tuples)))...}; 69 | }(kumi::forward_as_tuple(KUMI_FWD(ts)...), std::make_index_sequence{}); 70 | } 71 | } 72 | 73 | namespace result 74 | { 75 | template struct cat 76 | { 77 | using type = decltype( kumi::cat( std::declval()... ) ); 78 | }; 79 | 80 | template using cat_t = typename cat::type; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /include/kumi/algorithm/find.hpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #pragma once 9 | 10 | namespace kumi 11 | { 12 | //================================================================================================ 13 | //! @ingroup queries 14 | //! @brief Return the index of a value which type satisfies a given predicate 15 | //! @param t Tuple to process 16 | //! @param p Unary predicate. p must return a value convertible to `bool` for every element of t. 17 | //! @return Integral index of the element inside the tuple if present, kumi::size>::value 18 | //! otherwise. 19 | //! ## Example: 20 | //! @include doc/locate.cpp 21 | //================================================================================================ 22 | template 23 | [[nodiscard]] constexpr auto locate( tuple const& t, Pred p ) noexcept 24 | { 25 | auto locator = [&](auto const&... m) 26 | { 27 | bool checks[] = { p(m)... }; 28 | for(std::size_t i=0;i typename Pred, kumi::product_type T> struct partition; 25 | //! 26 | //! template typename Pred, kumi::product_type T> 27 | //! using partition_t = typename partition::type; 28 | //! } 29 | //! @endcode 30 | //! 31 | //! Computes the type returned by a call to kumi::partition. 32 | //! 33 | //! ## Example: 34 | //! @include doc/partition.cpp 35 | //================================================================================================ 36 | template typename Pred, kumi::product_type T> 37 | constexpr auto partition(T&& tup) noexcept 38 | { 39 | constexpr auto pos = [&]() 40 | { 41 | // MSVC is allergic to empty array 42 | struct { std::size_t count = {}, cut = {}, t[1+kumi::size::value]; } that{}; 43 | 44 | auto locate = [&](std::index_sequence) 45 | { 46 | (( Pred>::value ? (that.t[that.count++] = I) : I),...); 47 | that.cut = that.count; 48 | ((!Pred>::value ? (that.t[that.count++] = I) : I),...); 49 | }; 50 | 51 | locate(std::make_index_sequence::value>{}); 52 | 53 | return that; 54 | }(); 55 | 56 | auto select = [&](O, std::index_sequence) 57 | { 58 | using type = kumi::tuple>...>; 59 | return type{get(KUMI_FWD(tup))...}; 60 | }; 61 | 62 | return kumi::tuple{ select(kumi::index<0> , std::make_index_sequence{}) 63 | , select(kumi::index, std::make_index_sequence::value - pos.cut>{}) 64 | }; 65 | } 66 | 67 | namespace result 68 | { 69 | template typename Pred, kumi::product_type T> struct partition 70 | { 71 | using type = decltype( kumi::partition( std::declval() ) ); 72 | }; 73 | 74 | template typename Pred, kumi::product_type T> 75 | using partition_t = typename partition::type; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /include/kumi/algorithm/reorder.hpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #pragma once 9 | 10 | namespace kumi 11 | { 12 | //================================================================================================ 13 | //! @ingroup generators 14 | //! @brief Reorder elements of a kumi::product_type 15 | //! 16 | //! This function does not participate in overload resolution if any IDx is outside [0, size_v[. 17 | //! 18 | //! @note Nothing prevent the number of reordered index to be lesser or greater than t size or 19 | //! the fact they can appear multiple times. 20 | //! 21 | //! @tparam Idx Reordered index of elements 22 | //! @param t kumi::product_type to reorder 23 | //! @return A tuple equivalent to kumi::make_tuple(t[index]...); 24 | //! 25 | //! ## Helper type 26 | //! @code 27 | //! namespace kumi::result 28 | //! { 29 | //! template struct reorder; 30 | //! 31 | //! template 32 | //! using reorder_t = typename reorder::type; 33 | //! } 34 | //! @endcode 35 | //! 36 | //! Computes the return type of a call to kumi::reorder 37 | //! 38 | //! ## Example 39 | //! @include doc/reorder.cpp 40 | //================================================================================================ 41 | template 42 | requires((Idx < size_v) && ...) 43 | KUMI_TRIVIAL_NODISCARD constexpr auto reorder(Tuple &&t) 44 | { 45 | return kumi::make_tuple( get(KUMI_FWD(t))...); 46 | } 47 | 48 | namespace result 49 | { 50 | template 51 | struct reorder 52 | { 53 | using type = decltype( kumi::reorder( std::declval() ) ); 54 | }; 55 | 56 | template 57 | using reorder_t = typename reorder::type; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /include/kumi/algorithm/reverse.hpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #pragma once 9 | 10 | namespace kumi 11 | { 12 | //================================================================================================ 13 | //! @ingroup generators 14 | //! @brief Reverse elements of a kumi::product_type 15 | //! 16 | //! @param t kumi::product_type to reverse 17 | //! @return A tuple equivalent to kumi::make_tuple(t[index - 1 - Idx>]...); 18 | //! 19 | //! ## Helper type 20 | //! @code 21 | //! namespace kumi::result 22 | //! { 23 | //! template struct reverse; 24 | //! 25 | //! template 26 | //! using reverse_t = typename reverse::type; 27 | //! } 28 | //! @endcode 29 | //! 30 | //! Computes the return type of a call to kumi::reverse 31 | //! 32 | //! ## Example 33 | //! @include doc/reverse.cpp 34 | //================================================================================================ 35 | template 36 | [[nodiscard]] constexpr auto reverse(Tuple &&t) 37 | { 38 | if constexpr(sized_product_type) return kumi::tuple<>{}; 39 | else 40 | { 41 | return [&](std::index_sequence) 42 | { 43 | return kumi::make_tuple(get<(size_v - 1 - I)>(KUMI_FWD(t))...); 44 | } 45 | (std::make_index_sequence::value>()); 46 | } 47 | } 48 | 49 | namespace result 50 | { 51 | template 52 | struct reverse 53 | { 54 | using type = decltype( kumi::reverse( std::declval() ) ); 55 | }; 56 | 57 | template 58 | using reverse_t = typename reverse::type; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /include/kumi/algorithm/traits.hpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #pragma once 9 | 10 | namespace kumi 11 | { 12 | template< template typename Traits 13 | , product_type Tuple 14 | , typename Seq = std::make_index_sequence::value> 15 | > 16 | struct apply_traits; 17 | 18 | template< template typename Traits 19 | , product_type Tuple 20 | , std::size_t... Is 21 | > 22 | requires( requires {typename Traits...>::type;}) 23 | struct apply_traits> 24 | { 25 | using type = typename Traits...>::type; 26 | }; 27 | 28 | template< template typename Traits 29 | , product_type Tuple 30 | > 31 | using apply_traits_t = typename apply_traits::type; 32 | 33 | 34 | 35 | template< template typename Traits 36 | , product_type Tuple 37 | , typename Seq = std::make_index_sequence::value> 38 | > 39 | struct map_traits; 40 | 41 | template< template typename Traits 42 | , product_type Tuple 43 | , std::size_t... Is 44 | > 45 | requires( requires {typename Traits>::type;} && ...) 46 | struct map_traits> 47 | { 48 | using type = tuple >::type...>; 49 | }; 50 | 51 | template< template typename Traits 52 | , product_type Tuple 53 | > 54 | using map_traits_t = typename map_traits::type; 55 | 56 | } 57 | -------------------------------------------------------------------------------- /include/kumi/algorithm/transpose.hpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #pragma once 9 | 10 | namespace kumi 11 | { 12 | //================================================================================================ 13 | //! @ingroup generators 14 | //! @brief Transpose a tuple of tuples by shifting elements in their transposed position 15 | //! 16 | //! @param t Tuple to transpose 17 | //! @return A tuple containing the transposed elements of t. 18 | //! 19 | //! ## Helper type 20 | //! @code 21 | //! namespace kumi::result 22 | //! { 23 | //! template struct transpose; 24 | //! 25 | //! template 26 | //! using transpose_t = typename transpose::type; 27 | //! } 28 | //! @endcode 29 | //! 30 | //! Computes the return type of a call to kumi::transpose 31 | //! 32 | //! ## Example 33 | //! @include doc/transpose.cpp 34 | //================================================================================================ 35 | template [[nodiscard]] constexpr auto transpose(Tuple const &t) 36 | { 37 | if constexpr(sized_product_type) return t; 38 | else 39 | { 40 | return [&](std::index_sequence) 41 | { 42 | constexpr auto uz = [](N const &, auto const &u) { 43 | return apply([](auto const &...m) { return kumi::make_tuple(get(m)...); }, u); 44 | }; 45 | 46 | return kumi::make_tuple(uz(index_t {}, t)...); 47 | } 48 | (std::make_index_sequence>::value>()); 49 | } 50 | } 51 | 52 | namespace result 53 | { 54 | template struct transpose 55 | { 56 | using type = decltype( kumi::transpose( std::declval() ) ); 57 | }; 58 | 59 | template 60 | using transpose_t = typename transpose::type; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /include/kumi/algorithm/zip.hpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #pragma once 9 | 10 | namespace kumi 11 | { 12 | //================================================================================================ 13 | //! @ingroup generators 14 | //! @brief Constructs a tuple where the ith element is the tuple of all ith elements of ts... 15 | //! 16 | //! @param t0 Tuple to convert 17 | //! @param ts Tuples to convert 18 | //! @return The tuple of all combination of elements from t0, ts... 19 | //! 20 | //! ## Helper type 21 | //! @code 22 | //! namespace kumi::result 23 | //! { 24 | //! template struct zip; 25 | //! 26 | //! template 27 | //! using zip_t = typename zip::type; 28 | //! } 29 | //! @endcode 30 | //! 31 | //! Computes the return type of a call to kumi::zip 32 | //! 33 | //! ## Example 34 | //! @include doc/zip.cpp 35 | //================================================================================================ 36 | template>... Ts> 37 | [[nodiscard]] constexpr auto zip(T0 const &t0, Ts const &...ts) 38 | { 39 | return kumi::map( [](auto const &m0, auto const &...ms) { return kumi::make_tuple(m0, ms...); } 40 | , t0,ts... 41 | ); 42 | } 43 | 44 | namespace result 45 | { 46 | template 47 | struct zip 48 | { 49 | using type = decltype( kumi::zip( std::declval(), std::declval()... ) ); 50 | }; 51 | 52 | template 53 | using zip_t = typename zip::type; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /include/kumi/detail/abi.hpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #pragma once 9 | 10 | #if defined(__GNUC__) 11 | # define KUMI_TRIVIAL [[gnu::always_inline, gnu::flatten, gnu::artificial]] inline 12 | # define KUMI_TRIVIAL_NODISCARD [[nodiscard, gnu::always_inline, gnu::flatten, gnu::artificial]] inline 13 | #elif defined(_MSC_VER) 14 | # define KUMI_TRIVIAL __forceinline 15 | # define KUMI_TRIVIAL_NODISCARD [[nodiscard]] 16 | #endif 17 | -------------------------------------------------------------------------------- /include/kumi/detail/binder.hpp: -------------------------------------------------------------------------------- 1 | //====================================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //====================================================================================================================== 8 | #pragma once 9 | 10 | #include 11 | #include 12 | 13 | namespace kumi::_ 14 | { 15 | //==================================================================================================================== 16 | // Tuple leaf binder tricks 17 | //==================================================================================================================== 18 | template struct leaf 19 | { 20 | T value; 21 | }; 22 | 23 | template 24 | KUMI_TRIVIAL constexpr T & get_leaf(leaf & a) noexcept { return a.value; } 25 | template 26 | KUMI_TRIVIAL constexpr T && get_leaf(leaf &&a) noexcept { return static_cast(a.value); } 27 | template 28 | KUMI_TRIVIAL constexpr T const && get_leaf(leaf const &&a) noexcept { return static_cast(a.value); } 29 | template 30 | KUMI_TRIVIAL constexpr T const & get_leaf(leaf const & a) noexcept { return a.value; } 31 | 32 | template struct binder; 33 | 34 | // General N-case 35 | template 36 | struct binder, Ts...> : leaf... 37 | { 38 | static constexpr bool is_homogeneous = false; 39 | }; 40 | 41 | // Specializable binder type constructor 42 | template 43 | struct make_binder 44 | { 45 | using type = binder; 46 | }; 47 | 48 | template 49 | using make_binder_t = typename make_binder::type; 50 | } 51 | 52 | #include 53 | -------------------------------------------------------------------------------- /include/kumi/detail/stdfix.hpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #pragma once 9 | 10 | #if defined( __ANDROID__ ) || defined(__APPLE__) 11 | #include 12 | 13 | namespace kumi 14 | { 15 | template 16 | concept convertible_to = std::is_convertible_v 17 | && requires { static_cast(std::declval()); }; 18 | } 19 | #else 20 | #include 21 | 22 | namespace kumi 23 | { 24 | using std::convertible_to; 25 | } 26 | #endif 27 | -------------------------------------------------------------------------------- /include/kumi/utils.hpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #pragma once 9 | 10 | //================================================================================================== 11 | //! @namespace kumi 12 | //! @brief Main KUMI namespace 13 | //================================================================================================== 14 | namespace kumi 15 | { 16 | //================================================================================================ 17 | //! @defgroup utility Helper Types and Functions 18 | //! @brief Tools for interacting with kumi::tuple 19 | //! 20 | //! @defgroup tuple Tuple Types and Functions 21 | //! @brief Definition for kumi::tuple class and functions 22 | //! 23 | //! @defgroup concepts Tuple Related Concepts 24 | //! @brief Definition for product types related Concepts 25 | //! 26 | //! @defgroup traits Tuple Related Traits 27 | //! @brief Definition for kumi::tuple traits and extension points 28 | //================================================================================================ 29 | } 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | -------------------------------------------------------------------------------- /include/kumi/utils/apply.hpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #pragma once 9 | 10 | namespace kumi 11 | { 12 | 13 | namespace _{ 14 | template 15 | inline constexpr bool is_reference_wrapper_v = 16 | !std::is_same_v::type>, 17 | typename std::unwrap_ref_decay::type>; 18 | 19 | template 20 | struct apply_object_unwrap{ 21 | using type = T &&; 22 | }; 23 | template 24 | requires is_reference_wrapper_v 25 | struct apply_object_unwrap{ 26 | using type = typename std::remove_cvref_t::type &; 27 | }; 28 | template 29 | requires std::is_pointer_v> 30 | struct apply_object_unwrap{ 31 | using type = std::remove_pointer_t> &; 32 | }; 33 | template 34 | using apply_object_unwrap_t = typename apply_object_unwrap::type; 35 | 36 | } 37 | 38 | //================================================================================================ 39 | //! @ingroup transforms 40 | //! @brief Invoke the Callable object f with a tuple of arguments. 41 | //! 42 | //! @param f Callable object to be invoked 43 | //! @param t kumi::product_type whose elements to be used as arguments to f 44 | //! @return The value returned by f. 45 | //! 46 | //! ## Helper type 47 | //! @code 48 | //! namespace kumi::result 49 | //! { 50 | //! template struct apply; 51 | //! 52 | //! template 53 | //! using apply_t = typename apply::type; 54 | //! } 55 | //! @endcode 56 | //! 57 | //! Computes the return type of a call to kumi::apply 58 | //! 59 | //! ## Example 60 | //! @include doc/apply.cpp 61 | //================================================================================================ 62 | template 63 | constexpr decltype(auto) apply(Function &&f, Tuple &&t) noexcept(_::supports_nothrow_apply) 64 | requires _::supports_apply 65 | { 66 | if constexpr(sized_product_type) return KUMI_FWD(f)(); 67 | else if constexpr (std::is_member_pointer_v>) 68 | return [&](std::index_sequence) -> decltype(auto){ 69 | auto &&w = [](auto &&y) -> decltype(auto){ 70 | if constexpr(_::is_reference_wrapper_v) 71 | return y.get(); 72 | else if constexpr(std::is_pointer_v>) 73 | return *y; 74 | else 75 | return KUMI_FWD(y); 76 | }(get<0>(KUMI_FWD(t))); 77 | if constexpr(std::is_member_object_pointer_v>) 78 | return KUMI_FWD(w).*f; 79 | else 80 | return (KUMI_FWD(w).*f)(get(KUMI_FWD(t))...); 81 | } 82 | (std::make_index_sequence::value - 1>()); 83 | else 84 | return [&](std::index_sequence) -> decltype(auto) 85 | { 86 | return KUMI_FWD(f)(get(KUMI_FWD(t))...); 87 | } 88 | (std::make_index_sequence::value>()); 89 | } 90 | 91 | namespace result 92 | { 93 | template 94 | struct apply 95 | { 96 | using type = decltype(kumi::apply(std::declval(), std::declval())); 97 | }; 98 | 99 | template 100 | using apply_t = typename apply::type; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /include/kumi/utils/ct_helpers.hpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #pragma once 9 | 10 | #include 11 | 12 | namespace kumi 13 | { 14 | //================================================================================================ 15 | //! @ingroup utility 16 | //! @brief Integral constant type 17 | //! 18 | //! Defines a integral constant wrapper used to carry compile-time constant through API 19 | //================================================================================================ 20 | template struct index_t 21 | { 22 | /// Value stored by the constant 23 | static constexpr auto value = N; 24 | 25 | /// Conversion operator to integer 26 | constexpr inline operator std::size_t() const noexcept { return N; } 27 | }; 28 | 29 | //================================================================================================ 30 | //! @ingroup utility 31 | //! @brief Inline integral constant value for kumi::index_t 32 | //================================================================================================ 33 | template inline constexpr index_t const index = {}; 34 | 35 | //================================================================================================ 36 | //! @namespace literals 37 | //! @brief KUMI literals namespace 38 | //================================================================================================ 39 | namespace literals 40 | { 41 | template constexpr auto b10() 42 | { 43 | auto value = 0ULL; 44 | ((value = value * 10 + (c - '0')), ...); 45 | return value; 46 | } 47 | 48 | //============================================================================================== 49 | //! @ingroup utility 50 | //! @brief Forms a integral constant literal of the desired value. 51 | //! @return An instance of kumi::index_t for the specified integral value 52 | //! ## Example: 53 | //! @include doc/index.cpp 54 | //============================================================================================== 55 | template constexpr auto operator""_c() noexcept { return index()>; } 56 | } 57 | 58 | //================================================================================================ 59 | //! @ingroup utility 60 | //! @brief Convert a unary template meta-program in a running predicate 61 | //! @tparam Pred Unary template meta-program to convert. 62 | //! @return A Callable Object applying Pred to the type of its arguments 63 | //================================================================================================ 64 | template class Pred> [[nodiscard]] constexpr auto predicate() noexcept 65 | { 66 | return [](T const&) constexpr { return Pred::value; }; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /include/kumi/utils/for_each.hpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #pragma once 9 | 10 | namespace kumi 11 | { 12 | 13 | //================================================================================================ 14 | //! @ingroup transforms 15 | //! @brief Applies the Callable object f on each element of a kumi::product_type. 16 | //! 17 | //! @note This function does not take part in overload resolution if `f` can't be applied to the 18 | //! elements of `t` and/or `ts`. 19 | //! 20 | //! @param f Callable object to be invoked 21 | //! @param t kumi::product_type whose elements to be used as arguments to f 22 | //! @param ts Other kumi::product_type whose elements to be used as arguments to f 23 | //! 24 | //! @see kumi::for_each_index 25 | //! 26 | //! ## Example 27 | //! @include doc/for_each.cpp 28 | //================================================================================================ 29 | template 30 | constexpr void for_each(Function f, Tuple&& t, Tuples&&... ts) 31 | requires _::supports_call 32 | { 33 | if constexpr(sized_product_type) return; 34 | else 35 | { 36 | [&](std::index_sequence) 37 | { 38 | // clang needs this for some reason 39 | using std::get; 40 | [[maybe_unused]] auto call = [&](M) 41 | { f ( get(KUMI_FWD(t)) 42 | , get(KUMI_FWD(ts))... 43 | ); 44 | }; 45 | 46 | ( call(std::integral_constant{}), ... ); 47 | } 48 | (std::make_index_sequence::value>()); 49 | } 50 | } 51 | 52 | //================================================================================================ 53 | //! @ingroup transforms 54 | //! @brief Applies the Callable object f on each element of a kumi::product_type and its index. 55 | //! 56 | //! @note This function does not take part in overload resolution if `f` can't be applied to the 57 | //! elements of `t` and/or `ts` and an integral constant. 58 | //! 59 | //! @param f Callable object to be invoked 60 | //! @param t kumi::product_type whose elements to be used as arguments to f 61 | //! @param ts Other kumi::product_type whose elements to be used as arguments to f 62 | //! 63 | //! @see kumi::for_each 64 | //! 65 | //! ## Example 66 | //! @include doc/for_each_index.cpp 67 | //================================================================================================ 68 | template 69 | constexpr void for_each_index(Function f, Tuple&& t, Tuples&&... ts) 70 | { 71 | if constexpr(sized_product_type) return; 72 | else 73 | { 74 | auto const invoker{[&, f](auto const i) 75 | { 76 | f 77 | ( 78 | i, 79 | get(KUMI_FWD(t)), 80 | get(KUMI_FWD(ts))... 81 | ); 82 | }}; 83 | 84 | [=](std::index_sequence) 85 | { 86 | (invoker( std::integral_constant{} ), ...); 87 | }(std::make_index_sequence::value>()); 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /include/kumi/utils/pp_helpers.hpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #pragma once 9 | 10 | #if defined(__clang__) 11 | # pragma clang diagnostic ignored "-Wmissing-braces" 12 | #endif 13 | 14 | // Macro to replace std::forward. Better compile-time + less error-prone 15 | #define KUMI_FWD(...) static_cast(__VA_ARGS__) 16 | -------------------------------------------------------------------------------- /include/kumi/utils/std.hpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #pragma once 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #if !defined(KUMI_DOXYGEN_INVOKED) 17 | //================================================================================================== 18 | // Structured binding adaptation 19 | //================================================================================================== 20 | template 21 | struct std::tuple_element> 22 | : std::tuple_element> 23 | { 24 | }; 25 | 26 | template struct std::tuple_element const> 27 | { 28 | using type = typename tuple_element>::type const; 29 | }; 30 | 31 | template struct std::tuple_element<0, kumi::tuple> 32 | { 33 | using type = Head; 34 | }; 35 | 36 | template 37 | struct std::tuple_size> : std::integral_constant 38 | { 39 | }; 40 | 41 | #if !defined( __ANDROID__ ) 42 | //================================================================================================== 43 | // Common Reference support 44 | //================================================================================================== 45 | template< typename... Ts, typename... Us 46 | , template class TQual, template class UQual > 47 | requires(sizeof...(Ts) == sizeof...(Us)) 48 | struct std::basic_common_reference, kumi::tuple, TQual, UQual> 49 | { 50 | using type = kumi::tuple, UQual>...>; 51 | }; 52 | #endif 53 | 54 | //================================================================================================== 55 | // Standard array support 56 | //================================================================================================== 57 | #if !defined(KUMI_NO_STD_ADAPTORS) 58 | template< typename T, std::size_t N > 59 | struct kumi::is_product_type> : std::true_type {}; 60 | #endif 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ##====================================================================================================================== 2 | ## KUMI - Compact C++20 Tuple Toolbox 3 | ## Copyright : KUMI Project Contributors 4 | ## SPDX-License-Identifier: BSL-1.0 5 | ##====================================================================================================================== 6 | copa_setup_test_targets() 7 | set(root "${CMAKE_SOURCE_DIR}/test") 8 | 9 | ##====================================================================================================================== 10 | ## Documentation tests 11 | ##====================================================================================================================== 12 | copa_glob_unit(QUIET PATTERN "doc/*.cpp" INTERFACE kumi_docs OPT_RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}) 13 | 14 | ##====================================================================================================================== 15 | ## Unit tests 16 | ##====================================================================================================================== 17 | copa_glob_unit(QUIET PATTERN "unit/*.cpp" INTERFACE kumi_test OPT_RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}) 18 | -------------------------------------------------------------------------------- /test/doc/adapt.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | #include 9 | 10 | namespace ns 11 | { 12 | struct people 13 | { 14 | std::string name; 15 | int age; 16 | }; 17 | 18 | template 19 | decltype(auto) get(people const& s) noexcept 20 | { 21 | if constexpr(I==0) return s.name; 22 | if constexpr(I==1) return s.age; 23 | } 24 | 25 | template 26 | decltype(auto) get(people& s) noexcept 27 | { 28 | if constexpr(I==0) return s.name; 29 | if constexpr(I==1) return s.age; 30 | } 31 | } 32 | 33 | // Opt-in for Product Type semantic 34 | template<> 35 | struct kumi::is_product_type : std::true_type 36 | {}; 37 | 38 | // Adapt as structured bindable type 39 | template<> 40 | struct std::tuple_size 41 | : std::integral_constant {}; 42 | 43 | template<> struct std::tuple_element<0,ns::people> { using type = std::string; }; 44 | template<> struct std::tuple_element<1,ns::people> { using type = int; }; 45 | 46 | int main() 47 | { 48 | ns::people peter{"Peter Parker", 24}; 49 | kumi::for_each_index( [](int i, auto e) 50 | { 51 | std::cout << "# " << i 52 | << " : " << e 53 | << "\n"; 54 | } 55 | , peter 56 | ); 57 | } 58 | -------------------------------------------------------------------------------- /test/doc/all_of.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | 9 | int main() 10 | { 11 | auto t = kumi::tuple{1,2.,3.f}; 12 | std::cout << std::boolalpha << kumi::all_of( t, [](auto e) { return e < 5; }) << "\n"; 13 | std::cout << std::boolalpha << kumi::all_of( -3.3, [](auto e) { return e < 5; }) << "\n"; 14 | 15 | auto u = kumi::tuple{true,false,true,false}; 16 | std::cout << std::boolalpha << kumi::all_of(u) << "\n"; 17 | } 18 | -------------------------------------------------------------------------------- /test/doc/any_of.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | 9 | int main() 10 | { 11 | auto t = kumi::tuple{1,2.,3.f}; 12 | std::cout << std::boolalpha << kumi::any_of( t, [](auto e) { return e == 2; }) << "\n"; 13 | std::cout << std::boolalpha << kumi::any_of( 5.f, [](auto e) { return e == 5; }) << "\n"; 14 | 15 | auto u = kumi::tuple{true,false,true,false}; 16 | std::cout << std::boolalpha << kumi::any_of(u) << "\n"; 17 | } 18 | -------------------------------------------------------------------------------- /test/doc/apply.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | 9 | template 10 | void print(std::ostream& os, Tuple const& t) 11 | { 12 | kumi::apply 13 | ( 14 | [&os](auto const&... args) 15 | { 16 | os << '['; 17 | std::size_t n{0}; 18 | ((os << args << (++n != kumi::size::value ? ", " : "")), ...); 19 | os << ']'; 20 | }, t 21 | ); 22 | 23 | os << '\n'; 24 | } 25 | 26 | int main() 27 | { 28 | auto t = kumi::tuple{1,2.,3.f}; 29 | 30 | // Simple operation: sum all values 31 | std::cout << kumi::apply( [](auto... m) { return (m + ...); }, t) << "\n"; 32 | 33 | // Advanced usage 34 | print(std::cout, t); 35 | } 36 | -------------------------------------------------------------------------------- /test/doc/as_flat_ptr.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | 9 | int main() 10 | { 11 | kumi::tuple a = { 1, kumi::tuple{ 2.3, 4.5f }, short{89} }; 12 | 13 | auto ptr = kumi::as_flat_ptr(a); 14 | 15 | std::cout << a << "\n"; 16 | std::cout << ptr << "\n"; 17 | 18 | kumi::for_each([](auto p) { *p += 5; }, ptr ); 19 | 20 | std::cout << a << "\n"; 21 | } 22 | -------------------------------------------------------------------------------- /test/doc/as_tuple.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | struct vec3 13 | { 14 | float x, y, z; 15 | }; 16 | 17 | template 18 | decltype(auto) get(vec3 const& v) noexcept 19 | { 20 | if constexpr(I==0) return v.x; 21 | if constexpr(I==1) return v.y; 22 | if constexpr(I==2) return v.z; 23 | } 24 | 25 | template 26 | decltype(auto) get(vec3& v) noexcept 27 | { 28 | if constexpr(I==0) return v.x; 29 | if constexpr(I==1) return v.y; 30 | if constexpr(I==2) return v.z; 31 | } 32 | 33 | // Opt-in for Product Type semantic 34 | template<> 35 | struct kumi::is_product_type : std::true_type 36 | {}; 37 | 38 | // Adapt as structured bindable type 39 | template<> 40 | struct std::tuple_size 41 | : std::integral_constant {}; 42 | 43 | template struct std::tuple_element { using type = float; }; 44 | 45 | int main() 46 | { 47 | using three_floats = kumi::as_tuple_t; 48 | using single_type = kumi::as_tuple_t; 49 | using three_pointers = kumi::as_tuple_t; 50 | using single_pointer = kumi::as_tuple_t; 51 | 52 | static_assert( std::same_as >); 53 | static_assert( std::same_as >); 54 | static_assert( std::same_as >); 55 | static_assert( std::same_as >); 56 | } 57 | -------------------------------------------------------------------------------- /test/doc/back-front.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | 9 | int main() 10 | { 11 | kumi::tuple x{2.3,18, 5.f}; 12 | 13 | std::cout << kumi::front(x) << "\n"; 14 | std::cout << kumi::back(x) << "\n"; 15 | 16 | kumi::front(x) = 98.5; 17 | kumi::back(x) = 66.f; 18 | 19 | std::cout << x << "\n"; 20 | } 21 | -------------------------------------------------------------------------------- /test/doc/bit_and.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | 9 | int main() 10 | { 11 | auto t = kumi::tuple{14,short{7}, 255ULL}; 12 | 13 | std::cout << kumi::bit_and(t, 65535) << "\n"; 14 | std::cout << kumi::bit_and(t) << "\n"; 15 | } 16 | -------------------------------------------------------------------------------- /test/doc/bit_or.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | 9 | int main() 10 | { 11 | auto t = kumi::tuple{1,short{8},' ', 4ULL}; 12 | 13 | std::cout << kumi::bit_or(t, 0) << "\n"; 14 | std::cout << kumi::bit_or(t) << "\n"; 15 | } 16 | -------------------------------------------------------------------------------- /test/doc/cartesian_product.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | 9 | int main() 10 | { 11 | auto status = kumi::tuple{true, false}; 12 | auto id = kumi::tuple{'a','b','c'}; 13 | auto value = kumi::tuple{1.0,2.1,4.2,8.4}; 14 | 15 | auto r = kumi::cartesian_product( status, id, value ); 16 | 17 | kumi::for_each_index( [](auto i, auto e) 18 | { 19 | std::cout << "# " << i 20 | << ":" << std::boolalpha 21 | << e << "\n"; 22 | } 23 | , r 24 | ); 25 | } 26 | -------------------------------------------------------------------------------- /test/doc/cast.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | 9 | int main() 10 | { 11 | kumi::tuple a = { 65, 2.3, 4.5f}; 12 | auto b = a.cast(); 13 | 14 | std::cout << a << "\n"; 15 | std::cout << b << "\n"; 16 | } 17 | -------------------------------------------------------------------------------- /test/doc/cat.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | 9 | int main() 10 | { 11 | kumi::tuple a = { 1, 2.3, 4.5f}; 12 | kumi::tuple b = { '6' }; 13 | kumi::tuple c = { "7", short{89} }; 14 | 15 | auto abc = cat(a,b,c); 16 | 17 | std::cout << a << " " << b << " " << c << "\n"; 18 | std::cout << abc << "\n"; 19 | } 20 | -------------------------------------------------------------------------------- /test/doc/count.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | #include 9 | 10 | int main() 11 | { 12 | auto t = kumi::tuple{1, 0, 2., nullptr, 3.f, false, 'z'}; 13 | std::cout << std::boolalpha << kumi::count(t ) << "\n"; 14 | std::cout << std::boolalpha << kumi::count(7.89) << "\n"; 15 | } 16 | -------------------------------------------------------------------------------- /test/doc/count_if.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | #include 9 | 10 | int main() 11 | { 12 | auto t = kumi::tuple{1, 2., 3.f, 'z'}; 13 | std::cout << std::boolalpha 14 | << kumi::count_if( t, kumi::predicate() ) << "\n"; 15 | std::cout << std::boolalpha 16 | << kumi::count_if( 2.3, kumi::predicate() ) << "\n"; 17 | } 18 | -------------------------------------------------------------------------------- /test/doc/extract.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | 9 | int main() 10 | { 11 | using namespace kumi::literals; 12 | 13 | kumi::tuple a = { 1, 2.3, 4.5f,'6',"7", short{89} }; 14 | 15 | auto head = extract(a,0_c,1_c); 16 | auto mid = extract(a,1_c,3_c); 17 | auto last = extract(a,kumi::index<3>); 18 | 19 | std::cout << a << " => " << head << ' ' << mid << ' ' << last << '\n'; 20 | } 21 | -------------------------------------------------------------------------------- /test/doc/fill.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | 9 | int main() 10 | { 11 | std::cout << kumi::fill<7>(42.63) << "\n"; 12 | } 13 | -------------------------------------------------------------------------------- /test/doc/flatten.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | 9 | int main() 10 | { 11 | auto nbrs = kumi::tuple{1,2,3}; 12 | auto more_nbrs = kumi::tuple{0,nbrs,4}; 13 | auto ltrs = kumi::tuple{'a','b','c'}; 14 | 15 | auto r = kumi::flatten( kumi::tuple{3.5,nbrs,'z',more_nbrs,5.35f,ltrs} ); 16 | std::cout << r << "\n"; 17 | } 18 | -------------------------------------------------------------------------------- /test/doc/flatten_all.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | 9 | int main() 10 | { 11 | auto nbrs = kumi::tuple{1,2ULL,3}; 12 | auto more_nbrs = kumi::tuple{short{0},nbrs,4.}; 13 | auto ltrs = kumi::tuple{'a','b','c'}; 14 | 15 | auto r = kumi::flatten_all( kumi::tuple{3.5,nbrs,'z',more_nbrs,5.35f,ltrs} ); 16 | std::cout << r << "\n"; 17 | 18 | auto sz = kumi::flatten_all ( kumi::tuple{3.5,nbrs,'z',more_nbrs,5.35f,ltrs} 19 | , [](auto e) { return sizeof(e); } 20 | ); 21 | std::cout << sz << "\n"; 22 | } 23 | -------------------------------------------------------------------------------- /test/doc/fold_left.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | #include 9 | 10 | int main() 11 | { 12 | auto t = kumi::tuple{2.,1,short{55},'z'}; 13 | 14 | auto output = kumi::fold_left( [](auto a, auto m) { a.push_back(sizeof(m)); return a; } 15 | , t 16 | , std::vector{} 17 | ); 18 | 19 | for(auto s : output) std::cout << s << " "; 20 | std::cout << "\n"; 21 | 22 | auto u = kumi::tuple{1,3,2,4,0,5,9,6,7}; 23 | 24 | std::cout << kumi::fold_left( [](auto acc, auto e) 25 | { 26 | std::cout << '(' << acc << ',' << e << ")\n"; 27 | return (e 7 | #include 8 | #include 9 | 10 | int main() 11 | { 12 | auto t = kumi::tuple{2.,1,short{55},'z'}; 13 | 14 | auto output = kumi::fold_right( [](auto a, auto m) { a.push_back(sizeof(m)); return a; } 15 | , t 16 | , std::vector{} 17 | ); 18 | 19 | for(auto s : output) std::cout << s << " "; 20 | std::cout << "\n"; 21 | 22 | auto u = kumi::tuple{1,3,2,4,0,5,9,6,7}; 23 | 24 | std::cout << kumi::fold_right( [](auto acc, auto e) 25 | { 26 | std::cout << '(' << acc << ',' << e << ")\n"; 27 | return (e 7 | #include 8 | 9 | int main() 10 | { 11 | auto t = kumi::tuple{ 1, 2.3, 0.43f }; 12 | 13 | kumi::for_each( [](auto& m) { m *= 10; } 14 | , t 15 | ); 16 | 17 | std::cout << t << "\n"; 18 | } 19 | -------------------------------------------------------------------------------- /test/doc/for_each_index.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | 9 | int main() 10 | { 11 | auto t = kumi::tuple{ 1, 2.3, 0.43f }; 12 | 13 | kumi::for_each_index( [](auto i, auto& m) { m += (i+1)*10; } 14 | , t 15 | ); 16 | 17 | std::cout << t << "\n"; 18 | } 19 | -------------------------------------------------------------------------------- /test/doc/forward_as_tuple.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | template 12 | std::vector build(Data d) 13 | { 14 | return std::vector ( kumi::get<0>(d) 15 | , std::move(kumi::get<1>(d)) 16 | ); 17 | } 18 | 19 | int main() 20 | { 21 | auto v = build( kumi::forward_as_tuple(4,std::string{"the text !"})); 22 | 23 | for(auto const& s : v) 24 | std::cout << s << "\n"; 25 | } 26 | -------------------------------------------------------------------------------- /test/doc/from_tuple.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | #include 9 | 10 | struct my_struct 11 | { 12 | int i; 13 | float f; 14 | std::string name; 15 | }; 16 | 17 | int main() 18 | { 19 | auto a = kumi::make_tuple(1337, 2.3475f, "John"); 20 | auto b = from_tuple( a ); 21 | 22 | std::cout << a << "\n"; 23 | std::cout << b.i << ' ' << b.f << ' ' << b.name << "\n"; 24 | } 25 | -------------------------------------------------------------------------------- /test/doc/generate.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | 9 | int main() 10 | { 11 | auto t = [](auto p){ return 42.63 + p; }; 12 | std::cout << kumi::generate<7>(t) << "\n"; 13 | } 14 | -------------------------------------------------------------------------------- /test/doc/get.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | 9 | int main() 10 | { 11 | using namespace kumi::literals; 12 | 13 | kumi::tuple t = { 1, 2.3, 4.5f, '@' }; 14 | 15 | std::cout << kumi::get<0>(t) << "\n"; 16 | std::cout << kumi::get<1>(t) << "\n"; 17 | std::cout << kumi::get<2>(t) << "\n"; 18 | 19 | kumi::get<3>(t)++; 20 | 21 | std::cout << kumi::get<3>(t) << "\n"; 22 | } 23 | -------------------------------------------------------------------------------- /test/doc/index.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | 9 | int main() 10 | { 11 | using namespace kumi::literals; 12 | 13 | auto v = 42_c; 14 | auto w = kumi::index<63>; 15 | 16 | std::cout << v << "\n"; 17 | std::cout << w << "\n"; 18 | } 19 | -------------------------------------------------------------------------------- /test/doc/inner_product.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | #include 9 | 10 | int main() 11 | { 12 | auto bits = kumi::tuple{ 1, 0,1,0,0,1}; 13 | auto base = kumi::tuple{32,16,8,4,2,1}; 14 | 15 | std::cout << 0b101001L << "\n"; 16 | std::cout << kumi::inner_product(bits, base, 0) << "\n"; 17 | } 18 | -------------------------------------------------------------------------------- /test/doc/iota.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | 9 | int main() 10 | { 11 | std::cout << kumi::iota<10>(3.57f) << "\n"; 12 | } 13 | -------------------------------------------------------------------------------- /test/doc/locate.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | #include 9 | 10 | int main() 11 | { 12 | auto t = kumi::tuple{1, 2., 0ULL, 3.f, 'z'}; 13 | 14 | std::cout << std::boolalpha 15 | << kumi::locate( t, kumi::predicate() ) << "\n"; 16 | 17 | std::cout << std::boolalpha << kumi::locate( t, [](auto e) { return e > 3; } ) << "\n"; 18 | } 19 | -------------------------------------------------------------------------------- /test/doc/make_tuple.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | #include 9 | 10 | int main() 11 | { 12 | int k = 99; 13 | auto t = kumi::make_tuple( 1, 2.3, 4.5f, '@', std::ref(k)); 14 | 15 | std::cout << t << "\n"; 16 | 17 | // Reference access 18 | get<4>(t)++; 19 | std::cout << k << "\n"; 20 | } 21 | -------------------------------------------------------------------------------- /test/doc/map.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | 9 | int main() 10 | { 11 | auto lhs = kumi::tuple{1,2,3}; 12 | auto rhs = kumi::tuple{2.5,3.6,4.7}; 13 | 14 | auto res = kumi::map( [](auto l, auto r) { return l*r; }, lhs, rhs); 15 | 16 | std::cout << res << "\n"; 17 | } 18 | -------------------------------------------------------------------------------- /test/doc/map_index.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | 9 | int main() 10 | { 11 | auto lhs = kumi::tuple{1,2,3}; 12 | auto rhs = kumi::tuple{2.4,4.6,6.8}; 13 | 14 | auto res = kumi::map_index( [](auto i, auto l, auto r) { return 1000*(i+1)+(l*r); } 15 | , lhs, rhs 16 | ); 17 | 18 | std::cout << res << "\n"; 19 | } 20 | -------------------------------------------------------------------------------- /test/doc/max.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | 9 | int main() 10 | { 11 | auto f0 = kumi::tuple {1, 'A', 99.77f, 3. }; 12 | auto f1 = kumi::tuple {2., f0, 3.f }; 13 | 14 | std::cout << kumi::max(f0) << "\n"; 15 | std::cout << kumi::max(f1, [](auto m) { return sizeof(m); }) << "\n"; 16 | } 17 | -------------------------------------------------------------------------------- /test/doc/max_flat.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | 9 | int main() 10 | { 11 | auto f0 = kumi::tuple {2., kumi::tuple {1., 'u', 3. }, 3.f }; 12 | 13 | std::cout << kumi::max_flat (f0 , [](auto m) { return sizeof(m); }) << "\n"; 14 | } 15 | -------------------------------------------------------------------------------- /test/doc/min.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | 9 | int main() 10 | { 11 | auto f0 = kumi::tuple {1, 'A', -9.77f, 3. }; 12 | auto f1 = kumi::tuple {2., f0, 3.f }; 13 | 14 | std::cout << kumi::min(f0, [](auto m) { return sizeof(m); }) << "\n"; 15 | std::cout << kumi::min(f1, [](auto m) { return sizeof(m); }) << "\n"; 16 | } 17 | -------------------------------------------------------------------------------- /test/doc/min_flat.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | 9 | int main() 10 | { 11 | auto f0 = kumi::tuple {2., kumi::tuple {1., 'u', 3. }, 3.f }; 12 | 13 | std::cout << kumi::min_flat (f0 , [](auto m) { return sizeof(m); }) << "\n"; 14 | } 15 | -------------------------------------------------------------------------------- /test/doc/none_of.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | 9 | int main() 10 | { 11 | auto t = kumi::tuple{1,2.,3.f}; 12 | std::cout << std::boolalpha << kumi::none_of( t, [](auto e) { return e > 10.; }) << "\n"; 13 | std::cout << std::boolalpha << kumi::none_of( 8, [](auto e) { return e > 10.; }) << "\n"; 14 | 15 | auto u = kumi::tuple{0,0.,0.f}; 16 | std::cout << std::boolalpha << kumi::none_of( u ) << "\n"; 17 | } 18 | -------------------------------------------------------------------------------- /test/doc/partition.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | #include 9 | 10 | int main() 11 | { 12 | int a = 4; 13 | double b = 3.1415; 14 | float c = 0.01f; 15 | 16 | auto original = kumi::tuple{a,&a,b,&b,c,&c,'z',nullptr}; 17 | std::cout << original << "\n"; 18 | 19 | std::cout << "Pointers first: " << kumi::partition(original) << "\n"; 20 | std::cout << "Real first: " << kumi::partition(original) << "\n"; 21 | std::cout << "nullptr first: " << kumi::partition(original) << "\n"; 22 | } 23 | -------------------------------------------------------------------------------- /test/doc/pop_back.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | 9 | int main() 10 | { 11 | std::cout << kumi::pop_back( kumi::tuple{} ) << "\n"; 12 | 13 | kumi::tuple t{1,2.,3.4f}; 14 | std::cout << t << "\n"; 15 | std::cout << kumi::pop_back(t) << "\n"; 16 | } 17 | -------------------------------------------------------------------------------- /test/doc/pop_front.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | 9 | int main() 10 | { 11 | std::cout << kumi::pop_front( kumi::tuple{} ) << "\n"; 12 | 13 | kumi::tuple t{1,2.,3.4f}; 14 | std::cout << t << "\n"; 15 | std::cout << kumi::pop_front(t) << "\n"; 16 | } 17 | -------------------------------------------------------------------------------- /test/doc/prod.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | 9 | int main() 10 | { 11 | auto t = kumi::tuple{2.,5,short{3},'\4'}; 12 | 13 | std::cout << kumi::prod(t, 10) << "\n"; 14 | std::cout << kumi::prod(t) << "\n"; 15 | } 16 | -------------------------------------------------------------------------------- /test/doc/push_back.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | 9 | int main() 10 | { 11 | std::cout << kumi::push_back( kumi::tuple{}, 63.21) << "\n"; 12 | 13 | kumi::tuple t{1,2.,3.4f}; 14 | std::cout << t << "\n"; 15 | std::cout << kumi::push_back(t, 'Z') << "\n"; 16 | } 17 | -------------------------------------------------------------------------------- /test/doc/push_front.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | 9 | int main() 10 | { 11 | std::cout << kumi::push_front( kumi::tuple{}, 63.21) << "\n"; 12 | 13 | kumi::tuple t{1,2.,3.4f}; 14 | std::cout << t << "\n"; 15 | std::cout << kumi::push_front(t, 'Z') << "\n"; 16 | } 17 | -------------------------------------------------------------------------------- /test/doc/reorder.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | 9 | int main() 10 | { 11 | auto values = kumi::tuple { 1, 'a', 0.1 }; 12 | 13 | std::cout << values << "\n"; 14 | std::cout << kumi::reorder<2,1,0>(values) << "\n"; 15 | std::cout << kumi::reorder<2,1,0,1,2>(values) << "\n"; 16 | std::cout << kumi::reorder<1,1>(values) << "\n"; 17 | } 18 | -------------------------------------------------------------------------------- /test/doc/reverse.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | 9 | int main() 10 | { 11 | auto values = kumi::tuple { 1, 'a', 0.1 }; 12 | 13 | std::cout << values << "\n"; 14 | std::cout << kumi::reverse(values) << "\n"; 15 | } 16 | -------------------------------------------------------------------------------- /test/doc/split.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | 9 | int main() 10 | { 11 | using namespace kumi::literals; 12 | 13 | kumi::tuple a = { 1, 2.3, 4.5f,'6',"7", short{89} }; 14 | 15 | auto[first, second] = split(a, 3_c); 16 | 17 | std::cout << a << "\n"; 18 | std::cout << first << "\n"; 19 | std::cout << second << "\n"; 20 | } 21 | -------------------------------------------------------------------------------- /test/doc/subscript.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | 9 | int main() 10 | { 11 | using namespace kumi::literals; 12 | 13 | kumi::tuple t = { 1, 2.3, 4.5f, '@' }; 14 | 15 | std::cout << t[0_c] << "\n"; 16 | std::cout << t[1_c] << "\n"; 17 | std::cout << t[2_c] << "\n"; 18 | 19 | t[3_c]++; 20 | 21 | std::cout << t[kumi::index<3>] << "\n"; 22 | } 23 | -------------------------------------------------------------------------------- /test/doc/sum.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | 9 | int main() 10 | { 11 | auto t = kumi::tuple{2.,1,short{55},' '}; 12 | 13 | std::cout << kumi::sum(t, 100) << "\n"; 14 | std::cout << kumi::sum(t) << "\n"; 15 | } 16 | -------------------------------------------------------------------------------- /test/doc/tie.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | 9 | auto generate() 10 | { 11 | return kumi::tuple{1,2.3,4.56f}; 12 | } 13 | 14 | int main() 15 | { 16 | int i; 17 | double d; 18 | float f; 19 | 20 | kumi::tie( i,d,f ) = generate(); 21 | 22 | std::cout << i << " " << d << " " << f << "\n"; 23 | } 24 | -------------------------------------------------------------------------------- /test/doc/to_ref.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | int main() 9 | { 10 | auto original = kumi::make_tuple(0,'0',0.f); 11 | auto ref = kumi::to_ref( original ); 12 | 13 | std::cout << original << "\n"; 14 | 15 | kumi::get<0>(ref) = 9; 16 | kumi::get<1>(ref) = 'z'; 17 | kumi::get<2>(ref) = 3.14159f; 18 | 19 | std::cout << original << "\n"; 20 | } 21 | -------------------------------------------------------------------------------- /test/doc/to_tuple.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | struct pixel 13 | { 14 | int r, g, b; 15 | }; 16 | 17 | template 18 | decltype(auto) get(pixel const& p) noexcept 19 | { 20 | if constexpr(I==0) return p.r; 21 | if constexpr(I==1) return p.g; 22 | if constexpr(I==2) return p.b; 23 | } 24 | 25 | template 26 | decltype(auto) get(pixel& p) noexcept 27 | { 28 | if constexpr(I==0) return p.r; 29 | if constexpr(I==1) return p.g; 30 | if constexpr(I==2) return p.b; 31 | } 32 | 33 | // Opt-in for Product Type semantic 34 | template<> 35 | struct kumi::is_product_type : std::true_type 36 | {}; 37 | 38 | // Adapt as structured bindable type 39 | template<> 40 | struct std::tuple_size 41 | : std::integral_constant {}; 42 | 43 | template struct std::tuple_element { using type = int; }; 44 | 45 | int main() 46 | { 47 | pixel a = { 37, 15, 27 }; 48 | auto b = kumi::to_tuple(a); 49 | 50 | std::cout << b << "\n"; 51 | } 52 | -------------------------------------------------------------------------------- /test/doc/transpose.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | 9 | int main() 10 | { 11 | auto values = kumi::tuple { kumi::tuple{ 1, 'a', 0.1 } 12 | , kumi::tuple{ 2, 'b', 0.01 } 13 | }; 14 | 15 | auto r = kumi::transpose(values ); 16 | std::cout << r << "\n"; 17 | } 18 | -------------------------------------------------------------------------------- /test/doc/zip.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | KUMI - Compact Tuple Tools 3 | Copyright : KUMI Project Contributors 4 | SPDX-License-Identifier: BSL-1.0 5 | **/ 6 | #include 7 | #include 8 | 9 | int main() 10 | { 11 | auto nbrs = kumi::tuple{1,2,3}; 12 | auto ltrs = kumi::tuple{'a','b','c'}; 13 | auto ratio = kumi::tuple{0.1,0.01,0.001}; 14 | 15 | auto r = kumi::zip( nbrs, ltrs, ratio ); 16 | std::cout << r << "\n"; 17 | } 18 | -------------------------------------------------------------------------------- /test/integration/cpm-test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ##====================================================================================================================== 2 | ## KUMI - Compact C++20 Tuple Toolbox 3 | ## Copyright : KUMI Project Contributors 4 | ## SPDX-License-Identifier: BSL-1.0 5 | ##====================================================================================================================== 6 | cmake_minimum_required(VERSION 3.18) 7 | project(kumi-cpm-test LANGUAGES CXX) 8 | enable_testing() 9 | 10 | message(STATUS "Testing CPM for branch ${GIT_BRANCH}") 11 | 12 | # Setup CPM 13 | include(cpm.cmake) 14 | 15 | # Add dependencies 16 | CPMAddPackage ( NAME kumi 17 | GIT_REPOSITORY "https://github.com/jfalcou/kumi.git" 18 | GIT_TAG "${GIT_BRANCH}" 19 | OPTIONS "KUMI_BUILD_TEST OFF" 20 | ) 21 | 22 | # Use kumi 23 | add_executable(test_kumi ../main.cpp) 24 | target_link_libraries(test_kumi PUBLIC kumi::kumi) 25 | add_test(NAME test_kumi COMMAND test_kumi) 26 | -------------------------------------------------------------------------------- /test/integration/fetch-test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ##====================================================================================================================== 2 | ## KUMI - Compact C++20 Tuple Toolbox 3 | ## Copyright : KUMI Project Contributors 4 | ## SPDX-License-Identifier: BSL-1.0 5 | ##====================================================================================================================== 6 | cmake_minimum_required(VERSION 3.22) 7 | project(kumi-fetch-test LANGUAGES CXX) 8 | enable_testing() 9 | 10 | message(STATUS "Testing FetchContent for branch ${GIT_BRANCH}") 11 | 12 | # Enable FetchContent 13 | include(FetchContent) 14 | 15 | # Retrieve KUMI from relative git directory 16 | FetchContent_Declare(kumi 17 | GIT_REPOSITORY "https://github.com/jfalcou/kumi.git" 18 | GIT_TAG ${GIT_BRANCH} 19 | ) 20 | 21 | # make available 22 | FetchContent_MakeAvailable(kumi) 23 | 24 | add_executable(test_kumi ../main.cpp) 25 | target_link_libraries(test_kumi PUBLIC kumi::kumi) 26 | add_test(NAME test_kumi COMMAND test_kumi) 27 | -------------------------------------------------------------------------------- /test/integration/install-test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ##====================================================================================================================== 2 | ## KUMI - Compact C++20 Tuple Toolbox 3 | ## Copyright : KUMI Project Contributors 4 | ## SPDX-License-Identifier: BSL-1.0 5 | ##====================================================================================================================== 6 | cmake_minimum_required(VERSION 3.22) 7 | project(kumi-install-test LANGUAGES CXX) 8 | enable_testing() 9 | 10 | find_package(kumi CONFIG REQUIRED) 11 | add_executable(test_kumi ../main.cpp) 12 | target_link_libraries(test_kumi PUBLIC kumi::kumi) 13 | add_test(NAME test_kumi COMMAND test_kumi) 14 | -------------------------------------------------------------------------------- /test/integration/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | auto get_student(int id) 5 | { 6 | if (id == 0) return kumi::make_tuple(3.8, 'A', "Lisa Simpson"); 7 | else if (id == 1) return kumi::make_tuple(2.9, 'C', "Milhouse Van Houten"); 8 | else if (id == 2) return kumi::make_tuple(1.7, 'D', "Ralph Wiggum"); 9 | else return kumi::make_tuple(0., 'F', "Unknown"); 10 | } 11 | 12 | int main() 13 | { 14 | auto student0 = get_student(0); 15 | 16 | std::cout << "ID: 0, " 17 | << "GPA: " << kumi::get<0>(student0) << ", " 18 | << "grade: " << kumi::get<1>(student0) << ", " 19 | << "name: " << kumi::get<2>(student0) << '\n'; 20 | 21 | auto [ gpa1, grade1, name1 ] = get_student(1); 22 | std::cout << "ID: 1, " 23 | << "GPA: " << gpa1 << ", " 24 | << "grade: " << grade1 << ", " 25 | << "name: " << name1 << '\n'; 26 | std::cout << "\n"; 27 | 28 | auto all_students = kumi::make_tuple(get_student(0),get_student(1),get_student(2)); 29 | 30 | kumi::for_each_index( [](auto i, auto const& m) { std::cout << "Data #" << i << " : " << m << "\n";} 31 | , all_students 32 | ); 33 | std::cout << "\n"; 34 | 35 | auto grades = kumi::get<0>(kumi::transpose(all_students)); 36 | std::cout << grades << "\n"; 37 | 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /test/unit/access.cpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #define TTS_MAIN 9 | #include 10 | #include 11 | 12 | TTS_CASE("Check access to kumi::tuple via indexing") 13 | { 14 | using namespace kumi::literals; 15 | 16 | kumi::tuple t1 = {1}; 17 | kumi::tuple t2 = {1.f, 2}; 18 | kumi::tuple t3 = {1., 2.f, 3}; 19 | kumi::tuple t4 = {'1', 2., 3.f, 4}; 20 | 21 | t1[0_c] = 42; 22 | TTS_EQUAL(t1[0_c], 42); 23 | 24 | t2[0_c] = 4.2f; 25 | t2[1_c] = 69; 26 | TTS_EQUAL(t2[0_c], 4.2f); 27 | TTS_EQUAL(t2[1_c], 69); 28 | 29 | t3[0_c] = 13.37; 30 | t3[1_c] = 4.2f; 31 | t3[2_c] = 40; 32 | TTS_EQUAL(t3[0_c], 13.37); 33 | TTS_EQUAL(t3[1_c], 4.2f); 34 | TTS_EQUAL(t3[2_c], 40); 35 | 36 | t4[0_c] = 'z'; 37 | t4[1_c] = 6.9; 38 | t4[2_c] = 4.2f; 39 | t4[3_c] = 1337; 40 | TTS_EQUAL(t4[0_c], 'z'); 41 | TTS_EQUAL(t4[1_c], 6.9); 42 | TTS_EQUAL(t4[2_c], 4.2f); 43 | TTS_EQUAL(t4[3_c], 1337); 44 | }; 45 | 46 | TTS_CASE("Check constexpr access to kumi::tuple via indexing") 47 | { 48 | using namespace kumi::literals; 49 | 50 | constexpr kumi::tuple t1 = {1}; 51 | constexpr kumi::tuple t2 = {1.f, 2}; 52 | constexpr kumi::tuple t3 = {1., 2.f, 3}; 53 | constexpr kumi::tuple t4 = {'1', 2., 3.f, 4}; 54 | 55 | TTS_CONSTEXPR_EQUAL(get<0>(t1), t1[0_c]); 56 | 57 | TTS_CONSTEXPR_EQUAL(get<0>(t2), t2[0_c]); 58 | TTS_CONSTEXPR_EQUAL(get<1>(t2), t2[1_c]); 59 | 60 | TTS_CONSTEXPR_EQUAL(get<0>(t3), t3[0_c]); 61 | TTS_CONSTEXPR_EQUAL(get<1>(t3), t3[1_c]); 62 | TTS_CONSTEXPR_EQUAL(get<2>(t3), t3[2_c]); 63 | 64 | TTS_CONSTEXPR_EQUAL(get<0>(t4), t4[0_c]); 65 | TTS_CONSTEXPR_EQUAL(get<1>(t4), t4[1_c]); 66 | TTS_CONSTEXPR_EQUAL(get<2>(t4), t4[2_c]); 67 | TTS_CONSTEXPR_EQUAL(get<3>(t4), t4[3_c]); 68 | }; 69 | -------------------------------------------------------------------------------- /test/unit/adapt.cpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #define TTS_MAIN 9 | #include 10 | #include 11 | 12 | 13 | // -- 14 | // -- Make a pre adapted type 15 | // -- 16 | struct some_box 17 | { 18 | using is_product_type = void; 19 | 20 | int i; 21 | double f; 22 | char c; 23 | 24 | template 25 | friend constexpr auto const& get(some_box const& s) noexcept requires(I < 3) 26 | { 27 | if constexpr(I==0) return s.i; 28 | if constexpr(I==1) return s.f; 29 | if constexpr(I==2) return s.c; 30 | } 31 | 32 | template 33 | friend constexpr auto & get(some_box& s) noexcept requires(I < 3) 34 | { 35 | if constexpr(I==0) return s.i; 36 | if constexpr(I==1) return s.f; 37 | if constexpr(I==2) return s.c; 38 | } 39 | }; 40 | 41 | template<> struct std::tuple_size : std::integral_constant {}; 42 | template<> struct std::tuple_element<0,some_box> { using type = int; }; 43 | template<> struct std::tuple_element<1,some_box> { using type = double; }; 44 | template<> struct std::tuple_element<2,some_box> { using type = char; }; 45 | 46 | // -- 47 | 48 | TTS_CASE("Check adapted types model kumi::product_type concept") 49 | { 50 | TTS_EXPECT ( kumi::product_type ); 51 | TTS_EXPECT ( (kumi::product_type> )); 52 | TTS_EXPECT_NOT( (kumi::product_type>)); 53 | }; 54 | 55 | TTS_CASE("Check adapted type behave like a product_type") 56 | { 57 | auto r = kumi::apply( [](auto... x) { return (x + ...); }, some_box{1,2.5,'4'}); 58 | TTS_EQUAL(r, 55.5); 59 | 60 | auto zz = kumi::zip( some_box{1,2.5,'4'}, some_box{99,69.25,'Z'}); 61 | TTS_EQUAL ( zz, ( kumi::tuple { kumi::tuple{1 , 99 } 62 | , kumi::tuple{2.5 , 69.25 } 63 | , kumi::tuple{'4' ,'Z' } 64 | }) 65 | ); 66 | 67 | auto cc = kumi::cat( some_box{1,2.5,'4'}, some_box{99,69.25,'Z'}); 68 | TTS_EQUAL ( cc, ( kumi::tuple {1, 2.5, '4', 99, 69.25, 'Z'}) ); 69 | }; 70 | 71 | TTS_CASE("Check adapted external type behave like a product_type") 72 | { 73 | auto r = kumi::apply( [](auto... x) { return (x + ...); }, std::array{1,2,5,4}); 74 | TTS_EQUAL(r, 12); 75 | 76 | auto zz = kumi::zip( std::array{1,2,5}, std::array{0.1,2.3,4.5}); 77 | TTS_EQUAL ( zz, ( kumi::tuple { kumi::tuple{1 , 0.1 } 78 | , kumi::tuple{2 , 2.3 } 79 | , kumi::tuple{5 , 4.5 } 80 | }) 81 | ); 82 | 83 | auto cc = kumi::cat( std::array{1,2,5}, std::array{0.1,2.3,4.5} ); 84 | TTS_EQUAL ( cc, ( kumi::tuple {1, 2, 5, 0.1, 2.3, 4.5}) ); 85 | }; 86 | -------------------------------------------------------------------------------- /test/unit/aggregate_ctor.cpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #define TTS_MAIN 9 | #include 10 | #include 11 | 12 | TTS_CASE("Check tuple_element of kumi::tuple") 13 | { 14 | auto aggregate = kumi::tuple{'1', 2., 3.f}; 15 | TTS_TYPE_IS((std::tuple_element_t<0, decltype(aggregate)>), char); 16 | TTS_TYPE_IS((std::tuple_element_t<1, decltype(aggregate)>), double); 17 | TTS_TYPE_IS((std::tuple_element_t<2, decltype(aggregate)>), float); 18 | }; 19 | 20 | TTS_CASE("Check construction of kumi::tuple as an aggregate") 21 | { 22 | auto t0 = kumi::tuple{}; 23 | auto t1 = kumi::tuple{1}; 24 | auto t2 = kumi::tuple{1.f, 2}; 25 | auto t3 = kumi::tuple{1., 2.f, 3}; 26 | auto t4 = kumi::tuple{'1', 2., 3.f, 4}; 27 | 28 | TTS_CONSTEXPR_EXPECT((kumi::sized_product_type)); 29 | TTS_EQUAL(t0.size(), 0ULL); 30 | 31 | TTS_CONSTEXPR_EXPECT((kumi::sized_product_type)); 32 | TTS_EQUAL(t1.size(), 1ULL); 33 | TTS_EQUAL(get<0>(t1), 1); 34 | 35 | TTS_CONSTEXPR_EXPECT((kumi::sized_product_type)); 36 | TTS_EQUAL(t2.size(), 2ULL); 37 | TTS_EQUAL(get<0>(t2), 1.f); 38 | TTS_EQUAL(get<1>(t2), 2); 39 | 40 | TTS_CONSTEXPR_EXPECT((kumi::sized_product_type)); 41 | TTS_EQUAL(t3.size(), 3ULL); 42 | TTS_EQUAL(get<0>(t3), 1.); 43 | TTS_EQUAL(get<1>(t3), 2.f); 44 | TTS_EQUAL(get<2>(t3), 3); 45 | 46 | TTS_CONSTEXPR_EXPECT((kumi::sized_product_type)); 47 | TTS_EQUAL(t4.size(), 4ULL); 48 | TTS_EQUAL(get<0>(t4), '1'); 49 | TTS_EQUAL(get<1>(t4), 2.); 50 | TTS_EQUAL(get<2>(t4), 3.f); 51 | TTS_EQUAL(get<3>(t4), 4); 52 | }; 53 | 54 | TTS_CASE("Check construction of kumi::tuple as a constexpr aggregate") 55 | { 56 | constexpr auto t0 = kumi::tuple{}; 57 | constexpr auto t1 = kumi::tuple{1}; 58 | constexpr auto t2 = kumi::tuple{1.f, 2}; 59 | constexpr auto t3 = kumi::tuple{1., 2.f, 3}; 60 | constexpr auto t4 = kumi::tuple{'1', 2., 3.f, 4}; 61 | 62 | TTS_CONSTEXPR_EXPECT((kumi::sized_product_type)); 63 | TTS_CONSTEXPR_EQUAL(t0.size(), 0ULL); 64 | 65 | TTS_CONSTEXPR_EXPECT((kumi::sized_product_type)); 66 | TTS_CONSTEXPR_EQUAL(t1.size(), 1ULL); 67 | TTS_CONSTEXPR_EQUAL(get<0>(t1), 1); 68 | 69 | TTS_CONSTEXPR_EXPECT((kumi::sized_product_type)); 70 | TTS_CONSTEXPR_EQUAL(t2.size(), 2ULL); 71 | TTS_CONSTEXPR_EQUAL(get<0>(t2), 1.f); 72 | TTS_CONSTEXPR_EQUAL(get<1>(t2), 2); 73 | 74 | TTS_CONSTEXPR_EXPECT((kumi::sized_product_type)); 75 | TTS_CONSTEXPR_EQUAL(t3.size(), 3ULL); 76 | TTS_CONSTEXPR_EQUAL(get<0>(t3), 1.); 77 | TTS_CONSTEXPR_EQUAL(get<1>(t3), 2.f); 78 | TTS_CONSTEXPR_EQUAL(get<2>(t3), 3); 79 | 80 | TTS_CONSTEXPR_EXPECT((kumi::sized_product_type)); 81 | TTS_CONSTEXPR_EQUAL(t4.size(), 4ULL); 82 | TTS_CONSTEXPR_EQUAL(get<0>(t4), '1'); 83 | TTS_CONSTEXPR_EQUAL(get<1>(t4), 2.); 84 | TTS_CONSTEXPR_EQUAL(get<2>(t4), 3.f); 85 | TTS_CONSTEXPR_EQUAL(get<3>(t4), 4); 86 | }; 87 | -------------------------------------------------------------------------------- /test/unit/apply.cpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #define TTS_MAIN 9 | #include 10 | #include 11 | #include 12 | 13 | struct A { void operator()(auto&&...) & {} }; 14 | struct B { void operator()(auto&&) & {} }; 15 | struct C { void f(int){} int x; }; 16 | 17 | TTS_CASE("Check apply SFINAE compliance") 18 | { 19 | A a; 20 | B b; 21 | C c; 22 | auto t = kumi::make_tuple(1,2,3,4); 23 | auto u0 = kumi::make_tuple(std::ref(c), 1); 24 | kumi::tuple, int> u1{c,1}; 25 | kumi::tuple u2{&c,2}; 26 | auto u3 = kumi::make_tuple(std::ref(c)); 27 | kumi::tuple> u4{c}; 28 | auto u5 = kumi::make_tuple(&c); 29 | 30 | TTS_EXPECT_COMPILES(a, t, { kumi::apply(a, t); } ); 31 | TTS_EXPECT_NOT_COMPILES(b, t, { kumi::apply(b, t); } ); 32 | TTS_EXPECT_COMPILES(u0, { kumi::apply(&C::f, u0); } ); 33 | TTS_EXPECT_COMPILES(u1, { kumi::apply(&C::f, u1); } ); 34 | TTS_EXPECT_COMPILES(u2, { kumi::apply(&C::f, u2); } ); 35 | TTS_EXPECT_COMPILES(u3, { kumi::apply(&C::x, u3); } ); 36 | TTS_EXPECT_COMPILES(u4, { kumi::apply(&C::x, u4); } ); 37 | TTS_EXPECT_COMPILES(u5, { kumi::apply(&C::x, u5); } ); 38 | 39 | struct F0{ 40 | void operator()() && {} 41 | }; 42 | F0 f0{}; 43 | TTS_EXPECT_COMPILES(f0, { kumi::apply(std::move(f0), kumi::tuple{}); }); 44 | TTS_EXPECT_NOT_COMPILES(f0, { kumi::apply(f0, kumi::tuple{}); }); 45 | TTS_EXPECT_NOT_COMPILES(f0, { kumi::apply(std::ref(f0), kumi::tuple{}); }); 46 | struct F1{ 47 | void operator()() & {} 48 | }; 49 | F1 f1{}; 50 | TTS_EXPECT_NOT_COMPILES(f1, { kumi::apply(std::move(f1), kumi::tuple{}); }); 51 | TTS_EXPECT_COMPILES(f1, { kumi::apply(f1, kumi::tuple{}); }); 52 | TTS_EXPECT_COMPILES(f1, { kumi::apply(std::ref(f1), kumi::tuple{}); }); 53 | 54 | struct F2{ 55 | void operator()(int &&){} 56 | }; 57 | F2 f2{}; 58 | TTS_EXPECT_COMPILES(f2, { kumi::apply(f2, kumi::make_tuple(2)); }); 59 | int i2 = 2; 60 | TTS_EXPECT_NOT_COMPILES(f2, i2, { kumi::apply(f2, kumi::forward_as_tuple(i2)); }); 61 | TTS_EXPECT_COMPILES(f2, i2, { kumi::apply(f2, kumi::forward_as_tuple(std::move(i2))); }); 62 | auto t2 = kumi::forward_as_tuple(std::move(i2)); 63 | TTS_EXPECT_NOT_COMPILES(f2, t2, { kumi::apply(f2, t2); }); 64 | }; 65 | 66 | TTS_CASE("Check result::apply behavior") 67 | { 68 | auto lambda = [](auto... m) { return (m + ...); }; 69 | using func_t = decltype(lambda); 70 | 71 | TTS_TYPE_IS((kumi::result::apply_t>), double); 72 | }; 73 | 74 | TTS_CASE("Check apply behavior") 75 | { 76 | TTS_EQUAL((kumi::apply( []() { return 99; }, kumi::tuple{})), 99); 77 | 78 | TTS_EQUAL((kumi::apply( 79 | [](auto... m) { 80 | std::ostringstream s; 81 | ((s << m << " "), ...); 82 | return s.str(); 83 | }, 84 | kumi::tuple {1, '5', "things"})), 85 | "1 5 things "); 86 | 87 | kumi::tuple some_tuple {1, '5', "things"}; 88 | 89 | TTS_EQUAL((some_tuple([](auto... m) { 90 | std::ostringstream s; 91 | ((s << m << " "), ...); 92 | return s.str(); 93 | })), 94 | "1 5 things "); 95 | }; 96 | 97 | TTS_CASE("Check apply constexpr behavior") 98 | { 99 | constexpr auto t1 = []() { 100 | auto it = kumi::tuple {1, 2., 3.f}; 101 | return kumi::apply([](auto... m) { return (m + ...); }, it); 102 | }(); 103 | 104 | constexpr auto t2 = []() { 105 | auto it = kumi::tuple {1, 2., 3.f}; 106 | return it([](auto... m) { return (m + ...); }); 107 | }(); 108 | 109 | constexpr auto empty = []() { return 99; }; 110 | TTS_CONSTEXPR_EQUAL((kumi::apply( empty, kumi::tuple{})), 99); 111 | 112 | TTS_CONSTEXPR_EQUAL(t1, 6.); 113 | TTS_CONSTEXPR_EQUAL(t2, 6.); 114 | }; 115 | -------------------------------------------------------------------------------- /test/unit/apply_traits.cpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #include "kumi/utils/concepts.hpp" 9 | #include 10 | #include 11 | #define TTS_MAIN 12 | #include 13 | #include 14 | 15 | template 16 | struct nary_traits : std::integral_constant 17 | {}; 18 | 19 | TTS_CASE("Check apply_traits behavior") 20 | { 21 | TTS_TYPE_IS ( (kumi::apply_traits_t < nary_traits 22 | , kumi::tuple 23 | >) 24 | , (std::integral_constant) 25 | ); 26 | }; 27 | 28 | template 29 | kumi::apply_traits_t f(T const&) 30 | { 31 | return {}; 32 | } 33 | 34 | template 35 | kumi::apply_traits_t g(T const&) 36 | { 37 | return {}; 38 | } 39 | 40 | template 41 | requires( std::is_floating_point_v && ...) 42 | struct strict_traits 43 | { 44 | using type = bool; 45 | }; 46 | 47 | template 48 | kumi::apply_traits_t h(T const&) 49 | { 50 | return true; 51 | } 52 | 53 | TTS_CASE("Check apply_traits SFINAE compliance") 54 | { 55 | kumi::tuple t; 56 | kumi::tuple u; 57 | 58 | // wrong # of arguments to traits 59 | TTS_EXPECT_COMPILES(t, { f(t); } ); 60 | TTS_EXPECT_NOT_COMPILES(t, { g(t); } ); 61 | 62 | // Unsupported types within tuple 63 | TTS_EXPECT_COMPILES(u, { h(u); } ); 64 | TTS_EXPECT_NOT_COMPILES(t, { h(t); } ); 65 | }; 66 | -------------------------------------------------------------------------------- /test/unit/as_flat_ptr.cpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #define TTS_MAIN 9 | #include 10 | #include 11 | 12 | TTS_CASE("Check tuple::as_flat_ptr function behavior") 13 | { 14 | auto t = kumi::tuple{3.25f, kumi::tuple {2., kumi::tuple {2., 1, short {55}}, short {55}}, 'a'}; 15 | auto f = kumi::as_flat_ptr(t); 16 | 17 | TTS_EQUAL(get<0>(f), & get<0>(t) ); 18 | TTS_EQUAL(get<1>(f), & get<0>( get<1>(t) ) ); 19 | TTS_EQUAL(get<2>(f), &get<0>( get<1>( get<1>(t))) ); 20 | TTS_EQUAL(get<3>(f), &get<1>( get<1>( get<1>(t))) ); 21 | TTS_EQUAL(get<4>(f), &get<2>( get<1>( get<1>(t))) ); 22 | TTS_EQUAL(get<5>(f), & get<2>( get<1>(t) ) ); 23 | TTS_EQUAL(get<6>(f), & get<2>(t) ); 24 | }; 25 | -------------------------------------------------------------------------------- /test/unit/back_front.cpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #define TTS_MAIN 9 | #include 10 | #include 11 | 12 | TTS_CASE("Check access via kumi::back") 13 | { 14 | kumi::tuple t1 = {1}; 15 | kumi::tuple t2 = {1.f, 2}; 16 | kumi::tuple t3 = {1., 2.f, 3}; 17 | kumi::tuple t4 = {'1', 2., 3.f, 4}; 18 | 19 | TTS_EQUAL(kumi::back(t1), 1); 20 | kumi::back(t1) = 42; 21 | TTS_EQUAL(kumi::back(t1), 42); 22 | 23 | TTS_EQUAL(kumi::back(t2), 2); 24 | kumi::back(t2) = 42; 25 | TTS_EQUAL(kumi::back(t2), 42); 26 | 27 | TTS_EQUAL(kumi::back(t3), 3); 28 | kumi::back(t3) = 1337; 29 | TTS_EQUAL(kumi::back(t3), 1337); 30 | 31 | TTS_EQUAL(kumi::back(t4), 4); 32 | kumi::back(t4) = 357; 33 | TTS_EQUAL(kumi::back(t4), 357); 34 | }; 35 | 36 | 37 | TTS_CASE("Check access via constexpr kumi::back") 38 | { 39 | TTS_CONSTEXPR_EQUAL(kumi::back(kumi::tuple{1}), 1); 40 | TTS_CONSTEXPR_EQUAL(kumi::back(kumi::tuple{1.f, 2}), 2); 41 | TTS_CONSTEXPR_EQUAL(kumi::back(kumi::tuple{1., 2.f, 3}), 3); 42 | TTS_CONSTEXPR_EQUAL(kumi::back(kumi::tuple{'1', 2., 3.f, 4}), 4); 43 | }; 44 | 45 | TTS_CASE("Check access via kumi::front") 46 | { 47 | kumi::tuple t1 = {1}; 48 | kumi::tuple t2 = {1.f, 2}; 49 | kumi::tuple t3 = {1., 2.f, 3}; 50 | kumi::tuple t4 = {'1', 2., 3.f, 4}; 51 | 52 | TTS_EQUAL(kumi::front(t1), 1); 53 | kumi::front(t1) = 42; 54 | TTS_EQUAL(kumi::front(t1), 42); 55 | 56 | TTS_EQUAL(kumi::front(t2), 1.f); 57 | kumi::front(t2) = 4.2f; 58 | TTS_EQUAL(kumi::front(t2), 4.2f); 59 | 60 | TTS_EQUAL(kumi::front(t3), 1.); 61 | kumi::front(t3) = 13.37; 62 | TTS_EQUAL(kumi::front(t3), 13.37); 63 | 64 | TTS_EQUAL(kumi::front(t4), '1'); 65 | kumi::front(t4) = 'Z'; 66 | TTS_EQUAL(kumi::front(t4), 'Z'); 67 | }; 68 | 69 | TTS_CASE("Check access via constexpr kumi::front") 70 | { 71 | TTS_CONSTEXPR_EQUAL(kumi::front(kumi::tuple{1}), 1 ); 72 | TTS_CONSTEXPR_EQUAL(kumi::front(kumi::tuple{1.f, 2}), 1.f); 73 | TTS_CONSTEXPR_EQUAL(kumi::front(kumi::tuple{1., 2.f, 3}), 1. ); 74 | TTS_CONSTEXPR_EQUAL(kumi::front(kumi::tuple{'1', 2., 3.f, 4}), '1'); 75 | }; 76 | -------------------------------------------------------------------------------- /test/unit/cat.cpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #define TTS_MAIN 9 | #include 10 | #include 11 | 12 | TTS_CASE("Check result::cat behavior") 13 | { 14 | TTS_TYPE_IS ( (kumi::result::cat_t,kumi::tuple>) 15 | , (kumi::tuple) 16 | ); 17 | 18 | TTS_TYPE_IS ( (kumi::result::cat_t,kumi::tuple>) 19 | , (kumi::tuple) 20 | ); 21 | 22 | TTS_TYPE_IS ( (kumi::result::cat_t,kumi::tuple>) 23 | , (kumi::tuple) 24 | ); 25 | 26 | TTS_TYPE_IS ( (kumi::result::cat_t,kumi::tuple,kumi::tuple>) 27 | , (kumi::tuple) 28 | ); 29 | 30 | TTS_TYPE_IS ( (kumi::result::cat_t,kumi::tuple>) 31 | , (kumi::tuple) 32 | ); 33 | 34 | TTS_TYPE_IS ( (kumi::result::cat_t &&>) 35 | , (kumi::tuple) 36 | ); 37 | 38 | TTS_TYPE_IS ( (kumi::result::cat_t &&, kumi::tuple &, kumi::tuple &>) 39 | , (kumi::tuple) 40 | ); 41 | 42 | TTS_TYPE_IS ( (kumi::result::cat_t &&, kumi::tuple &&, kumi::tuple &>) 43 | , (kumi::tuple) 44 | ); 45 | 46 | TTS_TYPE_IS ( (kumi::result::cat_t &&, kumi::tuple &, kumi::tuple &&>) 47 | , (kumi::tuple) 48 | ); 49 | 50 | TTS_TYPE_IS ( (kumi::result::cat_t &&, kumi::tuple &&, kumi::tuple &&>) 51 | , (kumi::tuple) 52 | ); 53 | }; 54 | 55 | TTS_CASE("Check cat(tuple) behavior") 56 | { 57 | short s = 55; 58 | TTS_EQUAL((cat(kumi::tuple {} , kumi::tuple {})), (kumi::tuple {})); 59 | TTS_EQUAL((cat(kumi::tuple {1, 2.}, kumi::tuple {})), (kumi::tuple {1, 2.})); 60 | TTS_EQUAL((cat(kumi::tuple {}, kumi::tuple {1, 2.})), (kumi::tuple {1, 2.})); 61 | TTS_EQUAL((cat(kumi::tuple {1}, kumi::tuple {2., 3.f, 4})), (kumi::tuple {1, 2., 3.f, 4})); 62 | TTS_EQUAL((cat(kumi::tuple {1, 2.}, kumi::tuple {3.f, 4})), (kumi::tuple {1, 2., 3.f, 4})); 63 | TTS_EQUAL((cat(kumi::tuple {1, 2.}, kumi::tuple {3.f, 4}, kumi::tuple {s, 6.7})), 64 | (kumi::tuple {1, 2., 3.f, 4, s, 6.7})); 65 | 66 | // Check behavior with tuple of references 67 | { 68 | auto ref = kumi::tie(s); 69 | auto val = kumi::tuple{3.14f}; 70 | 71 | TTS_EQUAL(kumi::cat(ref, val), (kumi::tuple{s,3.14f}) ); 72 | } 73 | { 74 | auto ref = kumi::tie(s); 75 | auto rref = kumi::tuple{std::move(s)}; 76 | auto val = kumi::tuple{3.14f}; 77 | 78 | TTS_EQUAL(kumi::cat(ref, std::move(rref), val), (kumi::tuple{s,std::move(s),3.14f}) ); 79 | } 80 | }; 81 | 82 | TTS_CASE("Check cat(tuple) constexpr behavior") 83 | { 84 | constexpr short s = 55; 85 | TTS_CONSTEXPR_EQUAL((cat(kumi::tuple {}, kumi::tuple {})), (kumi::tuple {})); 86 | TTS_CONSTEXPR_EQUAL((cat(kumi::tuple {1, 2.}, kumi::tuple {})), (kumi::tuple {1, 2.})); 87 | TTS_CONSTEXPR_EQUAL((cat(kumi::tuple {}, kumi::tuple {1, 2.})), (kumi::tuple {1, 2.})); 88 | TTS_CONSTEXPR_EQUAL((cat(kumi::tuple {1}, kumi::tuple {2., 3.f, 4})), 89 | (kumi::tuple {1, 2., 3.f, 4})); 90 | TTS_CONSTEXPR_EQUAL((cat(kumi::tuple {1, 2.}, kumi::tuple {3.f, 4})), 91 | (kumi::tuple {1, 2., 3.f, 4})); 92 | TTS_CONSTEXPR_EQUAL((cat(kumi::tuple {1, 2.}, kumi::tuple {3.f, 4}, kumi::tuple {s, 6.7})), 93 | (kumi::tuple {1, 2., 3.f, 4, s, 6.7})); 94 | }; 95 | -------------------------------------------------------------------------------- /test/unit/common_reference.cpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #define TTS_MAIN 9 | #include 10 | #include 11 | #include 12 | 13 | TTS_CASE("Check behavior of std::common_reference on kumi::tuple") 14 | { 15 | #if !defined( __ANDROID__ ) 16 | TTS_TYPE_IS ( (std::common_reference_t< kumi::tuple, kumi::tuple&> ) 17 | , (kumi::tuple) 18 | ); 19 | 20 | TTS_TYPE_IS ( (std::common_reference_t< kumi::tuple, kumi::tuple const&> ) 21 | , (kumi::tuple) 22 | ); 23 | 24 | TTS_TYPE_IS ( (std::common_reference_t< kumi::tuple, kumi::tuple&> ) 25 | , (kumi::tuple) 26 | ); 27 | #else 28 | TTS_PASS("No support for common_reference on ANDROID"); 29 | #endif 30 | 31 | }; 32 | -------------------------------------------------------------------------------- /test/unit/convert.cpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #define TTS_MAIN 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | TTS_CASE("Check tuple to tuple conversion") 16 | { 17 | kumi::tuple in{short{49},62.5f}; 18 | 19 | TTS_EQUAL ( (in.cast() ) , (kumi::tuple{49 ,62.5}) ); 20 | TTS_EQUAL ( (in.cast() ) , (kumi::tuple{'1',62}) ); 21 | 22 | TTS_EQUAL ( kumi::tuple{"some text"}.cast() 23 | , kumi::tuple{std::string("some text")} 24 | ); 25 | }; 26 | 27 | TTS_CASE("Check tuple to tuple constexpr conversion") 28 | { 29 | constexpr kumi::tuple in{short{49},62.5f}; 30 | 31 | TTS_CONSTEXPR_EQUAL ( (in.cast() ) , (kumi::tuple{49 ,62.5}) ); 32 | TTS_CONSTEXPR_EQUAL ( (in.cast() ) , (kumi::tuple{'1',62}) ); 33 | }; 34 | 35 | struct my_struct 36 | { 37 | std::size_t n; 38 | double data; 39 | constexpr auto operator<=>(my_struct const&) const = default; 40 | }; 41 | 42 | TTS_CASE("Check tuple to constructible type conversion") 43 | { 44 | kumi::tuple in{std::size_t{9}, 13.37}; 45 | 46 | TTS_EQUAL ( kumi::from_tuple(in), (my_struct{9,13.37}) ); 47 | }; 48 | 49 | TTS_CASE("Check tuple to constructible type constexpr conversion") 50 | { 51 | constexpr kumi::tuple in{std::size_t{9}, 13.37}; 52 | 53 | TTS_CONSTEXPR_EQUAL ( kumi::from_tuple(in), (my_struct{9,13.37}) ); 54 | }; 55 | -------------------------------------------------------------------------------- /test/unit/extract.cpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #define TTS_MAIN 9 | #include 10 | #include 11 | 12 | TTS_CASE("Check tuple::extract behavior") 13 | { 14 | using namespace kumi::literals; 15 | 16 | kumi::tuple t = {'1', 2., 3.f, 4}; 17 | 18 | TTS_EQUAL((kumi::extract(t,0_c)) , (kumi::tuple{'1', 2., 3.f, 4}) ); 19 | TTS_EQUAL((kumi::extract(t,0_c, 4_c)) , (kumi::tuple{'1', 2., 3.f, 4}) ); 20 | TTS_EQUAL((kumi::extract(t,0_c, 3_c)) , (kumi::tuple {'1', 2., 3.f}) ); 21 | TTS_EQUAL((kumi::extract(t,0_c, 2_c)) , (kumi::tuple {'1', 2.}) ); 22 | TTS_EQUAL((kumi::extract(t,0_c, 1_c)) , kumi::tuple {'1'} ); 23 | TTS_EQUAL((kumi::extract(t,0_c, 0_c)) , kumi::tuple {} ); 24 | TTS_EQUAL((kumi::extract(t,1_c)) , (kumi::tuple {2., 3.f, 4}) ); 25 | TTS_EQUAL((kumi::extract(t,1_c, 4_c)) , (kumi::tuple {2., 3.f, 4}) ); 26 | TTS_EQUAL((kumi::extract(t,1_c, 3_c)) , (kumi::tuple {2., 3.f}) ); 27 | TTS_EQUAL((kumi::extract(t,1_c, 2_c)) , kumi::tuple {2.} ); 28 | TTS_EQUAL((kumi::extract(t,1_c, 1_c)) , kumi::tuple {} ); 29 | TTS_EQUAL((kumi::extract(t,2_c)) , (kumi::tuple {3.f, 4}) ); 30 | TTS_EQUAL((kumi::extract(t,2_c, 4_c)) , (kumi::tuple {3.f, 4}) ); 31 | TTS_EQUAL((kumi::extract(t,2_c, 3_c)) , (kumi::tuple {3.f}) ); 32 | TTS_EQUAL((kumi::extract(t,2_c, 2_c)) , kumi::tuple {} ); 33 | TTS_EQUAL((kumi::extract(t,3_c)) , kumi::tuple {4} ); 34 | TTS_EQUAL((kumi::extract(t,3_c, 4_c)) , kumi::tuple {4} ); 35 | TTS_EQUAL((kumi::extract(t,3_c, 3_c)) , kumi::tuple {} ); 36 | TTS_EQUAL((kumi::extract(t,4_c)) , kumi::tuple {} ); 37 | TTS_EQUAL((kumi::extract(t,4_c, 4_c)) , kumi::tuple {} ); 38 | }; 39 | 40 | TTS_CASE("Check tuple::extract constexpr behavior") 41 | { 42 | using namespace kumi::literals; 43 | 44 | constexpr kumi::tuple t = {'1', 2., 3.f, 4}; 45 | 46 | TTS_CONSTEXPR_EQUAL( kumi::extract(t,0_c) , t ); 47 | TTS_CONSTEXPR_EQUAL((kumi::extract(t,0_c, 4_c)) , t ); 48 | TTS_CONSTEXPR_EQUAL((kumi::extract(t,0_c, 3_c)) , (kumi::tuple {'1', 2., 3.f}) ); 49 | TTS_CONSTEXPR_EQUAL((kumi::extract(t,0_c, 2_c)) , (kumi::tuple {'1', 2.}) ); 50 | TTS_CONSTEXPR_EQUAL((kumi::extract(t,0_c, 1_c)) , kumi::tuple {'1'} ); 51 | TTS_CONSTEXPR_EQUAL((kumi::extract(t,0_c, 0_c)) , kumi::tuple {} ); 52 | TTS_CONSTEXPR_EQUAL((kumi::extract(t,1_c)) , (kumi::tuple {2., 3.f, 4}) ); 53 | TTS_CONSTEXPR_EQUAL((kumi::extract(t,1_c, 4_c)) , (kumi::tuple {2., 3.f, 4}) ); 54 | TTS_CONSTEXPR_EQUAL((kumi::extract(t,1_c, 3_c)) , (kumi::tuple {2., 3.f}) ); 55 | TTS_CONSTEXPR_EQUAL((kumi::extract(t,1_c, 2_c)) , kumi::tuple {2.} ); 56 | TTS_CONSTEXPR_EQUAL((kumi::extract(t,1_c, 1_c)) , kumi::tuple {} ); 57 | TTS_CONSTEXPR_EQUAL((kumi::extract(t,2_c)) , (kumi::tuple {3.f, 4}) ); 58 | TTS_CONSTEXPR_EQUAL((kumi::extract(t,2_c, 4_c)) , (kumi::tuple {3.f, 4}) ); 59 | TTS_CONSTEXPR_EQUAL((kumi::extract(t,2_c, 3_c)) , (kumi::tuple {3.f}) ); 60 | TTS_CONSTEXPR_EQUAL((kumi::extract(t,2_c, 2_c)) , kumi::tuple {} ); 61 | TTS_CONSTEXPR_EQUAL((kumi::extract(t,3_c)) , kumi::tuple {4} ); 62 | TTS_CONSTEXPR_EQUAL((kumi::extract(t,3_c, 4_c)) , kumi::tuple {4} ); 63 | TTS_CONSTEXPR_EQUAL((kumi::extract(t,3_c, 3_c)) , kumi::tuple {} ); 64 | TTS_CONSTEXPR_EQUAL((kumi::extract(t,4_c)) , kumi::tuple {} ); 65 | TTS_CONSTEXPR_EQUAL((kumi::extract(t,4_c, 4_c)) , kumi::tuple {} ); 66 | }; 67 | -------------------------------------------------------------------------------- /test/unit/fill.cpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #define TTS_MAIN 9 | #include 10 | #include 11 | 12 | TTS_CASE("Check runtime kumi::fill behavior") 13 | { 14 | TTS_EQUAL ( kumi::fill<1>(1 ) , (kumi::tuple{1} ) ); 15 | TTS_EQUAL ( kumi::fill<2>(2.f ) , (kumi::tuple{2.f, 2.f} ) ); 16 | TTS_EQUAL ( kumi::fill<3>(3. ) , (kumi::tuple{3.,3.,3.} ) ); 17 | TTS_EQUAL ( kumi::fill<7>('7' ) , (kumi::tuple{'7','7','7','7','7','7','7'}) ); 18 | }; 19 | 20 | TTS_CASE("Check constexpr kumi::fill behavior") 21 | { 22 | TTS_CONSTEXPR_EQUAL ( kumi::fill<1>(1 ) , (kumi::tuple{1} ) ); 23 | TTS_CONSTEXPR_EQUAL ( kumi::fill<2>(2.f ) , (kumi::tuple{2.f, 2.f} ) ); 24 | TTS_CONSTEXPR_EQUAL ( kumi::fill<3>(3. ) , (kumi::tuple{3.,3.,3.} ) ); 25 | TTS_CONSTEXPR_EQUAL ( kumi::fill<7>('7' ) , (kumi::tuple{'7','7','7','7','7','7','7'}) ); 26 | }; 27 | -------------------------------------------------------------------------------- /test/unit/fold.cpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #define TTS_MAIN 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | 15 | TTS_CASE("Check result::fold_right/fold_left<...> behavior") 16 | { 17 | auto lambda = [](auto a, auto m) { return a + sizeof(m); }; 18 | using func_t = decltype(lambda); 19 | 20 | TTS_TYPE_IS((kumi::result::fold_right_t,int>) , std::size_t); 21 | TTS_TYPE_IS((kumi::result::fold_left_t,int>) , std::size_t); 22 | 23 | TTS_TYPE_IS((kumi::result::fold_right_t>) , std::size_t); 24 | TTS_TYPE_IS((kumi::result::fold_left_t>) , std::size_t); 25 | }; 26 | 27 | TTS_CASE("Check tuple::fold_right behavior") 28 | { 29 | auto t = kumi::tuple {2., 1, short {55}, 'z'}; 30 | 31 | std::vector output; 32 | 33 | auto empty = kumi::fold_right( [](auto acc, auto) { return acc; }, kumi::tuple{}, 42); 34 | TTS_EQUAL(empty, 42); 35 | 36 | auto accumulated = kumi::fold_right( 37 | [](auto acc, auto m) { 38 | acc.push_back(sizeof(m)); 39 | return acc; 40 | }, 41 | t, 42 | output); 43 | 44 | TTS_EQUAL(accumulated, (std::vector {8, 4, 2, 1})); 45 | }; 46 | 47 | TTS_CASE("Check tuple::fold_right constexpr behavior") 48 | { 49 | constexpr auto t = kumi::tuple {2., 1, short {55}, 'z'}; 50 | 51 | constexpr auto empty = kumi::fold_right( [](auto acc, auto) { return acc; }, kumi::tuple{}, 42); 52 | TTS_CONSTEXPR_EQUAL(empty, 42); 53 | 54 | constexpr auto accumulated = kumi::fold_right( 55 | [](std::array acc, auto m) { 56 | if constexpr( N == 0 ) 57 | { 58 | std::array res {sizeof(m)}; 59 | return res; 60 | } 61 | else 62 | { 63 | std::array res; 64 | for( std::size_t i = 0; i < N; ++i ) res[i] = acc[i]; 65 | res[N] = sizeof(m); 66 | return res; 67 | } 68 | }, 69 | t, 70 | std::array {}); 71 | 72 | TTS_CONSTEXPR_EQUAL(accumulated, (std::array {8, 4, 2, 1})); 73 | }; 74 | 75 | TTS_CASE("Check tuple::fold_left behavior") 76 | { 77 | auto t = kumi::tuple {2., 1, short {55}, 'z'}; 78 | 79 | auto empty = kumi::fold_left( [](auto acc, auto) { return acc; }, kumi::tuple{}, 42); 80 | TTS_EQUAL(empty, 42); 81 | 82 | std::vector output; 83 | 84 | auto accumulated = kumi::fold_left( 85 | [](auto acc, auto m) { 86 | acc.push_back(sizeof(m)); 87 | return acc; 88 | }, 89 | t, 90 | output); 91 | 92 | TTS_EQUAL(accumulated, (std::vector {1, 2, 4, 8})); 93 | }; 94 | 95 | TTS_CASE("Check tuple::fold_left constexpr behavior") 96 | { 97 | constexpr auto t = kumi::tuple {2., 1, short {55}, 'z'}; 98 | 99 | constexpr auto empty = kumi::fold_left( [](auto acc, auto) { return acc; }, kumi::tuple{}, 42); 100 | TTS_CONSTEXPR_EQUAL(empty, 42); 101 | 102 | constexpr auto accumulated = kumi::fold_left( 103 | [](std::array acc, auto m) { 104 | if constexpr( N == 0 ) 105 | { 106 | std::array res {sizeof(m)}; 107 | return res; 108 | } 109 | else 110 | { 111 | std::array res; 112 | for( std::size_t i = 0; i < N; ++i ) res[i] = acc[i]; 113 | res[N] = sizeof(m); 114 | return res; 115 | } 116 | }, 117 | t, 118 | std::array {}); 119 | 120 | TTS_CONSTEXPR_EQUAL(accumulated, (std::array {1, 2, 4, 8})); 121 | }; 122 | -------------------------------------------------------------------------------- /test/unit/for_each.cpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #define TTS_MAIN 9 | #include 10 | #include 11 | 12 | struct A { void operator()(auto&&) & {} }; 13 | struct B { void operator()(auto&&) && {} }; 14 | 15 | TTS_CASE("Check for_each SFINAE compliance") 16 | { 17 | A a; 18 | B b; 19 | auto t = kumi::make_tuple(1,2); 20 | 21 | TTS_EXPECT_COMPILES(a, t, { kumi::for_each(a, t); } ); 22 | TTS_EXPECT_NOT_COMPILES(b, t, { kumi::for_each(b, t); } ); 23 | }; 24 | 25 | 26 | TTS_CASE("Check for_each behavior") 27 | { 28 | auto t = kumi::tuple {1, 2., 3.4f, '5'}; 29 | kumi::for_each([](auto &m) { m++; }, t); 30 | 31 | TTS_EQUAL(get<0>(t), 2); 32 | TTS_EQUAL(get<1>(t), 3.); 33 | TTS_EQUAL(get<2>(t), 4.4f); 34 | TTS_EQUAL(get<3>(t), '6'); 35 | 36 | kumi::for_each([](auto &m, auto n) { m *= n; }, t, t); 37 | 38 | TTS_EQUAL(get<0>(t), 4); 39 | TTS_EQUAL(get<1>(t), 9.); 40 | TTS_EQUAL(get<2>(t), 19.36f); 41 | TTS_EQUAL(get<3>(t), 'd'); 42 | 43 | bool was_run = false; 44 | kumi::for_each([&]() { was_run = true; }, kumi::tuple{}); 45 | TTS_EXPECT_NOT(was_run); 46 | }; 47 | 48 | TTS_CASE("Check for_each constexpr behavior") 49 | { 50 | constexpr auto t = []() { 51 | auto it = kumi::tuple {1, 2., 3.4f, '5'}; 52 | kumi::for_each([](auto &m) { m++; }, it); 53 | return it; 54 | }(); 55 | 56 | TTS_CONSTEXPR_EQUAL(get<0>(t), 2); 57 | TTS_CONSTEXPR_EQUAL(get<1>(t), 3.); 58 | TTS_CONSTEXPR_EQUAL(get<2>(t), 4.4f); 59 | TTS_CONSTEXPR_EQUAL(get<3>(t), '6'); 60 | 61 | constexpr auto t2 = []() { 62 | auto it = kumi::tuple {1, 2., 3.4f, char(8)}; 63 | kumi::for_each([](auto &m, auto n) { m *= n; }, it, it); 64 | return it; 65 | }(); 66 | 67 | TTS_CONSTEXPR_EQUAL(get<0>(t2), 1); 68 | TTS_CONSTEXPR_EQUAL(get<1>(t2), 4.); 69 | TTS_CONSTEXPR_EQUAL(get<2>(t2), 11.56f); 70 | TTS_CONSTEXPR_EQUAL(get<3>(t2), '@'); 71 | }; 72 | 73 | TTS_CASE("Check for_each_index behavior") 74 | { 75 | auto t = kumi::tuple {1, 2., 3.4f, '5'}; 76 | kumi::for_each_index( 77 | [](auto i, auto &m) { 78 | if constexpr( i % 2 == 0 ) 79 | m++; 80 | else 81 | m--; 82 | }, 83 | t); 84 | 85 | TTS_EQUAL(get<0>(t), 2); 86 | TTS_EQUAL(get<1>(t), 1.); 87 | TTS_EQUAL(get<2>(t), 4.4f); 88 | TTS_EQUAL(get<3>(t), '4'); 89 | 90 | kumi::for_each_index( 91 | [](auto i, auto &m, auto n) { 92 | if constexpr( i % 2 == 0 ) 93 | m *= n; 94 | else 95 | m += n; 96 | }, 97 | t, t); 98 | 99 | TTS_EQUAL(get<0>(t), 4); 100 | TTS_EQUAL(get<1>(t), 2.); 101 | TTS_EQUAL(get<2>(t), 19.36f); 102 | TTS_EQUAL(get<3>(t), 'h'); 103 | }; 104 | 105 | TTS_CASE("Check for_each_index constexpr behavior") 106 | { 107 | constexpr auto t = []() { 108 | auto it = kumi::tuple {1, 2., 3.4f, '5'}; 109 | kumi::for_each_index( 110 | [](auto i, auto &m) { 111 | if constexpr( i % 2 == 0 ) 112 | m++; 113 | else 114 | m--; 115 | }, 116 | it); 117 | return it; 118 | }(); 119 | 120 | TTS_CONSTEXPR_EQUAL(get<0>(t), 2); 121 | TTS_CONSTEXPR_EQUAL(get<1>(t), 1.); 122 | TTS_CONSTEXPR_EQUAL(get<2>(t), 4.4f); 123 | TTS_CONSTEXPR_EQUAL(get<3>(t), '4'); 124 | 125 | constexpr auto t2 = []() { 126 | auto it = kumi::tuple {1, 2., 3.4f, '5'}; 127 | kumi::for_each_index( 128 | [](auto i, auto &m, auto n) { 129 | if constexpr( i % 2 == 0 ) 130 | m *= n; 131 | else 132 | m +=n; 133 | }, 134 | it, it); 135 | return it; 136 | }(); 137 | 138 | TTS_CONSTEXPR_EQUAL(get<0>(t2), 1); 139 | TTS_CONSTEXPR_EQUAL(get<1>(t2), 4.); 140 | TTS_CONSTEXPR_EQUAL(get<2>(t2), 11.56f); 141 | TTS_CONSTEXPR_EQUAL(get<3>(t2), 'j'); 142 | 143 | bool was_run = false; 144 | kumi::for_each_index([&]() { was_run = true; }, kumi::tuple{}); 145 | TTS_EXPECT_NOT(was_run); 146 | }; 147 | -------------------------------------------------------------------------------- /test/unit/forward_as_tuple.cpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #define TTS_MAIN 9 | #include 10 | #include 11 | 12 | enum class operations 13 | { 14 | def_ctor, 15 | move_ctor, 16 | move_assign, 17 | copy_ctor, 18 | copy_assign 19 | }; 20 | 21 | struct ctor_tracker 22 | { 23 | operations value = operations::def_ctor; 24 | ctor_tracker() = default; 25 | ctor_tracker(ctor_tracker &&) : value(operations::move_ctor) {} 26 | ctor_tracker(ctor_tracker const &) : value(operations::copy_ctor) {} 27 | ctor_tracker &operator=(ctor_tracker &&) 28 | { 29 | value = operations::move_assign; 30 | return *this; 31 | } 32 | ctor_tracker &operator=(ctor_tracker const &) 33 | { 34 | value = operations::copy_assign; 35 | return *this; 36 | } 37 | }; 38 | 39 | TTS_CASE("Check tuple_element of kumi::forward_as_tuple") 40 | { 41 | int i; 42 | float const f {}; 43 | auto forwarded = kumi::forward_as_tuple('z', ctor_tracker(), i, f); 44 | 45 | TTS_TYPE_IS((std::tuple_element_t<0, decltype(forwarded)>), char &&); 46 | TTS_TYPE_IS((std::tuple_element_t<1, decltype(forwarded)>), ctor_tracker &&); 47 | TTS_TYPE_IS((std::tuple_element_t<2, decltype(forwarded)>), int &); 48 | TTS_TYPE_IS((std::tuple_element_t<3, decltype(forwarded)>), float const &); 49 | }; 50 | 51 | template 52 | operations 53 | move_ctor_fwd(Tuple &&t) 54 | { 55 | ctor_tracker local = std::forward(t)[kumi::index<0>]; 56 | return local.value; 57 | } 58 | 59 | template 60 | operations 61 | copy_ctor_fwd(Tuple &&t) 62 | { 63 | ctor_tracker local = t[kumi::index<0>]; 64 | return local.value; 65 | } 66 | 67 | template 68 | operations 69 | move_assign_fwd(Tuple &&t) 70 | { 71 | ctor_tracker local; 72 | local = std::forward(t)[kumi::index<0>]; 73 | return local.value; 74 | } 75 | 76 | template 77 | operations 78 | copy_assign_fwd(Tuple &&t) 79 | { 80 | ctor_tracker local; 81 | local = t[kumi::index<0>]; 82 | return local.value; 83 | } 84 | 85 | TTS_CASE("Check usage of kumi::tuple via forward_as_tuple") 86 | { 87 | TTS_EQUAL(move_ctor_fwd(kumi::forward_as_tuple(ctor_tracker())), operations::move_ctor); 88 | TTS_EQUAL(copy_ctor_fwd(kumi::forward_as_tuple(ctor_tracker())), operations::copy_ctor); 89 | TTS_EQUAL(move_assign_fwd(kumi::forward_as_tuple(ctor_tracker())), operations::move_assign); 90 | TTS_EQUAL(copy_assign_fwd(kumi::forward_as_tuple(ctor_tracker())), operations::copy_assign); 91 | }; 92 | -------------------------------------------------------------------------------- /test/unit/generate.cpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #define TTS_MAIN 9 | #include 10 | #include 11 | 12 | constexpr auto t1 = [](auto &p){ return static_cast(p); }; 13 | constexpr auto t2 = [](auto ){ return 2.f; }; 14 | constexpr auto t3 = [](auto p){ return static_cast(p); }; 15 | constexpr auto t4 = [](auto ){ return '7'; }; 16 | 17 | TTS_CASE("Check runtime kumi::generate behavior") 18 | { 19 | TTS_EQUAL ( kumi::generate<1>(t1 ) , (kumi::tuple{0} ) ); 20 | TTS_EQUAL ( kumi::generate<2>(t2 ) , (kumi::tuple{2.f, 2.f} ) ); 21 | TTS_EQUAL ( kumi::generate<9>(t3 ) , (kumi::tuple{0.,1.,2.,3.,4.,5.,6.,7.,8.} ) ); 22 | TTS_EQUAL ( kumi::generate<7>(t4 ) , (kumi::tuple{'7','7','7','7','7','7','7'}) ); 23 | }; 24 | 25 | TTS_CASE("Check constexpr kumi::generate behavior") 26 | { 27 | TTS_CONSTEXPR_EQUAL ( kumi::generate<1>(t1 ) , (kumi::tuple{0} ) ); 28 | TTS_CONSTEXPR_EQUAL ( kumi::generate<2>(t2 ) , (kumi::tuple{2.f, 2.f} ) ); 29 | TTS_CONSTEXPR_EQUAL ( kumi::generate<9>(t3 ) , (kumi::tuple{0.,1.,2.,3.,4.,5.,6.,7.,8.} ) ); 30 | TTS_CONSTEXPR_EQUAL ( kumi::generate<7>(t4 ) , (kumi::tuple{'7','7','7','7','7','7','7'}) ); 31 | }; 32 | -------------------------------------------------------------------------------- /test/unit/inner_product.cpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #define TTS_MAIN 9 | #include 10 | #include 11 | 12 | TTS_CASE("Check result::inner_product_t behavior") 13 | { 14 | auto sum = [](auto a, auto b) { return sizeof(a) + sizeof(b); }; 15 | auto prod = [](auto a, auto b) { return a*b; }; 16 | using sfunc_t = decltype(sum); 17 | using pfunc_t = decltype(prod); 18 | 19 | TTS_TYPE_IS ( (kumi::result::inner_product_t< kumi::tuple 20 | , kumi::tuple 21 | , int 22 | > 23 | ) 24 | , double 25 | ); 26 | 27 | TTS_TYPE_IS ( (kumi::result::inner_product_t< kumi::tuple 28 | , kumi::tuple 29 | , int 30 | , sfunc_t, pfunc_t 31 | > 32 | ) 33 | , std::size_t 34 | ); 35 | }; 36 | 37 | TTS_CASE("Check tuple::inner_product behavior") 38 | { 39 | auto t1 = kumi::tuple{2,4,8}; 40 | auto t2 = kumi::tuple{2.5,4.5,7.5}; 41 | 42 | TTS_EQUAL (kumi::inner_product(t1,t2,0.f), 83); 43 | TTS_EQUAL ( kumi::inner_product ( t1, t2, 1ULL 44 | , [](auto a, auto b) { return a*b; } 45 | , [](auto a, auto b) { return a+b; } 46 | ) 47 | , 592.875 48 | ); 49 | }; 50 | 51 | TTS_CASE("Check tuple::inner_product constexpr behavior") 52 | { 53 | TTS_CONSTEXPR_EQUAL ( kumi::inner_product(kumi::tuple{2,4,8},kumi::tuple{2.5,4.5,7.5},0.f), 83); 54 | TTS_CONSTEXPR_EQUAL ( kumi::inner_product ( kumi::tuple{2,4,8} 55 | , kumi::tuple{2.5,4.5,7.5}, 1ULL 56 | , [](auto a, auto b) { return a*b; } 57 | , [](auto a, auto b) { return a+b; } 58 | ) 59 | , 592.875 60 | ); 61 | }; 62 | -------------------------------------------------------------------------------- /test/unit/iota.cpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #define TTS_MAIN 9 | #include 10 | #include 11 | 12 | TTS_CASE("Check runtime kumi::iota behavior") 13 | { 14 | TTS_EQUAL ( kumi::iota<1>(1 ) , (kumi::tuple{1} ) ); 15 | TTS_EQUAL ( kumi::iota<2>(2.f ) , (kumi::tuple{2.f, 3.f} ) ); 16 | TTS_EQUAL ( kumi::iota<3>(3. ) , (kumi::tuple{3.,4.,5.} ) ); 17 | TTS_EQUAL ( kumi::iota<7>('0' ) , (kumi::tuple{'0','1','2','3','4','5','6'}) ); 18 | }; 19 | 20 | TTS_CASE("Check constexpr kumi::iota behavior") 21 | { 22 | TTS_CONSTEXPR_EQUAL ( kumi::iota<1>(1 ) , (kumi::tuple{1} ) ); 23 | TTS_CONSTEXPR_EQUAL ( kumi::iota<2>(2.f ) , (kumi::tuple{2.f, 3.f} ) ); 24 | TTS_CONSTEXPR_EQUAL ( kumi::iota<3>(3. ) , (kumi::tuple{3.,4.,5.} ) ); 25 | TTS_CONSTEXPR_EQUAL ( kumi::iota<7>('0' ) , (kumi::tuple{'0','1','2','3','4','5','6'}) ); 26 | }; 27 | -------------------------------------------------------------------------------- /test/unit/is_homogeneous.cpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #define TTS_MAIN 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | TTS_CASE("Check is_homogeneous for kumi::tuple") 15 | { 16 | TTS_CONSTEXPR_EXPECT_NOT( kumi::tuple<>::is_homogeneous ); 17 | TTS_CONSTEXPR_EXPECT ( kumi::tuple::is_homogeneous ); 18 | TTS_CONSTEXPR_EXPECT ((kumi::tuple::is_homogeneous )); 19 | TTS_CONSTEXPR_EXPECT_NOT((kumi::tuple::is_homogeneous )); 20 | TTS_CONSTEXPR_EXPECT ((kumi::tuple::is_homogeneous )); 21 | TTS_CONSTEXPR_EXPECT_NOT((kumi::tuple::is_homogeneous )); 22 | TTS_CONSTEXPR_EXPECT ((kumi::tuple::is_homogeneous )); 23 | TTS_CONSTEXPR_EXPECT_NOT((kumi::tuple::is_homogeneous )); 24 | 25 | TTS_CONSTEXPR_EXPECT_NOT( kumi::homogeneous_product_type> ); 26 | TTS_CONSTEXPR_EXPECT ( kumi::homogeneous_product_type> ); 27 | TTS_CONSTEXPR_EXPECT ( kumi::homogeneous_product_type> ); 28 | TTS_CONSTEXPR_EXPECT ((kumi::homogeneous_product_type> )); 29 | TTS_CONSTEXPR_EXPECT_NOT((kumi::homogeneous_product_type> )); 30 | TTS_CONSTEXPR_EXPECT ((kumi::homogeneous_product_type> )); 31 | TTS_CONSTEXPR_EXPECT_NOT((kumi::homogeneous_product_type> )); 32 | TTS_CONSTEXPR_EXPECT ((kumi::homogeneous_product_type> )); 33 | TTS_CONSTEXPR_EXPECT_NOT((kumi::homogeneous_product_type> )); 34 | }; 35 | 36 | template 37 | struct trivial_product_type : kumi::tuple 38 | {}; 39 | 40 | template 41 | struct trivial_product_type : kumi::tuple 42 | {}; 43 | 44 | template 45 | struct std::tuple_size> : std::integral_constant 46 | {}; 47 | 48 | template 49 | struct std::tuple_element> { using type = T; }; 50 | 51 | template 52 | struct std::tuple_element<4,trivial_product_type> { using type = void*; }; 53 | 54 | TTS_CASE("Check is_homogeneous for kumi::tuple derived types") 55 | { 56 | TTS_CONSTEXPR_EXPECT((trivial_product_type::is_homogeneous )); 57 | TTS_CONSTEXPR_EXPECT((kumi::homogeneous_product_type>)); 58 | 59 | TTS_CONSTEXPR_EXPECT_NOT((trivial_product_type::is_homogeneous )); 60 | TTS_CONSTEXPR_EXPECT_NOT((kumi::homogeneous_product_type>)); 61 | }; 62 | 63 | struct some_box 64 | { 65 | using is_product_type = void; 66 | 67 | int i; 68 | float f; 69 | char c; 70 | 71 | template 72 | friend constexpr auto const& get(some_box const& s) noexcept requires(I < 3) 73 | { 74 | if constexpr(I==0) return s.i; 75 | if constexpr(I==1) return s.f; 76 | if constexpr(I==2) return s.c; 77 | } 78 | 79 | template 80 | friend constexpr auto & get(some_box& s) noexcept requires(I < 3) 81 | { 82 | if constexpr(I==0) return s.i; 83 | if constexpr(I==1) return s.f; 84 | if constexpr(I==2) return s.c; 85 | } 86 | }; 87 | 88 | template<> struct std::tuple_size : std::integral_constant {}; 89 | template<> struct std::tuple_element<0,some_box> { using type = int; }; 90 | template<> struct std::tuple_element<1,some_box> { using type = float; }; 91 | template<> struct std::tuple_element<2,some_box> { using type = char; }; 92 | 93 | TTS_CASE("Check is_homogeneous for kumi::product_type adapted types") 94 | { 95 | TTS_CONSTEXPR_EXPECT((kumi::homogeneous_product_type>)); 96 | TTS_CONSTEXPR_EXPECT_NOT((kumi::homogeneous_product_type)); 97 | }; 98 | -------------------------------------------------------------------------------- /test/unit/locate.cpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #define TTS_MAIN 9 | #include 10 | #include 11 | #include 12 | 13 | TTS_CASE("kumi locate runtime behavior") 14 | { 15 | auto values = kumi::make_tuple(1, 2.5, -3.6f, 4ULL); 16 | 17 | TTS_EQUAL(kumi::locate(values, [](auto e) { return e < 0; }) , 2ULL); 18 | TTS_EQUAL(kumi::locate(values, kumi::predicate()) , 3ULL); 19 | }; 20 | 21 | TTS_CASE("kumi locate constexpr behavior") 22 | { 23 | TTS_CONSTEXPR_EQUAL ( kumi::locate(kumi::make_tuple(1, 2.5, -3.6f, 4ULL) 24 | , [](auto e) { return e < 0; } 25 | ) 26 | , 2ULL 27 | ); 28 | 29 | TTS_CONSTEXPR_EQUAL ( kumi::locate(kumi::make_tuple(1, 2.5, -3.6f, 4ULL) 30 | , kumi::predicate() 31 | ) 32 | , 3ULL 33 | ); 34 | }; 35 | -------------------------------------------------------------------------------- /test/unit/make_tuple.cpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #define TTS_MAIN 9 | #include 10 | #include 11 | #include 12 | 13 | TTS_CASE("Check tuple_element of kumi::tuple") 14 | { 15 | float const f {}; 16 | double d; 17 | std::reference_wrapper rf = f; 18 | std::reference_wrapper rd = d; 19 | 20 | auto made = kumi::make_tuple('1', 2., 3.f, rf, rd); 21 | 22 | TTS_TYPE_IS((std::tuple_element_t<0, decltype(made)>), char); 23 | TTS_TYPE_IS((std::tuple_element_t<1, decltype(made)>), double); 24 | TTS_TYPE_IS((std::tuple_element_t<2, decltype(made)>), float); 25 | TTS_TYPE_IS((std::tuple_element_t<3, decltype(made)>), float const &); 26 | TTS_TYPE_IS((std::tuple_element_t<4, decltype(made)>), double &); 27 | }; 28 | 29 | TTS_CASE("Check construction of kumi::tuple via make_tuple") 30 | { 31 | auto t0 = kumi::make_tuple(); 32 | auto t1 = kumi::make_tuple(1); 33 | auto t2 = kumi::make_tuple(1.f, 2); 34 | auto t3 = kumi::make_tuple(1., 2.f, 3); 35 | auto t4 = kumi::make_tuple('1', 2., 3.f, 4); 36 | 37 | TTS_CONSTEXPR_EXPECT((kumi::sized_product_type)); 38 | TTS_EQUAL(t0.size(), 0ULL); 39 | 40 | TTS_CONSTEXPR_EXPECT((kumi::sized_product_type)); 41 | TTS_EQUAL(t1.size(), 1ULL); 42 | TTS_EQUAL(get<0>(t1), 1); 43 | 44 | TTS_CONSTEXPR_EXPECT((kumi::sized_product_type)); 45 | TTS_EQUAL(t2.size(), 2ULL); 46 | TTS_EQUAL(get<0>(t2), 1.f); 47 | TTS_EQUAL(get<1>(t2), 2); 48 | 49 | TTS_CONSTEXPR_EXPECT((kumi::sized_product_type)); 50 | TTS_EQUAL(t3.size(), 3ULL); 51 | TTS_EQUAL(get<0>(t3), 1.); 52 | TTS_EQUAL(get<1>(t3), 2.f); 53 | TTS_EQUAL(get<2>(t3), 3); 54 | 55 | TTS_CONSTEXPR_EXPECT((kumi::sized_product_type)); 56 | TTS_EQUAL(t4.size(), 4ULL); 57 | TTS_EQUAL(get<0>(t4), '1'); 58 | TTS_EQUAL(get<1>(t4), 2.); 59 | TTS_EQUAL(get<2>(t4), 3.f); 60 | TTS_EQUAL(get<3>(t4), 4); 61 | }; 62 | 63 | TTS_CASE("Check construction of kumi::tuple via constexpr make_tuple") 64 | { 65 | constexpr auto t0 = kumi::make_tuple(); 66 | constexpr auto t1 = kumi::make_tuple(1); 67 | constexpr auto t2 = kumi::make_tuple(1.f, 2); 68 | constexpr auto t3 = kumi::make_tuple(1., 2.f, 3); 69 | constexpr auto t4 = kumi::make_tuple('1', 2., 3.f, 4); 70 | 71 | TTS_CONSTEXPR_EXPECT((kumi::sized_product_type)); 72 | TTS_CONSTEXPR_EQUAL(t0.size(), 0ULL); 73 | 74 | TTS_CONSTEXPR_EXPECT((kumi::sized_product_type)); 75 | TTS_CONSTEXPR_EQUAL(t1.size(), 1ULL); 76 | TTS_CONSTEXPR_EQUAL(get<0>(t1), 1); 77 | 78 | TTS_CONSTEXPR_EXPECT((kumi::sized_product_type)); 79 | TTS_CONSTEXPR_EQUAL(t2.size(), 2ULL); 80 | TTS_CONSTEXPR_EQUAL(get<0>(t2), 1.f); 81 | TTS_CONSTEXPR_EQUAL(get<1>(t2), 2); 82 | 83 | TTS_CONSTEXPR_EXPECT((kumi::sized_product_type)); 84 | TTS_CONSTEXPR_EQUAL(t3.size(), 3ULL); 85 | TTS_CONSTEXPR_EQUAL(get<0>(t3), 1.); 86 | TTS_CONSTEXPR_EQUAL(get<1>(t3), 2.f); 87 | TTS_CONSTEXPR_EQUAL(get<2>(t3), 3); 88 | 89 | TTS_CONSTEXPR_EXPECT((kumi::sized_product_type)); 90 | TTS_CONSTEXPR_EQUAL(t4.size(), 4ULL); 91 | TTS_CONSTEXPR_EQUAL(get<0>(t4), '1'); 92 | TTS_CONSTEXPR_EQUAL(get<1>(t4), 2.); 93 | TTS_CONSTEXPR_EQUAL(get<2>(t4), 3.f); 94 | TTS_CONSTEXPR_EQUAL(get<3>(t4), 4); 95 | }; 96 | -------------------------------------------------------------------------------- /test/unit/map.cpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #define TTS_MAIN 9 | #include 10 | #include 11 | 12 | TTS_CASE("Check result::map behavior") 13 | { 14 | auto lambda = [](auto const& m) { return &m; }; 15 | using func_t = decltype(lambda); 16 | 17 | TTS_TYPE_IS ( (kumi::result::map_t>) 18 | , (kumi::tuple) 19 | ); 20 | 21 | auto add = [](auto a, auto b) { return a+b; }; 22 | using add_t = decltype(add); 23 | 24 | TTS_TYPE_IS ( (kumi::result::map_t 25 | , kumi::tuple 26 | > 27 | ) 28 | , (kumi::tuple) 29 | ); 30 | }; 31 | 32 | TTS_CASE("Check map(f, {}) behavior") 33 | { 34 | bool was_run = false; 35 | auto s = map([&](auto m) { was_run = true; return sizeof(m); }, kumi::tuple{}); 36 | TTS_EQUAL( s.size(), 0ULL ); 37 | TTS_EXPECT_NOT( was_run ); 38 | }; 39 | 40 | TTS_CASE("Check map(f, tuple) behavior") 41 | { 42 | { 43 | auto t = kumi::tuple {1, 2., 3.4f, '5'}; 44 | 45 | { 46 | auto s = map([](auto m) { return sizeof(m); }, t); 47 | 48 | auto [s0, s1, s2, s3] = s; 49 | auto m0 = s0; 50 | auto m1 = s1; 51 | auto m2 = s2; 52 | auto m3 = s3; 53 | TTS_EQUAL(m0, sizeof(int)); 54 | TTS_EQUAL(m1, sizeof(double)); 55 | TTS_EQUAL(m2, sizeof(float)); 56 | TTS_EQUAL(m3, sizeof(char)); 57 | } 58 | 59 | { 60 | auto u = kumi::tuple {2, 3, 4, 5}; 61 | auto s = map([](auto m, auto n) { return n * sizeof(m); }, t, u); 62 | 63 | auto [s0, s1, s2, s3] = s; 64 | auto m0 = s0; 65 | auto m1 = s1; 66 | auto m2 = s2; 67 | auto m3 = s3; 68 | TTS_EQUAL(m0, 2 * sizeof(int)); 69 | TTS_EQUAL(m1, 3 * sizeof(double)); 70 | TTS_EQUAL(m2, 4 * sizeof(float)); 71 | TTS_EQUAL(m3, 5 * sizeof(char)); 72 | } 73 | } 74 | }; 75 | 76 | TTS_CASE("Check map(f, tuple) constexpr behavior") 77 | { 78 | { 79 | constexpr auto t = kumi::tuple {1, 2., 3.4f, '5'}; 80 | 81 | { 82 | constexpr auto s = map([](auto m) { return sizeof(m); }, t); 83 | 84 | TTS_CONSTEXPR_EQUAL(get<0>(s), sizeof(int)); 85 | TTS_CONSTEXPR_EQUAL(get<1>(s), sizeof(double)); 86 | TTS_CONSTEXPR_EQUAL(get<2>(s), sizeof(float)); 87 | TTS_CONSTEXPR_EQUAL(get<3>(s), sizeof(char)); 88 | } 89 | 90 | { 91 | constexpr auto u = kumi::tuple {2, 3, 4, 5}; 92 | constexpr auto s = map([](auto m, auto n) { return n * sizeof(m); }, t, u); 93 | 94 | TTS_CONSTEXPR_EQUAL(get<0>(s), 2 * sizeof(int)); 95 | TTS_CONSTEXPR_EQUAL(get<1>(s), 3 * sizeof(double)); 96 | TTS_CONSTEXPR_EQUAL(get<2>(s), 4 * sizeof(float)); 97 | TTS_CONSTEXPR_EQUAL(get<3>(s), 5 * sizeof(char)); 98 | } 99 | } 100 | }; 101 | -------------------------------------------------------------------------------- /test/unit/map_index.cpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #define TTS_MAIN 9 | #include 10 | #include 11 | 12 | TTS_CASE("Check result::map_index behavior") 13 | { 14 | auto lambda = [](auto, auto const& m) { return &m; }; 15 | using func_t = decltype(lambda); 16 | 17 | TTS_TYPE_IS ( (kumi::result::map_index_t>) 18 | , (kumi::tuple) 19 | ); 20 | 21 | auto add = [](auto i, auto a, auto b) { return (a*b)/(i+1.); }; 22 | using add_t = decltype(add); 23 | 24 | TTS_TYPE_IS ( (kumi::result::map_index_t 25 | , kumi::tuple 26 | > 27 | ) 28 | , (kumi::tuple) 29 | ); 30 | }; 31 | 32 | TTS_CASE("Check map_index(f, {}) behavior") 33 | { 34 | bool was_run = false; 35 | auto s = map_index([&](auto, auto m) { was_run = true; return sizeof(m); }, kumi::tuple{}); 36 | TTS_EQUAL( s.size(), 0ULL ); 37 | TTS_EXPECT_NOT( was_run ); 38 | }; 39 | 40 | TTS_CASE("Check map_index(f, tuple) behavior") 41 | { 42 | { 43 | auto t = kumi::tuple {1, 2., 3.4f, '5'}; 44 | 45 | { 46 | auto s = map_index([](auto i, auto m) { return i+sizeof(m); }, t); 47 | 48 | auto [s0, s1, s2, s3] = s; 49 | auto m0 = s0; 50 | auto m1 = s1; 51 | auto m2 = s2; 52 | auto m3 = s3; 53 | TTS_EQUAL(m0, sizeof(int)); 54 | TTS_EQUAL(m1, 1+sizeof(double)); 55 | TTS_EQUAL(m2, 2+sizeof(float)); 56 | TTS_EQUAL(m3, 3+sizeof(char)); 57 | } 58 | 59 | { 60 | auto u = kumi::tuple {2, 3, 4, 5}; 61 | auto s = map_index([](auto i, auto m, auto n) { return (n+i) * sizeof(m); }, t, u); 62 | 63 | auto [s0, s1, s2, s3] = s; 64 | auto m0 = s0; 65 | auto m1 = s1; 66 | auto m2 = s2; 67 | auto m3 = s3; 68 | TTS_EQUAL(m0, 2 * sizeof(int)); 69 | TTS_EQUAL(m1, 4 * sizeof(double)); 70 | TTS_EQUAL(m2, 6 * sizeof(float)); 71 | TTS_EQUAL(m3, 8 * sizeof(char)); 72 | } 73 | } 74 | }; 75 | 76 | #if 0 77 | TTS_CASE("Check map_index(f, tuple) constexpr behavior") 78 | { 79 | { 80 | constexpr auto t = kumi::tuple {1, 2., 3.4f, '5'}; 81 | 82 | { 83 | constexpr auto s = map_index([](auto m) { return sizeof(m); }, t); 84 | 85 | TTS_CONSTEXPR_EQUAL(get<0>(s), sizeof(int)); 86 | TTS_CONSTEXPR_EQUAL(get<1>(s), sizeof(double)); 87 | TTS_CONSTEXPR_EQUAL(get<2>(s), sizeof(float)); 88 | TTS_CONSTEXPR_EQUAL(get<3>(s), sizeof(char)); 89 | } 90 | 91 | { 92 | constexpr auto u = kumi::tuple {2, 3, 4, 5}; 93 | constexpr auto s = map_index([](auto m, auto n) { return n * sizeof(m); }, t, u); 94 | 95 | TTS_CONSTEXPR_EQUAL(get<0>(s), 2 * sizeof(int)); 96 | TTS_CONSTEXPR_EQUAL(get<1>(s), 3 * sizeof(double)); 97 | TTS_CONSTEXPR_EQUAL(get<2>(s), 4 * sizeof(float)); 98 | TTS_CONSTEXPR_EQUAL(get<3>(s), 5 * sizeof(char)); 99 | } 100 | } 101 | }; 102 | #endif 103 | -------------------------------------------------------------------------------- /test/unit/map_traits.cpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #include "kumi/utils/concepts.hpp" 9 | #include 10 | #include 11 | #define TTS_MAIN 12 | #include 13 | #include 14 | 15 | template 16 | struct nary_traits : std::integral_constant 17 | {}; 18 | 19 | TTS_CASE("Check map_traits behavior") 20 | { 21 | using mapped = kumi::tuple< std::integral_constant , std::integral_constant 22 | , std::integral_constant , std::integral_constant 23 | , std::integral_constant , std::integral_constant 24 | >; 25 | 26 | TTS_TYPE_IS ( (kumi::map_traits_t < nary_traits 27 | , kumi::tuple 28 | >) 29 | , ( mapped ) 30 | ); 31 | }; 32 | 33 | template 34 | kumi::map_traits_t f(T const&) 35 | { 36 | return {}; 37 | } 38 | 39 | template 40 | kumi::map_traits_t g(T const&) 41 | { 42 | return {}; 43 | } 44 | 45 | template 46 | requires( std::is_floating_point_v && ...) 47 | struct strict_traits 48 | { 49 | using type = bool; 50 | }; 51 | 52 | template 53 | kumi::map_traits_t h(T const&) 54 | { 55 | return true; 56 | } 57 | 58 | TTS_CASE("Check map_traits SFINAE compliance") 59 | { 60 | kumi::tuple t; 61 | kumi::tuple u; 62 | 63 | // wrong # of arguments to traits 64 | TTS_EXPECT_COMPILES(t, { f(t); } ); 65 | TTS_EXPECT_COMPILES(t, { g(t); } ); 66 | 67 | // Unsupported types within tuple 68 | TTS_EXPECT_COMPILES(u, { h(u); } ); 69 | TTS_EXPECT_NOT_COMPILES(t, { h(t); } ); 70 | }; 71 | -------------------------------------------------------------------------------- /test/unit/max.cpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #define TTS_MAIN 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | TTS_CASE("Check result::max/max_flat<...> behavior") 15 | { 16 | auto lambda = [](auto m) { return sizeof(m); }; 17 | using func_t = decltype(lambda); 18 | 19 | TTS_TYPE_IS ( (kumi::result::max_t>) 20 | , double 21 | ); 22 | 23 | TTS_TYPE_IS ( (kumi::result::max_t,func_t>) 24 | , std::size_t 25 | ); 26 | 27 | TTS_TYPE_IS ( (kumi::result::max_flat_t,func_t>) 28 | , std::size_t 29 | ); 30 | 31 | TTS_TYPE_IS ( (kumi::result::max_flat_t,double>,func_t>) 32 | , std::size_t 33 | ); 34 | }; 35 | 36 | TTS_CASE("Check tuple::max/max_flat behavior") 37 | { 38 | auto t0 = kumi::tuple {'e', 2, 7894.5, short {55}, 'z'}; 39 | TTS_EQUAL( kumi::max(t0), 7894.5); 40 | TTS_EQUAL((kumi::max(t0, [](auto m) { return sizeof(m); })), sizeof(double)); 41 | 42 | auto f0 = kumi::tuple {'e', 2., kumi::tuple {1., short {55}, 'u'}, 3.f, 'z'}; 43 | TTS_EQUAL((kumi::max (f0 , [](auto m) { return sizeof(m); })), 2*sizeof(double)); 44 | TTS_EQUAL((kumi::max_flat (f0 , [](auto m) { return sizeof(m); })), sizeof(double)); 45 | 46 | auto t1 = kumi::tuple {1.5,3.6f,8,-3.6,2.4,0}; 47 | TTS_EQUAL((kumi::max(t1, [](auto m) { return (m-5)<0 ? (5-m) : (m-5); })), 8.6); 48 | }; 49 | 50 | TTS_CASE("Check tuple::max/max_flat constexpr behavior") 51 | { 52 | constexpr auto t0 = kumi::tuple {'e', 2, 7894.5, short {55}, 'z'}; 53 | TTS_CONSTEXPR_EQUAL( kumi::max(t0), 7894.5); 54 | TTS_CONSTEXPR_EQUAL((kumi::max(t0, [](auto m) { return sizeof(m); })), sizeof(double)); 55 | 56 | constexpr auto f0 = kumi::tuple {'e', 2., kumi::tuple {1., short {55}, 'u'}, 3.f, 'z'}; 57 | TTS_CONSTEXPR_EQUAL((kumi::max (f0 , [](auto m) { return sizeof(m); })), 2*sizeof(double)); 58 | TTS_CONSTEXPR_EQUAL((kumi::max_flat (f0 , [](auto m) { return sizeof(m); })), sizeof(double)); 59 | 60 | constexpr auto t1 = kumi::tuple {1.5,3.6f,8,-3.6,2.4,0}; 61 | TTS_CONSTEXPR_EQUAL((kumi::max(t1, [](auto m) { return (m-5)<0 ? (5-m) : (m-5); })), 8.6); 62 | }; 63 | -------------------------------------------------------------------------------- /test/unit/min.cpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #define TTS_MAIN 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | TTS_CASE("Check result::min/min_flat<...> behavior") 15 | { 16 | auto lambda = [](auto m) { return sizeof(m); }; 17 | using func_t = decltype(lambda); 18 | 19 | TTS_TYPE_IS ( (kumi::result::min_t>) 20 | , double 21 | ); 22 | 23 | TTS_TYPE_IS ( (kumi::result::min_t,func_t>) 24 | , std::size_t 25 | ); 26 | 27 | TTS_TYPE_IS ( (kumi::result::min_flat_t,func_t>) 28 | , std::size_t 29 | ); 30 | 31 | TTS_TYPE_IS ( (kumi::result::min_flat_t,double>,func_t>) 32 | , std::size_t 33 | ); 34 | }; 35 | 36 | TTS_CASE("Check tuple::min/min_flat behavior") 37 | { 38 | auto t0 = kumi::tuple {'e', 2, 1., short {55}, 'z'}; 39 | TTS_EQUAL( kumi::min(t0), 1.); 40 | TTS_EQUAL((kumi::min(t0, [](auto m) { return sizeof(m); })), sizeof(char)); 41 | 42 | auto f0 = kumi::tuple {2., 1., kumi::tuple{'u','z'}, 3.f}; 43 | TTS_EQUAL((kumi::min (f0 , [](auto m) { return sizeof(m); })), 2*sizeof(char)); 44 | TTS_EQUAL((kumi::min_flat (f0 , [](auto m) { return sizeof(m); })), sizeof(char)); 45 | 46 | auto t1 = kumi::tuple {1.5,3.6f,8,-3.6,2.4,-0.5}; 47 | TTS_EQUAL((kumi::min(t1, [](auto m) { return m<0 ? -m : m; })), 0.5); 48 | }; 49 | 50 | TTS_CASE("Check tuple::min/min_flat constexpr behavior") 51 | { 52 | constexpr auto t0 = kumi::tuple {'e', 2, 1., short {55}, 'z'}; 53 | TTS_CONSTEXPR_EQUAL( kumi::min(t0), 1.); 54 | TTS_CONSTEXPR_EQUAL((kumi::min(t0, [](auto m) { return sizeof(m); })), sizeof(char)); 55 | 56 | constexpr auto f0 = kumi::tuple {2., 1., kumi::tuple{'u','z'}, 3.f}; 57 | TTS_CONSTEXPR_EQUAL((kumi::min (f0 , [](auto m) { return sizeof(m); })), 2*sizeof(char)); 58 | TTS_CONSTEXPR_EQUAL((kumi::min_flat (f0 , [](auto m) { return sizeof(m); })), sizeof(char)); 59 | 60 | constexpr auto t1 = kumi::tuple {1.5,3.6f,8,-3.6,2.4,-0.5}; 61 | TTS_CONSTEXPR_EQUAL((kumi::min(t1, [](auto m) { return m<0 ? -m : m; })), 0.5); 62 | }; 63 | -------------------------------------------------------------------------------- /test/unit/partition.cpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #define TTS_MAIN 9 | #include 10 | #include 11 | #include 12 | 13 | TTS_CASE("Check result::partition behavior") 14 | { 15 | TTS_TYPE_IS ( (kumi::result::partition_t>) 16 | , (kumi::tuple,kumi::tuple<>>) 17 | ); 18 | 19 | TTS_TYPE_IS ( (kumi::result::partition_t>) 20 | , (kumi::tuple,kumi::tuple>) 21 | ); 22 | 23 | TTS_TYPE_IS ( (kumi::result::partition_t< std::is_rvalue_reference 24 | , kumi::tuple 25 | > 26 | ) 27 | , (kumi::tuple,kumi::tuple>) 28 | ); 29 | }; 30 | 31 | TTS_CASE("Check partition(kumi::tuple<>{}) behavior") 32 | { 33 | TTS_EQUAL ( (kumi::partition(kumi::tuple{})) 34 | , (kumi::tuple,kumi::tuple<>>{}) 35 | ); 36 | }; 37 | 38 | TTS_CASE("Check partition() behavior with values") 39 | { 40 | int a = 4; 41 | double b = 3.1415; 42 | float c = 0.01f; 43 | 44 | auto original = kumi::tuple{a,&a,b,&b,c,&c,'z',nullptr}; 45 | 46 | TTS_EQUAL ( kumi::partition(original) 47 | , (kumi::tuple{kumi::tuple{&a,&b,&c},kumi::tuple{a,b,c,'z',nullptr}}) 48 | ); 49 | 50 | TTS_EQUAL ( kumi::partition(original) 51 | , (kumi::tuple{kumi::tuple{b,c},kumi::tuple{a,&a,&b,&c,'z',nullptr}}) 52 | ); 53 | 54 | TTS_EQUAL ( kumi::partition(original) 55 | , (kumi::tuple{kumi::tuple{nullptr},kumi::tuple{a,&a,b,&b,c,&c,'z',}}) 56 | ); 57 | }; 58 | 59 | 60 | TTS_CASE("Check partition() behavior with reference") 61 | { 62 | int a = 4; 63 | double b = 3.1415; 64 | 65 | auto original = kumi::tuple{a,a,b,b}; 66 | 67 | TTS_EQUAL ( kumi::partition(original) 68 | , (kumi::tuple{kumi::tuple{a,b},kumi::tuple{a,b}}) 69 | ); 70 | }; 71 | -------------------------------------------------------------------------------- /test/unit/push_pop.cpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #define TTS_MAIN 9 | #include 10 | #include 11 | 12 | TTS_CASE("Check kumi::push_front/pop_front type computation") 13 | { 14 | using namespace kumi::result; 15 | 16 | TTS_TYPE_IS((push_front_t,int>), kumi::tuple); 17 | TTS_TYPE_IS((push_front_t,int>),(kumi::tuple)); 18 | TTS_TYPE_IS((push_front_t,int>),(kumi::tuple)); 19 | 20 | TTS_TYPE_IS((pop_front_t>), kumi::tuple<>); 21 | TTS_TYPE_IS((pop_front_t>), kumi::tuple<>); 22 | TTS_TYPE_IS((pop_front_t>), kumi::tuple); 23 | TTS_TYPE_IS((pop_front_t>),(kumi::tuple)); 24 | }; 25 | 26 | TTS_CASE("Check kumi::push_front function behavior") 27 | { 28 | TTS_EQUAL( (kumi::push_front(kumi::tuple{},4)), kumi::tuple{4} ); 29 | TTS_EQUAL( (kumi::push_front(kumi::tuple{3.5},4)), (kumi::tuple{4,3.5}) ); 30 | TTS_EQUAL( (kumi::push_front(kumi::tuple{3.5,'e'},4)), (kumi::tuple{4,3.5,'e'}) ); 31 | 32 | TTS_EQUAL( kumi::pop_front(kumi::tuple{}) , kumi::tuple{} ); 33 | TTS_EQUAL( kumi::pop_front(kumi::tuple{3.5}) , kumi::tuple{} ); 34 | TTS_EQUAL( kumi::pop_front(kumi::tuple{3.5,'e'}) , kumi::tuple{'e'} ); 35 | TTS_EQUAL( kumi::pop_front(kumi::tuple{4,3.5,'e'}), (kumi::tuple{3.5,'e'})); 36 | }; 37 | 38 | TTS_CASE("Check kumi::push_front/pop_front constexpr behavior") 39 | { 40 | TTS_CONSTEXPR_EQUAL( (kumi::push_front(kumi::tuple{},4)), kumi::tuple{4} ); 41 | TTS_CONSTEXPR_EQUAL( (kumi::push_front(kumi::tuple{3.5},4)), (kumi::tuple{4,3.5}) ); 42 | TTS_CONSTEXPR_EQUAL( (kumi::push_front(kumi::tuple{3.5,'e'},4)), (kumi::tuple{4,3.5,'e'}) ); 43 | 44 | TTS_CONSTEXPR_EQUAL( kumi::pop_front(kumi::tuple{}) , kumi::tuple{} ); 45 | TTS_CONSTEXPR_EQUAL( kumi::pop_front(kumi::tuple{3.5}) , kumi::tuple{} ); 46 | TTS_CONSTEXPR_EQUAL( kumi::pop_front(kumi::tuple{3.5,'e'}) , kumi::tuple{'e'} ); 47 | TTS_CONSTEXPR_EQUAL( kumi::pop_front(kumi::tuple{4,3.5,'e'}), (kumi::tuple{3.5,'e'})); 48 | }; 49 | 50 | TTS_CASE("Check kumi::push_back/pop_back type computation") 51 | { 52 | using namespace kumi::result; 53 | 54 | TTS_TYPE_IS((push_back_t,int>),kumi::tuple); 55 | TTS_TYPE_IS((push_back_t,int>),(kumi::tuple)); 56 | TTS_TYPE_IS((push_back_t,int>),(kumi::tuple)); 57 | 58 | TTS_TYPE_IS((pop_back_t>),kumi::tuple<>); 59 | TTS_TYPE_IS((pop_back_t>),kumi::tuple<>); 60 | TTS_TYPE_IS((pop_back_t>),kumi::tuple); 61 | TTS_TYPE_IS((pop_back_t>),(kumi::tuple)); 62 | }; 63 | 64 | TTS_CASE("Check kumi::push_back/pop_back function behavior") 65 | { 66 | TTS_EQUAL( (kumi::push_back(kumi::tuple{},4)), kumi::tuple{4} ); 67 | TTS_EQUAL( (kumi::push_back(kumi::tuple{3.5},4)), (kumi::tuple{3.5,4}) ); 68 | TTS_EQUAL( (kumi::push_back(kumi::tuple{3.5,'e'},4)), (kumi::tuple{3.5,'e',4}) ); 69 | 70 | TTS_EQUAL( kumi::pop_back(kumi::tuple{}) , kumi::tuple{} ); 71 | TTS_EQUAL( kumi::pop_back(kumi::tuple{3.5}) , kumi::tuple{} ); 72 | TTS_EQUAL( kumi::pop_back(kumi::tuple{3.5,'e'}) , kumi::tuple{3.5} ); 73 | TTS_EQUAL( kumi::pop_back(kumi::tuple{4,3.5,'e'}), (kumi::tuple{4,3.5})); 74 | }; 75 | 76 | TTS_CASE("Check kumi::push_back/pop_back constexpr behavior") 77 | { 78 | TTS_EQUAL( (kumi::push_back(kumi::tuple{},4)), kumi::tuple{4} ); 79 | TTS_EQUAL( (kumi::push_back(kumi::tuple{3.5},4)), (kumi::tuple{3.5,4}) ); 80 | TTS_EQUAL( (kumi::push_back(kumi::tuple{3.5,'e'},4)), (kumi::tuple{3.5,'e',4}) ); 81 | 82 | TTS_EQUAL( kumi::pop_back(kumi::tuple{}) , kumi::tuple{} ); 83 | TTS_EQUAL( kumi::pop_back(kumi::tuple{3.5}) , kumi::tuple{} ); 84 | TTS_EQUAL( kumi::pop_back(kumi::tuple{3.5,'e'}) , kumi::tuple{3.5} ); 85 | TTS_EQUAL( kumi::pop_back(kumi::tuple{4,3.5,'e'}), (kumi::tuple{4,3.5})); 86 | }; 87 | -------------------------------------------------------------------------------- /test/unit/reduce.cpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #define TTS_MAIN 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | 15 | TTS_CASE("Check result::prod/sum/bit_* behavior") 16 | { 17 | TTS_TYPE_IS ( (kumi::result::sum_t,int>) 18 | , double 19 | ); 20 | 21 | TTS_TYPE_IS ( (kumi::result::prod_t,int>) 22 | , double 23 | ); 24 | 25 | TTS_TYPE_IS ( (kumi::result::bit_or_t,char>) 26 | , std::size_t 27 | ); 28 | 29 | TTS_TYPE_IS ( (kumi::result::bit_and_t,char>) 30 | , std::size_t 31 | ); 32 | 33 | TTS_TYPE_IS ( (kumi::result::sum_t>) 34 | , double 35 | ); 36 | 37 | TTS_TYPE_IS ( (kumi::result::prod_t>) 38 | , double 39 | ); 40 | 41 | TTS_TYPE_IS ( (kumi::result::bit_or_t>) 42 | , std::size_t 43 | ); 44 | 45 | TTS_TYPE_IS ( (kumi::result::bit_and_t>) 46 | , std::size_t 47 | ); 48 | }; 49 | 50 | TTS_CASE("Check tuple::sum behavior") 51 | { 52 | constexpr auto t = kumi::tuple {2., 1, short {55}, 'z'}; 53 | 54 | TTS_EQUAL(kumi::sum(kumi::tuple{}, 42), 42 ); 55 | TTS_EQUAL(kumi::sum(t, 0) , 180 ); 56 | 57 | TTS_CONSTEXPR_EQUAL(kumi::sum(kumi::tuple{}, 42), 42 ); 58 | TTS_CONSTEXPR_EQUAL(kumi::sum(t, 0) , 180 ); 59 | TTS_CONSTEXPR_EQUAL(kumi::sum(t) , 180 ); 60 | }; 61 | 62 | TTS_CASE("Check tuple::prod behavior") 63 | { 64 | constexpr auto t = kumi::tuple {2., 3, short {5}, '\a'}; 65 | 66 | TTS_EQUAL(kumi::prod(kumi::tuple{}, 42), 42 ); 67 | TTS_EQUAL(kumi::prod(t, 1) , 210 ); 68 | 69 | TTS_CONSTEXPR_EQUAL(kumi::prod(kumi::tuple{}, 42), 42 ); 70 | TTS_CONSTEXPR_EQUAL(kumi::prod(t, 1) , 210 ); 71 | TTS_CONSTEXPR_EQUAL(kumi::prod(t) , 210 ); 72 | }; 73 | 74 | TTS_CASE("Check tuple::bit_and behavior") 75 | { 76 | constexpr auto t = kumi::tuple {14UL, char{7}, short{6}}; 77 | 78 | TTS_EQUAL(kumi::bit_and(kumi::tuple{}, 42), 42 ); 79 | TTS_EQUAL(kumi::bit_and(t, 255) , 6UL ); 80 | 81 | TTS_CONSTEXPR_EQUAL(kumi::bit_and(kumi::tuple{}, 42), 42 ); 82 | TTS_CONSTEXPR_EQUAL(kumi::bit_and(t, 255) , 6UL ); 83 | TTS_CONSTEXPR_EQUAL(kumi::bit_and(t) , 6UL ); 84 | }; 85 | 86 | TTS_CASE("Check tuple::bit_or behavior") 87 | { 88 | constexpr auto t = kumi::tuple {2UL, 3, short {5}, char{64}}; 89 | 90 | TTS_EQUAL(kumi::bit_or(kumi::tuple{}, 42), 42 ); 91 | TTS_EQUAL(kumi::bit_or(t, 1) , 71UL ); 92 | 93 | TTS_CONSTEXPR_EQUAL(kumi::bit_or(kumi::tuple{}, 42), 42 ); 94 | TTS_CONSTEXPR_EQUAL(kumi::bit_or(t, 1) , 71UL ); 95 | TTS_CONSTEXPR_EQUAL(kumi::bit_or(t) , 71UL ); 96 | }; 97 | -------------------------------------------------------------------------------- /test/unit/reorder.cpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #define TTS_MAIN 9 | #include 10 | #include 11 | 12 | TTS_CASE("Check result::reorder behavior") 13 | { 14 | using tuple_t = kumi::tuple; 15 | 16 | TTS_TYPE_IS( (kumi::result::reorder_t), tuple_t ); 17 | TTS_TYPE_IS( (kumi::result::reorder_t), (kumi::tuple) ); 18 | TTS_TYPE_IS( (kumi::result::reorder_t ), (kumi::tuple) ); 19 | TTS_TYPE_IS( (kumi::result::reorder_t ), kumi::tuple<> ); 20 | }; 21 | 22 | TTS_CASE("Check reorder(tuple) behavior") 23 | { 24 | { 25 | auto t = kumi::tuple {1, 2., 3.4f, '5'}; 26 | 27 | { 28 | auto s = kumi::reorder<0,1,2,3>(t); 29 | TTS_EQUAL(s, t); 30 | } 31 | 32 | { 33 | auto s = kumi::reorder<3,2,1,0>(t); 34 | TTS_EQUAL(s, (kumi::tuple{'5',3.4f,2.,1})); 35 | } 36 | 37 | { 38 | auto s = kumi::reorder<0,1,2>(t); 39 | TTS_EQUAL(s, (kumi::tuple{1,2.,3.4f}) ); 40 | } 41 | 42 | { 43 | auto s = kumi::reorder<0,1>(t); 44 | TTS_EQUAL(s, (kumi::tuple{1,2.}) ); 45 | } 46 | 47 | { 48 | auto s = kumi::reorder<0>(t); 49 | TTS_EQUAL(s, (kumi::tuple{1}) ); 50 | } 51 | 52 | { 53 | auto s = kumi::reorder<1>(t); 54 | TTS_EQUAL(s, (kumi::tuple{2.}) ); 55 | } 56 | 57 | { 58 | auto s = kumi::reorder<2>(t); 59 | TTS_EQUAL(s, (kumi::tuple{3.4f}) ); 60 | } 61 | 62 | { 63 | auto s = kumi::reorder<3>(t); 64 | TTS_EQUAL(s, (kumi::tuple{'5'}) ); 65 | } 66 | 67 | { 68 | auto s = kumi::reorder<0,1,2,3,2,1,0>(t); 69 | TTS_EQUAL(s, (kumi::tuple{1,2.,3.4f,'5',3.4f,2.,1}) ); 70 | } 71 | } 72 | }; 73 | 74 | TTS_CASE("Check reorder(tuple) constexpr behavior") 75 | { 76 | { 77 | constexpr auto t = kumi::tuple {1, 2., 3.4f, '5'}; 78 | 79 | { 80 | constexpr auto s = kumi::reorder<0,1,2,3>(t); 81 | TTS_CONSTEXPR_EQUAL(s, t); 82 | } 83 | 84 | { 85 | constexpr auto s = kumi::reorder<3,2,1,0>(t); 86 | TTS_CONSTEXPR_EQUAL(s, (kumi::tuple{'5',3.4f,2.,1})); 87 | } 88 | 89 | { 90 | constexpr auto s = kumi::reorder<0,1,2>(t); 91 | TTS_CONSTEXPR_EQUAL(s, (kumi::tuple{1,2.,3.4f}) ); 92 | } 93 | 94 | { 95 | constexpr auto s = kumi::reorder<0,1>(t); 96 | TTS_CONSTEXPR_EQUAL(s, (kumi::tuple{1,2.}) ); 97 | } 98 | 99 | { 100 | constexpr auto s = kumi::reorder<0>(t); 101 | TTS_CONSTEXPR_EQUAL(s, (kumi::tuple{1}) ); 102 | } 103 | 104 | { 105 | constexpr auto s = kumi::reorder<1>(t); 106 | TTS_CONSTEXPR_EQUAL(s, (kumi::tuple{2.}) ); 107 | } 108 | 109 | { 110 | constexpr auto s = kumi::reorder<2>(t); 111 | TTS_CONSTEXPR_EQUAL(s, (kumi::tuple{3.4f}) ); 112 | } 113 | 114 | { 115 | constexpr auto s = kumi::reorder<3>(t); 116 | TTS_CONSTEXPR_EQUAL(s, (kumi::tuple{'5'}) ); 117 | } 118 | 119 | { 120 | constexpr auto s = kumi::reorder<0,1,2,3,2,1,0>(t); 121 | TTS_CONSTEXPR_EQUAL(s, (kumi::tuple{1,2.,3.4f,'5',3.4f,2.,1}) ); 122 | } 123 | } 124 | }; 125 | -------------------------------------------------------------------------------- /test/unit/reverse.cpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #define TTS_MAIN 9 | #include 10 | #include 11 | 12 | TTS_CASE("Check result::reverse behavior") 13 | { 14 | using tuple_t = kumi::tuple; 15 | 16 | TTS_TYPE_IS( (kumi::result::reverse_t), (kumi::tuple) ); 17 | }; 18 | 19 | TTS_CASE("Check reverse(tuple) behavior") 20 | { 21 | auto t = kumi::tuple {1, 2., 3.4f, '5'}; 22 | TTS_EQUAL(kumi::reverse(t), (kumi::tuple {'5', 3.4f, 2., 1 })); 23 | TTS_EQUAL(kumi::reverse(kumi::tuple<>{}), (kumi::tuple{})); 24 | }; 25 | 26 | TTS_CASE("Check reverse(tuple) constexpr behavior") 27 | { 28 | constexpr auto t = kumi::tuple {1, 2., 3.4f, '5'}; 29 | TTS_CONSTEXPR_EQUAL(kumi::reverse(t), (kumi::tuple {'5', 3.4f, 2., 1 })); 30 | TTS_CONSTEXPR_EQUAL(kumi::reverse(kumi::tuple<>{}), (kumi::tuple{})); 31 | }; 32 | -------------------------------------------------------------------------------- /test/unit/tie.cpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #define TTS_MAIN 9 | #include 10 | #include 11 | 12 | TTS_CASE("Check tuple_element of kumi::tuple") 13 | { 14 | char c {}; 15 | char const cc {}; 16 | double d {}; 17 | double const cd {}; 18 | float f {}; 19 | float const cf {}; 20 | 21 | auto tied = kumi::tie(c, d, f); 22 | auto const_tied = kumi::tie(cc, cd, cf); 23 | 24 | TTS_TYPE_IS((std::tuple_element_t<0, decltype(tied)>), char &); 25 | TTS_TYPE_IS((std::tuple_element_t<1, decltype(tied)>), double &); 26 | TTS_TYPE_IS((std::tuple_element_t<2, decltype(tied)>), float &); 27 | 28 | TTS_TYPE_IS((std::tuple_element_t<0, decltype(const_tied)>), char const &); 29 | TTS_TYPE_IS((std::tuple_element_t<1, decltype(const_tied)>), double const &); 30 | TTS_TYPE_IS((std::tuple_element_t<2, decltype(const_tied)>), float const &); 31 | }; 32 | 33 | TTS_CASE("Check construction of kumi::tuple via tie") 34 | { 35 | auto i = 1; 36 | auto f = 2.f; 37 | auto d = 3.; 38 | auto c = '4'; 39 | 40 | auto t1 = kumi::tie(i); 41 | auto t2 = kumi::tie(i, f); 42 | auto t3 = kumi::tie(i, f, d); 43 | auto t4 = kumi::tie(i, f, d, c); 44 | 45 | auto &[s1_0] = t1; 46 | auto& t1_0 = s1_0; 47 | TTS_CONSTEXPR_EXPECT((kumi::sized_product_type)); 48 | TTS_EQUAL(t1.size(), 1ULL); 49 | TTS_EQUAL(&t1_0, &i); 50 | 51 | auto &[s2_0, s2_1] = t2; 52 | auto& t2_0 = s2_0; 53 | auto& t2_1 = s2_1; 54 | TTS_CONSTEXPR_EXPECT((kumi::sized_product_type)); 55 | TTS_EQUAL(t2.size(), 2ULL); 56 | TTS_EQUAL(&t2_0, &i); 57 | TTS_EQUAL(&t2_1, &f); 58 | 59 | auto &[s3_0, s3_1, s3_2] = t3; 60 | auto& t3_0 = s3_0; 61 | auto& t3_1 = s3_1; 62 | auto& t3_2 = s3_2; 63 | TTS_CONSTEXPR_EXPECT((kumi::sized_product_type)); 64 | TTS_EQUAL(t3.size(), 3ULL); 65 | TTS_EQUAL(&t3_0, &i); 66 | TTS_EQUAL(&t3_1, &f); 67 | TTS_EQUAL(&t3_2, &d); 68 | 69 | auto &[s4_0, s4_1, s4_2, s4_3] = t4; 70 | auto& t4_0 = s4_0; 71 | auto& t4_1 = s4_1; 72 | auto& t4_2 = s4_2; 73 | auto& t4_3 = s4_3; 74 | TTS_CONSTEXPR_EXPECT((kumi::sized_product_type)); 75 | TTS_EQUAL(t4.size(), 4ULL); 76 | TTS_EQUAL(&t4_0, &i); 77 | TTS_EQUAL(&t4_1, &f); 78 | TTS_EQUAL(&t4_2, &d); 79 | TTS_EQUAL(&t4_3, &c); 80 | }; 81 | -------------------------------------------------------------------------------- /test/unit/to_ref.cpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #define TTS_MAIN 9 | #include 10 | #include 11 | #include 12 | 13 | TTS_CASE("Check tuple_element of kumi::to_ref result") 14 | { 15 | float const f {}; 16 | double d; 17 | std::reference_wrapper rf = f; 18 | std::reference_wrapper rd = d; 19 | 20 | auto made = kumi::make_tuple('1', 2., 3.f, rf, rd); 21 | auto made_lref = kumi::to_ref(made); 22 | auto made_rref = kumi::to_ref(std::move(made)); 23 | auto made_cref = kumi::to_ref(std::as_const(made)); 24 | 25 | TTS_TYPE_IS((std::tuple_element_t<0, decltype(made_lref)>), char&); 26 | TTS_TYPE_IS((std::tuple_element_t<1, decltype(made_lref)>), double&); 27 | TTS_TYPE_IS((std::tuple_element_t<2, decltype(made_lref)>), float&); 28 | TTS_TYPE_IS((std::tuple_element_t<3, decltype(made_lref)>), float const&); 29 | TTS_TYPE_IS((std::tuple_element_t<4, decltype(made_lref)>), double&); 30 | 31 | TTS_TYPE_IS((std::tuple_element_t<0, decltype(made_rref)>), char&&); 32 | TTS_TYPE_IS((std::tuple_element_t<1, decltype(made_rref)>), double&&); 33 | TTS_TYPE_IS((std::tuple_element_t<2, decltype(made_rref)>), float&&); 34 | TTS_TYPE_IS((std::tuple_element_t<3, decltype(made_rref)>), float const&); 35 | TTS_TYPE_IS((std::tuple_element_t<4, decltype(made_rref)>), double&); 36 | 37 | TTS_TYPE_IS((std::tuple_element_t<0, decltype(made_cref)>), char const&); 38 | TTS_TYPE_IS((std::tuple_element_t<1, decltype(made_cref)>), double const&); 39 | TTS_TYPE_IS((std::tuple_element_t<2, decltype(made_cref)>), float const&); 40 | TTS_TYPE_IS((std::tuple_element_t<3, decltype(made_cref)>), float const&); 41 | TTS_TYPE_IS((std::tuple_element_t<4, decltype(made_cref)>), double&); 42 | }; 43 | 44 | -------------------------------------------------------------------------------- /test/unit/transpose.cpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #define TTS_MAIN 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | TTS_CASE("Check result::transpose behavior") 15 | { 16 | using tuple1_t = kumi::tuple; 17 | using tuple2_t = kumi::tuple; 18 | using tuple_t = kumi::tuple; 19 | 20 | TTS_TYPE_IS ( (kumi::result::transpose_t), ( kumi::tuple < kumi::tuple 21 | , kumi::tuple 22 | , kumi::tuple 23 | > 24 | ) 25 | ); 26 | }; 27 | 28 | TTS_CASE("Check tuple::transpose behavior") 29 | { 30 | using kumi::tuple; 31 | 32 | auto numbers = tuple {1, 2, 3, 4}; 33 | auto letters = tuple {'a', 'b', 'c', 'd'}; 34 | auto ratio = tuple {1.f, 0.1f, 0.01f, 0.001f}; 35 | 36 | TTS_EQUAL(kumi::transpose(kumi::tuple{}),kumi::tuple{}); 37 | 38 | TTS_EQUAL((kumi::transpose(tuple{ numbers, letters, ratio })), 39 | (tuple {tuple {1, 'a' , 1.f}, tuple {2, 'b',0.1f}, tuple {3, 'c',0.01f}, tuple {4, 'd',0.001f}})); 40 | }; 41 | 42 | TTS_CASE("Check constexpr tuple::transpose behavior") 43 | { 44 | using kumi::tuple; 45 | 46 | constexpr auto numbers = tuple {1, 2, 3, 4}; 47 | constexpr auto letters = tuple {'a', 'b', 'c', 'd'}; 48 | constexpr auto ratio = tuple {1.f, 0.1f, 0.01f, 0.001f}; 49 | 50 | TTS_CONSTEXPR_EQUAL((kumi::transpose(tuple{ numbers, letters, ratio })), 51 | (tuple {tuple {1, 'a' , 1.f}, tuple {2, 'b',0.1f}, tuple {3, 'c',0.01f}, tuple {4, 'd',0.001f}})); 52 | }; 53 | -------------------------------------------------------------------------------- /test/unit/zip.cpp: -------------------------------------------------------------------------------- 1 | //================================================================================================== 2 | /* 3 | KUMI - Compact Tuple Tools 4 | Copyright : KUMI Project Contributors 5 | SPDX-License-Identifier: BSL-1.0 6 | */ 7 | //================================================================================================== 8 | #define TTS_MAIN 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | TTS_CASE("Check result::zip behavior") 15 | { 16 | using tuple1_t = kumi::tuple; 17 | using tuple2_t = kumi::tuple; 18 | using tuple3_t = kumi::tuple; 19 | 20 | TTS_TYPE_IS ( (kumi::result::zip_t) 21 | , ( kumi::tuple < kumi::tuple 22 | , kumi::tuple 23 | , kumi::tuple 24 | > 25 | ) 26 | ); 27 | }; 28 | 29 | TTS_CASE("Check tuple::zip behavior") 30 | { 31 | using kumi::tuple; 32 | 33 | auto numbers = tuple {1, 2, 3, 4}; 34 | auto letters = tuple {'a', 'b', 'c', 'd'}; 35 | auto ratio = tuple {1.f, 0.5f, 0.25, 0.01}; 36 | 37 | TTS_EQUAL((kumi::zip(kumi::tuple{},kumi::tuple{})),kumi::tuple{}); 38 | 39 | TTS_EQUAL((kumi::zip(numbers, letters)), 40 | (tuple {tuple {1, 'a'}, tuple {2, 'b'}, tuple {3, 'c'}, tuple {4, 'd'}})); 41 | 42 | TTS_EQUAL( 43 | (kumi::zip(numbers, letters, ratio)), 44 | (tuple { 45 | tuple {1, 'a', 1.f}, tuple {2, 'b', 0.5f}, tuple {3, 'c', 0.25}, tuple {4, 'd', 0.01}})); 46 | }; 47 | 48 | TTS_CASE("Check tuple::zip constexpr behavior") 49 | { 50 | using kumi::tuple; 51 | 52 | constexpr auto numbers = tuple {1, 2, 3, 4}; 53 | constexpr auto letters = tuple {'a', 'b', 'c', 'd'}; 54 | constexpr auto ratio = tuple {1.f, 0.5f, 0.25, 0.01}; 55 | 56 | TTS_CONSTEXPR_EQUAL((kumi::zip(numbers, letters)), 57 | (tuple {tuple {1, 'a'}, tuple {2, 'b'}, tuple {3, 'c'}, tuple {4, 'd'}})); 58 | 59 | TTS_CONSTEXPR_EQUAL( 60 | (kumi::zip(numbers, letters, ratio)), 61 | (tuple { 62 | tuple {1, 'a', 1.f}, tuple {2, 'b', 0.5f}, tuple {3, 'c', 0.25}, tuple {4, 'd', 0.01}})); 63 | }; 64 | --------------------------------------------------------------------------------