#include "catch.hpp" #include "kblib/logic.h" #include #include #include template auto multi_template() -> int { return I1 * I2; } template struct tag {}; template constexpr std::array get_col( const std::array, rows>& in, std::index_sequence) { static_assert(rows == sizeof...(row), ""); return {std::get(std::get(in))...}; } template constexpr std::array, cols> transpose_arr_impl( const std::array, rows>& in, std::index_sequence) { return {get_col(in, std::make_index_sequence{})...}; } template constexpr std::array, cols> transpose_arr( std::array, rows> in) { return transpose_arr_impl(in, std::make_index_sequence{}); // C++17 version /* std::array, rows> ret{}; for (std::size_t C = 0; C != cols; ++C) { for (std::size_t R = 0; R != rows; ++R) { ret[R][C] = in[C][R]; } } return ret;*/ } TEST_CASE("transpose") { std::array, 3> input{ {{0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11}}}; std::array, 4> transposed{ {{0, 4, 8}, {1, 5, 9}, {2, 6, 10}, {3, 7, 11}}}; REQUIRE(transpose_arr(input) == transposed); } template constexpr auto gen_row(tag) -> std::array { return {&multi_template...}; } template constexpr auto gen_dispatch_table() -> std::array, 8> { std::array, 8> tmp = {gen_row(Tag1{})...}; return transpose_arr(tmp); } constexpr std::array, 8> dispatch_table = gen_dispatch_table, 1, 3, 5, 6, 18, 21, 25, 31>(); auto multi_dispatcher(int i1, int i2) -> int { constexpr std::array i1_lookup = {6, 13, 14, 19, 22, 22, 24, 27}; constexpr std::array i2_lookup = {1, 3, 5, 6, 18, 21, 25, 31}; auto find = [](int v, const std::array& arr) { for (std::size_t i = 0; i != 8; ++i) { if (arr[i] == v) { return i; } } throw std::out_of_range(std::to_string(v)); }; return dispatch_table[find(i1, i1_lookup)][find(i2, i2_lookup)](); } TEST_CASE("run-time template dispatching") { for (auto x : {6, 13, 14, 19, 22, 22, 24, 27}) { for (auto y : {1, 3, 5, 6, 18, 21, 25, 31}) { // std::cout<