-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtest_offset_trick.cpp
45 lines (40 loc) · 1.21 KB
/
test_offset_trick.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
#include "boost/pfr/precise.hpp"
#include <cassert>
#include <cstddef>
#include <type_traits>
struct A {
int i;
double b;
};
struct test {
A a;
int b;
unsigned long long d;
};
template <typename test, std::size_t... indices> struct converted_test {
using num_fields =
std::integral_constant<std::size_t, boost::pfr::tuple_size<test>::value>;
static_assert(sizeof...(indices) == num_fields::value);
static constexpr std::size_t field_sizes[num_fields::value] = {
sizeof(boost::pfr::tuple_element_t<indices, test>)...};
static constexpr std::size_t translate_field(std::size_t in,
std::size_t offset_so_far = 0) {
if (in == 0)
return offset_so_far;
else {
return translate_field(in - field_sizes[offset_so_far],
offset_so_far + 1);
}
}
};
#define DECT(x...) std::decay_t<decltype(x)>
#define field(a, x) \
boost::pfr::get<converted_test<DECT(a), 0, 1, 2>::translate_field( \
offsetof(DECT(a), x))>(a)
int main() {
converted_test<test, 0, 1, 2> t;
test t2;
t2.b = 4;
assert(t2.b == field(t2, b));
return field(t2, b);
}