-
Notifications
You must be signed in to change notification settings - Fork 73
/
Copy path202.md
128 lines (101 loc) · 3.98 KB
/
202.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
<details open><summary>Info</summary><p>
* **Did you know that C++20 added `Using Enum` which introduces the enumerator names of the named enumeration as if by a using-declaration for each enumerator?**
* http://wg21.link/p1099
</p></details><details open><summary>Example</summary><p>
```cpp
enum quantlab { dev, research, };
struct Quantlab {
using enum quantlab;
};
int main() {
std::cout << Quantlab::dev; // prints 0
std::cout << Quantlab{}.research; // prints 1
}
```
> https://godbolt.org/z/jf4d8Kc
</p></details><details open><summary>Puzzle</summary><p>
* **Can you introduce missing enumerators by applying `using Enum` and add `is_enum_in_scope` routine to verify whether an enum is in a given scope?**
```cpp
enum E { e1, e2 };
enum class EC { ec1, ec2, };
enum class ECT : int { ect1, ect2 };
struct UsingEnum {
// TODO
};
static_assert(0 == UsingEnum::e1);
static_assert(1 == UsingEnum::e2);
static_assert([](auto t) { return requires { t.e1; }; }(UsingEnum{}));
static_assert([](auto t) { return requires { t.e2; }; }(UsingEnum{}));
struct UsingEnumValue {
// TODO
};
static_assert(0 == UsingEnumValue::e1);
static_assert([](auto t) { return requires { t.e1; }; }(UsingEnumValue{}));
static_assert(not [](auto t) { return requires { t.e2; }; }(UsingEnumValue{}));
struct UsingEnumsMix {
// TODO
};
static_assert(1 == UsingEnumsMix::e2);
static_assert(0 == int(UsingEnumsMix::ec1));
static_assert(0 == int(UsingEnumsMix::ect1));
static_assert(1 == int(UsingEnumsMix::ect2));
static_assert(not [](auto t) { return requires { t.e1; }; }(UsingEnumsMix{}));
static_assert(not [](auto t) { return requires { t.ec2; }; }(UsingEnumsMix{}));
static_assert([](auto t) { return requires { t.e2; }; }(UsingEnumsMix{}));
static_assert([](auto t) { return requires { t.ec1; }; }(UsingEnumsMix{}));
static_assert([](auto t) { return requires { t.ect1; }; }(UsingEnumsMix{}));
static_assert([](auto t) { return requires { t.ect2; }; }(UsingEnumsMix{}));
template<class T>
constexpr auto is_enum_in_scope(auto expr) { /*TODO*/ return false; }
struct NotInScope {};
static_assert(not is_enum_in_scope<NotInScope>([](auto e){ return requires { e.ec1; }; }));
struct InScope {
using enum EC;
};
static_assert(is_enum_in_scope<InScope>([](auto e){ return requires { e.ec1; }; }));
```
> https://godbolt.org/z/ocs9ME
</p></details><details><summary>Solutions</summary><p>
```cpp
enum E { e1, e2 };
enum class EC { ec1, ec2, };
enum class ECT : int { ect1, ect2 };
struct UsingEnum {
using enum E;
};
static_assert(0 == UsingEnum::e1);
static_assert(1 == UsingEnum::e2);
static_assert([](auto t) { return requires { t.e1; }; }(UsingEnum{}));
static_assert([](auto t) { return requires { t.e2; }; }(UsingEnum{}));
struct UsingEnumValue {
using E::e1;
};
static_assert(0 == UsingEnumValue::e1);
static_assert([](auto t) { return requires { t.e1; }; }(UsingEnumValue{}));
static_assert(not [](auto t) { return requires { t.e2; }; }(UsingEnumValue{}));
struct UsingEnumsMix {
using E::e2;
using EC::ec1;
using enum ECT;
};
static_assert(1 == UsingEnumsMix::e2);
static_assert(0 == int(UsingEnumsMix::ec1));
static_assert(0 == int(UsingEnumsMix::ect1));
static_assert(1 == int(UsingEnumsMix::ect2));
static_assert(not [](auto t) { return requires { t.e1; }; }(UsingEnumsMix{}));
static_assert(not [](auto t) { return requires { t.ec2; }; }(UsingEnumsMix{}));
static_assert([](auto t) { return requires { t.e2; }; }(UsingEnumsMix{}));
static_assert([](auto t) { return requires { t.ec1; }; }(UsingEnumsMix{}));
static_assert([](auto t) { return requires { t.ect1; }; }(UsingEnumsMix{}));
static_assert([](auto t) { return requires { t.ect2; }; }(UsingEnumsMix{}));
template<class T>
constexpr auto is_enum_in_scope(auto expr) { return expr(T{}); }
struct NotInScope {};
static_assert(not is_enum_in_scope<NotInScope>([](auto e){ return requires { e.ec1; }; }));
struct InScope {
using enum EC;
};
static_assert(is_enum_in_scope<InScope>([](auto e){ return requires { e.ec1; }; }));
```
> https://godbolt.org/z/KvYYKM
</p></details>