-
Notifications
You must be signed in to change notification settings - Fork 73
/
Copy path277.md
150 lines (114 loc) · 3.29 KB
/
277.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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
<details open><summary>Info</summary><p>
* **Did you know that C++17 structured bindings support to custom classes can be added?**
* https://wg21.link/P1061
</p></details><details open><summary>Example</summary><p>
```cpp
struct foo {
int i{};
std::string s{};
};
template <auto N>
const auto& get(const foo& f) {
if constexpr (N == 0) {
return f.i;
} else if constexpr (N == 1) {
return f.s;
}
}
namespace std {
template <>
struct tuple_size<::foo> : integral_constant<std::size_t, 2> {};
template <std::size_t N>
struct tuple_element<N, ::foo> {
using type = decltype(get<N>(std::declval<::foo&>()));
};
} // namespace std
int main() {
auto [i, s] = foo{.i = 42, .s = "str"};
assert(42 == i);
assert("str" == s);
}
```
> https://godbolt.org/z/n66GMfWao
</p></details><details open><summary>Puzzle</summary><p>
* **Can you add structured bindings support to std::index_sequence?**
```cpp
namespace std {
// TODO
}
int main() {
{
auto [... Is] = std::make_index_sequence<0>{};
static_assert(sizeof...(Is) == 0);
}
{
auto [... Is] = std::make_index_sequence<3>{};
static_assert(sizeof...(Is) == 3);
static_assert(
typeid(std::tuple{std::integral_constant<std::size_t, 0>{},
std::integral_constant<std::size_t, 1>{},
std::integral_constant<std::size_t, 2>{}}) ==
typeid(std::tuple{Is...}));
}
{
auto [... Is] = std::make_index_sequence<42>{};
static_assert(sizeof...(Is) == 42);
}
}
```
> https://godbolt.org/z/qavcThr9K
</p></details><details><summary>Solutions</summary><p>
```cpp
namespace std {
template <std::size_t N>
using index_constant = std::integral_constant<std::size_t, N>;
template <auto N, auto... Is>
auto get(index_sequence<Is...>) {
return index_constant<N>{};
}
template <auto... Is>
struct tuple_size<index_sequence<Is...>> : index_constant<sizeof...(Is)> {};
template <auto N, auto... Is>
struct tuple_element<N, index_sequence<Is...>> {
using type = index_constant<N>;
};
} // namespace std
```
> https://godbolt.org/z/466j7snqK
```cpp
namespace std {
template<auto N, size_t ...Ints>
auto constexpr get(const index_sequence<Ints...>&) {
return get<N>(tuple{integral_constant<size_t, Ints>{}...});
};
template<size_t ... Ints>
struct tuple_size<index_sequence<Ints...>> : integral_constant<size_t, sizeof...(Ints)> {};
template<size_t N, size_t ...Ints>
struct tuple_element<N, index_sequence<Ints...>> {
using type = decltype(get<N>(tuple{integral_constant<size_t, Ints>{}...}));
};
}
```
> https://godbolt.org/z/6fb7e89fK
```cpp
namespace stdext {
template <std::size_t... Is>
struct index_sequence : std::index_sequence<Is...> {
template <std::size_t I>
auto get() const -> std::tuple_element_t<I, index_sequence> {
return {};
}
};
namespace detail {
template <std::size_t N, class = std::make_index_sequence<N>>
struct make_index_sequence;
template <std::size_t N, auto... Is>
struct make_index_sequence<N, std::index_sequence<Is...>> {
using type = index_sequence<Is...>;
};
} // namespace detail
template <std::size_t N>
using make_index_sequence = typename detail::make_index_sequence<N>::type;
} // namespace stdext
```
> https://godbolt.org/z/jeY9qoYG4