-
Notifications
You must be signed in to change notification settings - Fork 16
/
attrib2.cxx
68 lines (56 loc) · 1.64 KB
/
attrib2.cxx
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
#include <iostream>
#include <type_traits>
template<typename type_t>
const char* enum_to_name(type_t x) {
switch(x) {
@meta for enum(type_t x2 : type_t)
case x2:
return @enum_name(x2);
default:
return "<unknown>";
}
}
using title [[attribute]] = const char*;
using url [[attribute]] = const char*;
using magic [[attribute]] = int;
enum class edge {
left, top, right, bottom,
};
enum class corner {
nw, ne, se, sw,
};
template<typename type_t>
std::string to_string(type_t x) {
if constexpr(std::is_enum_v<type_t>) {
return enum_to_name(x);
} else if constexpr(std::is_same_v<bool, type_t>) {
return x ? "true" : "false";
} else if constexpr(std::is_arithmetic_v<type_t>) {
return std::to_string(x);
} else {
static_assert(std::is_same_v<const char*, type_t>);
return x;
}
}
struct foo_t {
[[.edge=right, .url="https://www.fake.url/"]] int x;
[[.title="Sometimes a vowel", .corner=ne]] int y;
[[.magic=10101, .title="The magic number"]] int z;
};
template<typename type_t>
void print_member_attributes() {
std::cout<< "Member attributes for "<< @type_string(type_t)<< "\n";
@meta for(int i = 0; i < @member_count(type_t); ++i) {{
// Loop over each member.
std::cout<< " "<< @member_name(type_t, i)<< ":\n";
// @member_attribute_list is a type parameter pack of all attribute names.
// Loop over them and print them out.
@meta for typename(t : { @member_attribute_list(type_t, i)... }) {
std::cout<< " "<< @type_string(t)<< " = "<<
to_string(@member_attribute(type_t, i, t))<< "\n";
}
}}
}
int main() {
print_member_attributes<foo_t>();
}