- 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
#define EMPTY(...)
#define DEFER(...) __VA_ARGS__ EMPTY()
#define EXPAND(...) __VA_ARGS__
#define PARENS ()
#define CONCAT_IMPL(L, R) L ## R
#define CONCAT(L, R) CONCAT_IMPL(L, R)
#define EVAL(...) __VA_ARGS__
#define EVAL_1(...) __VA_ARGS__
#define EVAL_1_1(...) __VA_ARGS__
#define EVAL_1_2(...) __VA_ARGS__
#define EVAL_2(...) EVAL_1(EVAL_1(__VA_ARGS__))
#define EVAL_4(...) EVAL_2(EVAL_2(__VA_ARGS__))
#define EVAL_8(...) EVAL_4(EVAL_4(__VA_ARGS__))
#define EVAL_16(...) EVAL_8(EVAL_8(__VA_ARGS__))
#define EVAL_32(...) EVAL_16(EVAL_16(__VA_ARGS__))
#define EVAL_64(...) EVAL_32(EVAL_32(__VA_ARGS__))
#define EVAL_128(...) EVAL_64(EVAL_64(__VA_ARGS__))
#define EVAL_256(...) EVAL_128(EVAL_128(__VA_ARGS__))
#define EVAL_512(...) EVAL_256(EVAL_256(__VA_ARGS__))
#define EVAL_1024(...) EVAL_512(EVAL_512(__VA_ARGS__))
#define FOR_EACH_64(MACRO, ...) EVAL_64(FOR_EACH_IMPL(MACRO, __VA_ARGS__))
#define FOR_EACH_128(MACRO, ...) EVAL_128(FOR_EACH_IMPL(MACRO, __VA_ARGS__))
#define FOR_EACH_256(MACRO, ...) EVAL_256(FOR_EACH_IMPL(MACRO, __VA_ARGS__))
#define FOR_EACH_512(MACRO, ...) EVAL_512(FOR_EACH_IMPL(MACRO, __VA_ARGS__))
#define FOR_EACH_1024(MACRO, ...) EVAL_1024(FOR_EACH_IMPL(MACRO, __VA_ARGS__))
#define FOR_EACH(MACRO, ...) EVAL_1024(FOR_EACH_IMPL(MACRO, __VA_ARGS__))
#define FOR_EACH_NEXT() FOR_EACH_IMPL
#define FOR_EACH_IMPL(MACRO, ARG1, ...) MACRO(ARG1)__VA_OPT__(FOR_EACH_NEXT PARENS (MACRO, __VA_ARGS__))
#define SELECT(FIRST, ...) FIRST
#define SELECT_SECOND(FIRST, ...) __VA_ARGS__
#define DISCARD_1(FIRST, ...) SELECT##__VA_OPT__(_SECOND)(FIRST, __VA_ARGS__)
#define REMOVE_PARENTHESES_IMPL(ARG, _, ...) __VA_OPT__(EVAL) ARG
#define REMOVE_PARENTHESES(ARG) EVAL_1(DEFER(REMOVE_PARENTHESES_IMPL)(ARG, CHECK_PARENTHESES ARG))
#define CHECK_PARENTHESES(...) _, __VA_ARGS__
#define MAKE_HELPER_STRUCT(COUNTER, ...) template<EVAL_1024(MAKE_HELPER_STRUCT_IMPL(COUNTER, __VA_ARGS__))
#define MEMBER_POINTER_CONCAT(_, ...) FOR_EACH_256(MEMBER_POINTER_CONCAT_ONCE, __VA_ARGS__)
#define MEMBER_POINTER_CONCAT_ONCE(ARG) auto EVAL_1_1(DEFER(DISCARD_1)(REMOVE_PARENTHESES(ARG))), EMPTY()
#define MAKE_HELPER_STRUCT_IMPL(COUNTER, ARG1, ...) EVAL_1_2(DEFER(MAKE_HELPER_STRUCT_IMPL_DISPATCH)(COUNTER, ARG1, (__VA_ARGS__), CHECK_PARENTHESES ARG1))
#define MAKE_HELPER_STRUCT_IMPL_DISPATCH(COUNTER, ARG1, ARGS, _, ...) MAKE_HELPER_STRUCT_IMPL_TASK##__VA_OPT__(_EXEC)(COUNTER, CONCAT(ARG1, EVAL ARGS), __VA_ARGS__) __VA_OPT__(MAKE_HELPER_STRUCT_NEXT PARENS (COUNTER, EVAL ARGS))
#define MAKE_HELPER_STRUCT_IMPL_TASK(COUNTER, FUNCTIONS, ...) void *> struct intrusive_function_helper_##COUNTER { FUNCTIONS };
#define MAKE_HELPER_STRUCT_IMPL_TASK_EXEC(_1, _2, ...) MEMBER_POINTER_CONCAT(__VA_ARGS__)
#define MAKE_HELPER_STRUCT_NEXT() MAKE_HELPER_STRUCT_IMPL
#define CLASS_CONCAT(CLASS, ...) EVAL_256(CLASS_CONCAT_IMPL(CLASS, __VA_ARGS__))
#define CLASS_CONCAT_IMPL(CLASS, ARG1, ...) &CLASS::EVAL(DEFER(SELECT)(REMOVE_PARENTHESES(ARG1))), __VA_OPT__(CLASS_CONCAT_NEXT PARENS (CLASS, __VA_ARGS__))
#define CLASS_CONCAT_NEXT() CLASS_CONCAT_IMPL
#define MAKE_TEMPLATE_INST(COUNTER, ...) template struct intrusive_function_helper_##COUNTER<EVAL_1024(MAKE_TEMPLATE_INST_IMPL(__VA_ARGS__)) nullptr>
#define MAKE_TEMPLATE_INST_IMPL(ARG1, ...) EVAL_1_1(DEFER(MAKE_TEMPLATE_INST_IMPL_DISPATCH)((__VA_ARGS__), CHECK_PARENTHESES ARG1))
#define MAKE_TEMPLATE_INST_IMPL_DISPATCH(ARGS, _, ...) MAKE_TEMPLATE_INST_IMPL_TASK##__VA_OPT__(_EXEC)(__VA_ARGS__) __VA_OPT__(MAKE_TEMPLATE_INST_NEXT PARENS ARGS)
#define MAKE_TEMPLATE_INST_IMPL_TASK(...)
#define MAKE_TEMPLATE_INST_IMPL_TASK_EXEC(...) CLASS_CONCAT(__VA_ARGS__)
#define MAKE_TEMPLATE_INST_NEXT() MAKE_TEMPLATE_INST_IMPL
#define DEFINE_INTRUSIVE_FUNCTIONS_IMPL(COUNTER, ...) MAKE_HELPER_STRUCT(COUNTER, __VA_ARGS__) MAKE_TEMPLATE_INST(COUNTER, __VA_ARGS__)
#define DEFINE_INTRUSIVE_FUNCTIONS(...) DEFINE_INTRUSIVE_FUNCTIONS_IMPL(__COUNTER__, __VA_ARGS__);
template<class T> T force_create() { char bytes[sizeof(T)]{}; return *reinterpret_cast<T *>(bytes); }
//=======================================================================================//
#include <iostream>
#include <tuple>
class Person {
private:
class BankAccount { int money; } bank_account;
int money;
std::string name;
std::string status;
Person() = delete;
};
DEFINE_INTRUSIVE_FUNCTIONS((Person, name, bank_account, money, status), (Person::BankAccount, (money, bank_money)),
friend Person force_create_person(auto ...args) {
auto p = force_create<Person>();
std::tie(p.*name, p.*status, p.*bank_account.*bank_money, p.*money) = std::make_tuple(args...);
return p;
}
friend void force_print(const Person &p) {
std::cout << p.*name
<< "\n status: " << p.*status
<< "\n bank_money: " << p.*bank_account.*bank_money
<< "\n money: " << p.*money
<< "\n";
}
friend void force_rob(Person &p) {
p.*status = "poor";
p.*bank_account.*bank_money = std::min(0, p.*bank_account.*bank_money);
p.*money = std::min(0, p.*money);
})
Person force_create_person(auto ...args);
void force_print(const Person &p);
void force_rob(Person &p);
int main() {
auto p = force_create_person("John", "rich", 999999, 4242);
force_print(p);
force_rob (p);
force_print(p); // John
// status: poor
// bank_money: 0
// money: 0
}