Repository navigation
Expand file tree
/
Copy pathmain.cpp
More file actions
118 lines (87 loc) · 3.72 KB
/
Copy pathmain.cpp
File metadata and controls
118 lines (87 loc) · 3.72 KB
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include <iostream>
#include <string>
#include "access/access.h"
struct hidden {
private:
int x = 10;
std::string str = "hello";
int func() const &{ return x; }
int sum(int a, int b) { return a + b; }
void rrefOnly() && {}
static int sta() { return y; }
static int y;
virtual int vf() { return 1; }
};
int hidden::y = 12345;
struct base {
private:
virtual void vf() { std::cout << "base\n"; }
};
struct derived : public base {
private:
void vf() override { std::cout << "derived\n"; }
};
ACCESS_CREATE_TAG(tag_hidden_x, hidden, x);
ACCESS_CREATE_UNIQUE_TAG(hidden, x);
ACCESS_CREATE_TAG(tag_hidden_str, hidden, str);
ACCESS_CREATE_TAG(tag_hidden_func, hidden, func);
ACCESS_CREATE_TAG(tag_hidden_sum, hidden, sum);
ACCESS_CREATE_TAG(tag_hidden_sta, hidden, sta);
ACCESS_CREATE_TAG(tag_hidden_y, hidden, y);
ACCESS_CREATE_TAG(tag_hidden_rref, hidden, rrefOnly);
ACCESS_CREATE_UNIQUE_TAG(base, vf);
int main() {
hidden h;
// can read and write private member
std::cout << access::get<tag_hidden_x>(h) << std::endl;
access::get<tag_hidden_x>(h) = 100;
std::cout << access::get<tag_hidden_x>(h) << std::endl;
std::cout << access::get<tag_hidden_str>(h) << std::endl;
access::get<tag_hidden_str>(std::move(h));
std::cout << access::get<tag_hidden_str>(h) << std::endl;
// using unnamed(unique) tag
std::cout << access::get<ACCESS_GET_UNIQUE_TAG(hidden, x)>(h) << std::endl;
access::get<ACCESS_GET_UNIQUE_TAG(hidden, x)>(h) = 200;
std::cout << access::get<ACCESS_GET_UNIQUE_TAG(hidden, x)>(h) << std::endl;
// can read and write static private member
std::cout << access::get<tag_hidden_y>() << std::endl;
access::get<tag_hidden_y>() = -123;
std::cout << access::get<tag_hidden_y>() << std::endl;
// can call private member function
access::call<tag_hidden_func>(h);
(h.*access::get<tag_hidden_func>(h))();
// value types overloads
access::call<tag_hidden_sum>(h, 1, 2);
access::call<tag_hidden_sum>(std::move(h), 1, 2);
// access::call<tag_hidden_rref>(h);
access::call<tag_hidden_rref>(hidden());
// can call private static member function
access::call<tag_hidden_sta>();
access::get<tag_hidden_sta>()();
// access::call<tag_hidden_sta>(h);
const hidden h2;
// const overload is read-only
access::get<tag_hidden_x>(h2);
// access::get<tag_hidden_x>(h2) = 132;
access::call<tag_hidden_func>(h2);
(h2.*access::get<tag_hidden_func>(h2))();
// Note that access::Type_t returns actual type, while access::get returns it's reference
static_assert(std::is_same<access::Type_t<tag_hidden_x>, int>::value, "");
static_assert(std::is_same<decltype(access::get<tag_hidden_x>(h)), int&>::value, "");
// Same applies to the static member variables
static_assert(std::is_same<access::Type_t<tag_hidden_y>, int>::value, "");
static_assert(std::is_same<decltype(access::get<tag_hidden_y>()), int&>::value, "");
// Note that type of function is different too
static_assert(std::is_same<access::Type_t<tag_hidden_func>, int() const&>::value, ""); // function type
static_assert(std::is_same<decltype(access::get<tag_hidden_func>(std::declval<hidden>())), int (hidden::*)() const&>::value, ""); // function pointer type
// Same applies to the static member function
static_assert(std::is_same<access::Type_t<tag_hidden_sta>, int()>::value, ""); // function type
static_assert(std::is_same<decltype(access::get<tag_hidden_sta>()), int(*)()>::value, ""); // function pointer type
// private virtual function can be called
base b;
derived d;
access::call<ACCESS_GET_UNIQUE_TAG(base, vf)>(b);
access::call<ACCESS_GET_UNIQUE_TAG(base, vf)>(d);
access::call<ACCESS_GET_UNIQUE_TAG(base, vf)>(static_cast<base &>(d));
return 0;
}