Skip to content

Commit

Permalink
[332] - Did you know that in C++ you can generate jump tables at comp…
Browse files Browse the repository at this point in the history
…ile-time?
  • Loading branch information
kris-jusiak committed May 29, 2023
1 parent 44d66c7 commit 73ee938
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

### Tips

* [[332]](https://github.com/QuantlabFinancial/cpp_tip_of_the_week/blob/master/tips/332.md) - Did you know that in C++ you can generate jump tables at compile-time?
* [[331]](https://github.com/QuantlabFinancial/cpp_tip_of_the_week/blob/master/tips/331.md) - Did you about C++17 std::index_sequence, std::make_index_sequence?
* [[330]](https://github.com/QuantlabFinancial/cpp_tip_of_the_week/blob/master/tips/330.md) - Did you know that C++17 added std::pmr::polymorphic_allocator?
* [[329]](https://github.com/QuantlabFinancial/cpp_tip_of_the_week/blob/master/tips/329.md) - Did you know about C++ allows to pass Pointer To Member Function via template parameter?
Expand Down
68 changes: 68 additions & 0 deletions tips/331.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

* **Did you about C++17 std::index_sequence, std::make_index_sequence?**

* https://eel.is/c++draft/utility.syn#lib:index_sequence

</p></details><details open><summary>Example</summary><p>

```cpp
Expand Down Expand Up @@ -51,4 +53,70 @@ static_assert(matrix<Foo>[2][2]);
> https://godbolt.org/z/3YvfqezPa

</p></details><details><summary>Solutions</summary><p>

```cpp
template <class T, std::size_t N = 3, class = std::make_index_sequence<N>>
constexpr const std::array<std::array<int, N>, N> matrix{};

template <class T, auto N, auto... Is>
constexpr const std::array matrix<T, N, std::index_sequence<Is...>>{
[]<auto I> -> std::array<int, 3> {
return {[]<auto J> -> int {
return requires(T v, id<I, J> p) { v.bar(p); };
}.template operator()<Is>()...};
}.template operator()<Is>()...};
```
> https://godbolt.org/z/Yq9xdYo3a
```cpp
template <class T, auto... ns>
constexpr auto has = []() { return requires(T t) { t.bar(id<ns...>{}); }; };
template <class T, auto R, auto N>
constexpr auto row = []() {
constexpr auto make_row =
[]<auto... I>(std::index_sequence<I...>) -> std::array<bool, N> {
return {has<T, R, I>()...};
};
return make_row(std::make_index_sequence<N>{});
};
template <class T, auto N>
constexpr auto rows = []() {
constexpr auto make_rows = []<auto... R>(std::index_sequence<R...>)
-> std::array<std::array<bool, N>, N> { return {row<T, R, N>()...}; };
return make_rows(std::make_index_sequence<N>{});
};
template <class T, auto N = 3>
constexpr const auto matrix = rows<T, N>();
```

> https://godbolt.org/z/Gcx4sd5E3

```cpp
template <typename T, auto N, auto X, auto C = X % N, auto R = (X - C) / N>
concept hasBar = requires(T t) {
{ t.bar(std::declval<id<R, C>>()) };
};

template <auto N, typename... Args>
constexpr std::array<std::array<long, N>, N> make_symmetric_matrix(
Args&&... args) {
return {std::forward<Args>(args)...};
}

template <class T, auto N = 3>
constexpr const auto matrix =
[]<auto... Indices>(std::index_sequence<Indices...>)
-> std::array<std::array<long, N>, N> {
return make_symmetric_matrix<N>(hasBar<T, N, static_cast<int>(Indices)>...);
}(std::make_index_sequence<N * N>{});
```
> https://godbolt.org/z/bdjEadn5f
</p></details>
43 changes: 43 additions & 0 deletions tips/332.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<details open><summary>Info</summary><p>

* **Did you know that in C++ you can generate jump tables at compile-time?**

* https://en.wikipedia.org/wiki/Branch_table

</p></details><details open><summary>Example</summary><p>

```cpp
template<auto N> constexpr auto foo() { return N; }

constexpr std::array jump_table{
foo<0>,
foo<1>,
foo<2>,
};

static_assert(0 == jump_table[0]());
static_assert(1 == jump_table[1]());
static_assert(2 == jump_table[2]());
```
> https://godbolt.org/z/x3xa9erGE
</p></details><details open><summary>Puzzle</summary><p>
* **Can you implemnt dispatch fn which generates jump table for given N?**
```cpp
template<auto N> constexpr auto foo() { return N; }
template<auto N = 42>
constexpr auto dispatch(auto n); // TODO
static_assert(1 == dispatch(1));
static_assert(7 == dispatch(7));
static_assert(23 == dispatch(23));
```

> https://godbolt.org/z/4M9x1vjcG
</p></details><details><summary>Solutions</summary><p>
</p></details>

0 comments on commit 73ee938

Please sign in to comment.