kblib 0.2.3
General utilities library for modern C++
logic.cpp
Go to the documentation of this file.
1#include "catch.hpp"
2
3#include "kblib/logic.h"
4
5#include <array>
6#include <iostream>
7#include <string>
8
9template <int I1, int I2>
10auto multi_template() -> int {
11 return I1 * I2;
12}
13
14template <int... Is>
15struct tag {};
16
17template <std::size_t COL, typename T, std::size_t rows, std::size_t cols,
18 std::size_t... row>
19constexpr auto get_col(const std::array<std::array<T, cols>, rows>& in,
20 std::index_sequence<row...>) -> std::array<T, rows> {
21 static_assert(rows == sizeof...(row), "");
22 return {std::get<COL>(std::get<row>(in))...};
23}
24
25template <typename T, std::size_t rows, std::size_t cols, std::size_t... row,
26 std::size_t... col>
27constexpr auto transpose_arr_impl(
28 const std::array<std::array<T, cols>, rows>& in,
29 std::index_sequence<col...>) -> std::array<std::array<T, rows>, cols> {
30 return {get_col<col>(in, std::make_index_sequence<rows>{})...};
31}
32
33template <typename T, std::size_t rows, std::size_t cols>
34constexpr auto transpose_arr(std::array<std::array<T, cols>, rows> in)
35 -> std::array<std::array<T, rows>, cols> {
36 return transpose_arr_impl(in, std::make_index_sequence<cols>{});
37 // C++17 version
38 /*
39 std::array<std::array<T, cols>, rows> ret{};
40 for (std::size_t C = 0; C != cols; ++C) {
41 for (std::size_t R = 0; R != rows; ++R) {
42 ret[R][C] = in[C][R];
43 }
44 }
45 return ret;*/
46}
47
48TEST_CASE("transpose") {
49 std::array<std::array<int, 4>, 3> input{
50 {{0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11}}};
51 std::array<std::array<int, 3>, 4> transposed{
52 {{0, 4, 8}, {1, 5, 9}, {2, 6, 10}, {3, 7, 11}}};
53
54 REQUIRE(transpose_arr(input) == transposed);
55}
56
57template <int I2, int... Is1>
58constexpr auto gen_row(tag<Is1...>) -> std::array<int (*)(), 8> {
59 return {&multi_template<Is1, I2>...};
60}
61
62template <typename Tag1, int... Is2>
63constexpr auto gen_dispatch_table() -> std::array<std::array<int (*)(), 8>, 8> {
64 std::array<std::array<int (*)(), 8>, 8> tmp = {gen_row<Is2>(Tag1{})...};
65 return transpose_arr(tmp);
66}
67
68constexpr std::array<std::array<int (*)(), 8>, 8> dispatch_table
70 25, 31>();
71
72auto multi_dispatcher(int i1, int i2) -> int {
73 constexpr std::array<int, 8> i1_lookup = {6, 13, 14, 19, 22, 22, 24, 27};
74 constexpr std::array<int, 8> i2_lookup = {1, 3, 5, 6, 18, 21, 25, 31};
75 auto find = [](int v, const std::array<int, 8>& arr) {
76 for (std::size_t i = 0; i != 8; ++i) {
77 if (arr[i] == v) {
78 return i;
79 }
80 }
81 throw std::out_of_range(std::to_string(v));
82 };
83
84 return dispatch_table[find(i1, i1_lookup)][find(i2, i2_lookup)]();
85}
86
87TEST_CASE("run-time template dispatching") {
88 for (auto x : {6, 13, 14, 19, 22, 22, 24, 27}) {
89 for (auto y : {1, 3, 5, 6, 18, 21, 25, 31}) {
90 // std::cout<<x<<" * "<<y<<" = "<<multi_dispatcher(x, y)<<'\n';
91 REQUIRE(multi_dispatcher(x, y) == x * y);
92 }
93 }
94}
constexpr std::array< std::array< int(*)(), 8 >, 8 > dispatch_table
Definition: logic.cpp:69
auto multi_template() -> int
Definition: logic.cpp:10
constexpr auto get_col(const std::array< std::array< T, cols >, rows > &in, std::index_sequence< row... >) -> std::array< T, rows >
Definition: logic.cpp:19
constexpr auto gen_dispatch_table() -> std::array< std::array< int(*)(), 8 >, 8 >
Definition: logic.cpp:63
auto multi_dispatcher(int i1, int i2) -> int
Definition: logic.cpp:72
constexpr auto gen_row(tag< Is1... >) -> std::array< int(*)(), 8 >
Definition: logic.cpp:58
constexpr auto transpose_arr_impl(const std::array< std::array< T, cols >, rows > &in, std::index_sequence< col... >) -> std::array< std::array< T, rows >, cols >
Definition: logic.cpp:27
TEST_CASE("transpose")
Definition: logic.cpp:48
constexpr auto transpose_arr(std::array< std::array< T, cols >, rows > in) -> std::array< std::array< T, rows >, cols >
Definition: logic.cpp:34
Provides basic compile-time logic operations.
auto to_string(Int num) -> std::string
Definition: convert.h:71
constexpr auto find(ForwardIt begin, EndIt end, const Elem &value) noexcept(noexcept(*begin==value)) -> ForwardIt
Finds a value in range [begin, end). If not found, returns end. It also allows for a sentinel end ite...
Definition: algorithm.h:290
Definition: logic.cpp:15