forked from Mq-b/Loser-HomeWork
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Matrix-A-reflect.cpp
70 lines (65 loc) · 2.04 KB
/
Matrix-A-reflect.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
//!all
#include<iostream>
#include<cstdint>
#include<vector>
#include<mutex>
#include<experimental/reflect>
namespace reflect = std::experimental::reflect;
template<typename T>
requires std::is_aggregate_v<T>
constexpr std::size_t size() {
if constexpr (std::is_array_v<T>) {
return std::extent_v<T>;
}
else {
using Reflected_t = reflexpr(T);
using data_members = reflect::get_data_members_t<Reflected_t>;
return reflect::get_size_v<data_members>;
}
}
template<typename T, typename Func>
requires std::is_aggregate_v<T>
void for_each_member(const T& t, Func func) {
constexpr auto T_size = size<T>();
if constexpr (std::is_array_v<T>) {
for (const auto& i : t) {
func(i);
}
}
else {
using Reflected_t = reflexpr(T);
using data_members = reflect::get_data_members_t<Reflected_t>;
[&] <size_t... ints>(std::index_sequence<ints...>) {
std::tuple args{ reflect::get_pointer_v<reflect::get_element_t<ints, data_members>>... };
auto application = [&](auto&&... args) { (func(t.*args), ...); };
std::apply(application, args);
}(std::make_index_sequence<T_size>{});
}
}
int main() {
std::string ts{ "123" };
struct X { const std::string s; } x{ ts };
struct Y { double a[2]{ 3., 2. }, b{}, c{}, d{}; } y;
Y ys[10];
struct Z { std::mutex m; } z;
std::cout << size<X>() << std::endl;
std::cout << size<Y>() << std::endl;
std::cout << size<decltype(ys)>() << std::endl;
std::cout << size<Z>() << std::endl;
auto print = [](const auto& member) {
if constexpr (!requires { std::cout << member; }) {
std::cout << "[" << &member << "] ";
}
else {
std::cout << member << ' ';
}
};
for_each_member(x, print);
std::cout << std::endl;
for_each_member(y, print);
std::cout << std::endl;
for_each_member(ys, print);
std::cout << std::endl;
for_each_member(z, print);
std::cout << std::endl;
}