Skip to content

Commit

Permalink
[366] - solution using friend injection
Browse files Browse the repository at this point in the history
  • Loading branch information
kris-jusiak committed Jan 28, 2024
1 parent 1bf3de9 commit 64f9758
Showing 1 changed file with 42 additions and 0 deletions.
42 changes: 42 additions & 0 deletions tips/366.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,4 +104,46 @@ int main() {
> https://godbolt.org/z/P6sTdPEG8
```cpp
template<class...> struct type_list {};
template<auto> struct nth { auto friend get(nth); auto friend get(nth); };
template<auto N, class T> struct set { auto friend get(nth<N>) { return T{}; } };
template<class T, template<class...> class TList, class... Ts> auto append_impl(TList<Ts...>) -> TList<Ts..., T>;
template<class T, auto N = 0, auto unique = []{}>
consteval auto append() {
if constexpr (requires { get(nth<N>{}); }) {
append<T, N+1, unique>();
} else if constexpr (N == 0) {
void(set<N, type_list<T>>{});
} else {
void(set<N, decltype(append_impl<T>(get(nth<N-1>{})))>{});
}
}
template<auto unique = []{}, auto N = 0>
consteval auto get_list() {
if constexpr (requires { get(nth<N>{}); }) {
return get_list<unique, N+1>();
} else if constexpr (N == 0) {
return type_list{};
} else {
return get(nth<N-1>{});
}
}
int main() {
static_assert(typeid(get_list()) == typeid(type_list<>));
append<int>();
static_assert(typeid(get_list()) == typeid(type_list<int>));
append<float>();
static_assert(typeid(get_list()) == typeid(type_list<int, float>));
}
```

> https://godbolt.org/z/d7GrW1j76
</p></details>

0 comments on commit 64f9758

Please sign in to comment.