-
Notifications
You must be signed in to change notification settings - Fork 73
/
Copy path182.md
103 lines (86 loc) · 2.95 KB
/
182.md
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
<details open><summary>Info</summary><p>
* **Did you know about the proposal to add Non-terminal variadic template parameters?**
</p></details><details open><summary>Example</summary><p>
```cpp
template<class... Ts, class T>
auto foo(Ts..., T t) { return t; }
int main() {
std::cout << foo(1); // prints 1
std::cout << foo(1, 2, 3, 4); // prints 4
std::cout << foo(); // compilation error
}
```
> https://godbolt.org/z/z9jvd4vhx
</p></details><details open><summary>Puzzle</summary><p>
* **[NTVTP] Can you implement `last_using_{get,apply,inplace_lambda}` functions which will return the last element of given tuple?**
```cpp
/* TODO */
constexpr auto last_using_get(...);
constexpr auto last_using_apply(...);
constexpr auto last_using_inplace_lambda(...);
int main() {
"tuple - get last"_test = [] {
should("return the only element") = []{
auto tuple = std::tuple{42};
42_i == last_using_get(tuple) and
42_i == last_using_apply(tuple) and
42_i == last_using_inplace_lambda(tuple);
};
should("return the last element with same types") = [] {
auto tuple = std::tuple{4l, 2l, 42l};
42_l == last_using_get(tuple) and
42_l == last_using_apply(tuple) and
42_l == last_using_inplace_lambda(tuple);
};
should("return the last element with differen types") = [] {
auto tuple = std::tuple{1, 2.0, "3", 4ul};
4_ul == last_using_get(tuple) and
4_ul == last_using_apply(tuple) and
4_ul == last_using_inplace_lambda(tuple);
};
};
}
```
> https://godbolt.org/z/111hzT
</p></details><details><summary>Solutions</summary><p>
```cpp
constexpr auto last_using_get(const auto& tuple) noexcept
{
using tuple_type = std::decay_t<decltype(tuple)>;
return std::get<std::tuple_size_v<tuple_type> - 1>(tuple);
}
constexpr auto last_using_apply(const auto& tuple)
{
return std::apply([](const auto... args) { return (args, ...); }, tuple);
}
constexpr auto last_using_inplace_lambda(const auto& tuple) {
return [&](){
return last_using_get(tuple);
}();
}
```
> https://godbolt.org/z/1P3Mcj
```cpp
template <typename TTuple>
constexpr auto last_using_get(TTuple&& t) -> decltype(auto) {
constexpr auto size = std::tuple_size_v<std::remove_reference_t<TTuple>>;
return std::get<size-1>(std::forward<TTuple>(t));
}
template <typename TTuple>
constexpr auto last_using_apply(TTuple&& t) -> decltype(auto) {
return std::apply(
[](auto&&...args) -> decltype(auto) {
return (std::forward<decltype(args)>(args), ...);
},
std::forward<TTuple>(t));
}
template <typename TTuple>
constexpr auto last_using_inplace_lambda(TTuple&& t) -> decltype(auto) {
constexpr auto size = std::tuple_size_v<std::remove_reference_t<TTuple>>;
return [&] <auto... I> (std::index_sequence<I...>) -> decltype(auto) {
return std::get<(I,...)>(std::forward<TTuple>(t));
}(std::make_index_sequence<size>{});
}
```
> https://godbolt.org/z/c5PzYK
</p></details>