-
Notifications
You must be signed in to change notification settings - Fork 137
/
akchilov3.cpp
96 lines (86 loc) · 2.48 KB
/
akchilov3.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
93
94
95
96
#include<iostream>
#include<string>
template<typename structT, typename T>
std::size_t align_offset_seek(std::size_t& layer, std::size_t& offset)
{
constexpr std::size_t pack_size = alignof(structT);
constexpr std::size_t offset_size = sizeof(T);
if (offset % offset_size) {
offset += 1;
if (offset + offset_size > pack_size) {
layer += 1;
offset = 0;
}
return align_offset_seek<structT, T>(layer, offset);
}
return pack_size * layer + offset;
}
template<typename structT, typename T>
void align_offset_advance(std::size_t& layer, std::size_t& offset)
{
constexpr std::size_t pack_size = alignof(structT);
constexpr std::size_t advance_size = sizeof(T);
if (offset + advance_size < pack_size) {
offset += advance_size;
}
else {
layer += advance_size / pack_size;
layer += advance_size % pack_size ? 1 : 0;
offset = 0;
}
}
template<typename structT, typename T>
T& read_from_align_offset(structT* base_ptr, const std::size_t offset)
{
return *(reinterpret_cast<T*>(reinterpret_cast<unsigned char*>(base_ptr) + offset));
}
template<class F, class TT> struct init_and_call
{
F f;
TT* x;
inline static std::size_t value = 0;
inline static std::size_t layer = 0;
template<class T>
operator T() {
const std::size_t off = align_offset_seek<TT, T>(layer, value);
f(read_from_align_offset<TT, T>(x, off));
align_offset_advance<TT, T>(layer, value);
return T{};
};
};
template<class F, class T, class first, class ...rest> constexpr void for_each_member_impl(F f, T* x)
{
if constexpr (!requires{ T{ first{}, rest{}... }; }) {
T{ rest{f, x}... };
}
else {
for_each_member_impl<F, T, init_and_call<F, T>, first, rest...>(f, x);
}
}
template<class F, class T> constexpr void for_each_member(F f, T& x)
{
for_each_member_impl<F, T, init_and_call<F, T>>(f, &x);
}
int main()
{
struct X
{
char aaa{ 'A' };
int aaaak{ 100 };
std::string str{ "hello X!" };
char cc{ 'k' };
int a{ 10 };
char c{ 'l' };
short r{ 123 };
char e{ 'u' };
short rr{ 889 };
int ac{ 19 };
double b{ 2.33 };
std::string str2{ "hello X again!" };
double bbg{ 4.55 };
};
X x{};
for_each_member([](auto&& i) {
std::cout << i << ' ';
}, x);
}