- 001
- 002
- 003
- 004
- 005
- 006
- 007
- 008
- 009
- 010
- 011
- 012
- 013
- 014
- 015
- 016
- 017
- 018
- 019
- 020
- 021
- 022
- 023
- 024
- 025
- 026
- 027
- 028
- 029
- 030
- 031
- 032
- 033
- 034
- 035
- 036
- 037
- 038
- 039
- 040
- 041
- 042
- 043
- 044
- 045
- 046
- 047
- 048
- 049
- 050
- 051
- 052
- 053
- 054
- 055
- 056
- 057
- 058
- 059
- 060
- 061
- 062
- 063
- 064
- 065
- 066
- 067
- 068
- 069
- 070
- 071
- 072
- 073
- 074
- 075
- 076
- 077
- 078
- 079
- 080
- 081
- 082
- 083
- 084
- 085
- 086
- 087
- 088
- 089
- 090
- 091
- 092
- 093
- 094
- 095
- 096
- 097
- 098
- 099
- 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
}