-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexample.cpp
92 lines (76 loc) · 2.92 KB
/
example.cpp
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
#include "mirror.hpp"
#include <iostream>
#include <cstdint>
#include <bit>
#include <iomanip>
using namespace mirror;
template <typename T>
struct color_rgb {
T red{};
T green{};
T blue{};
// Reflection information in the class itself
static constexpr inline std::tuple reflection{
field{ "red", &color_rgb::red },
field{ "green", &color_rgb::green },
field{ "blue", &color_rgb::blue },
};
};
template <typename T>
color_rgb(T, T, T) -> color_rgb<T>;
struct attr_mask {
uint32_t mask;
};
struct attr_json_name {
std::string_view json_name;
};
struct color_rgba32 {
uint8_t red{};
uint8_t green{};
uint8_t blue{};
uint8_t alpha{};
// Reflection information with extra fields
static constexpr inline std::tuple reflection{
field{ "red", &color_rgba32::red, attr_mask{ 0x000000FFu }, attr_json_name{ "r" } },
field{ "green", &color_rgba32::green, attr_mask{ 0x0000FF00u }, attr_json_name{ "g" } },
field{ "blue", &color_rgba32::blue, attr_mask{ 0x00FF0000u }, attr_json_name{ "b" } },
field{ "alpha", &color_rgba32::alpha, attr_mask{ 0xFF000000u }, attr_json_name{ "a" } },
};
};
// Reflection informatino for an external class
template <typename T1, typename T2>
inline constexpr const std::tuple mirror::reflection_of<std::pair<T1, T2>> = {
field{ "first", &std::pair<T1, T2>::first },
field{ "second", &std::pair<T1, T2>::second },
};
constexpr auto print_field = [](std::string_view name, auto value) {
std::cout << name << "=";
if constexpr (std::is_integral_v<decltype(value)>)
std::cout.operator<<(value).operator<<(std::endl); // avoid printing uint8_t as character
else
std::cout << value << std::endl;
};
int main() {
std::cout << std::endl << "reading struct fields:" << std::endl;
for_each_field(std::make_pair("answer", 42), [](std::string_view name, auto value) {
std::cout << name << "=" << value << std::endl;
});
for_each_field(color_rgb{ 1.0, 0.0, 0.5 }, [](std::string_view name, auto value) {
std::cout << name << "=" << value << std::endl;
});
const std::pair p{ 1.0, "abc" };
for_each_field(p, print_field);
std::cout << std::endl << "writing struct fields:" << std::endl;
color_rgba32 c;
uint32_t input = 0xFFCC80EE;
for_each_field(c, [input](std::string_view name, uint8_t& value, const attr_mask& mask) {
value = (input & mask.mask) >> std::countr_zero(mask.mask);
});
for_each_field(c, print_field);
std::cout << std::endl << "enumerating struct fields:" << std::endl;
for_each_field<color_rgba32>(
[](std::string_view name, const field<color_rgba32, uint8_t, attr_mask, attr_json_name>& field) {
std::cout << name << " (mask: " << std::hex << std::setw(8) << std::setfill('0') << field.mask
<< std::dec << ", json: " << field.json_name << ")" << std::endl;
});
}