44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |  |
52 |
53 |
54 |
55 | $projectname $projectnumber
56 |
57 | $projectbrief
58 | |
59 |
60 |
61 |
62 |
63 | $projectbrief
64 | |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 | $searchbox |
73 |
74 |
75 |
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