Created
March 18, 2015 22:17
-
-
Save andik/da76a26b8056b56700ee to your computer and use it in GitHub Desktop.
C++ PP List and PP Typelists
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define List(o) \ | |
o(1,2) \ | |
o(2,3) \ | |
#define MAP_CALL_FN_PARENS(...) (__VA_ARGS__); | |
#define MAP_CALL_FN(fn) fn MAP_CALL_FN_PARENS | |
#define MAP(list, fn, ...) list(MAP_CALL_FN(fn)) | |
#define elem(...) element __VA_ARGS__ | |
#define NONE | |
List(elem) | |
MAP(List, myfn) | |
// Works due to | |
List(xy elem) | |
// is xy elem(1,2) xy elem(3,4) | |
#define CASE_RETURN(a,b) case a: return b; | |
#define LIST_AS_ARRAY(...) {__VA_ARGS__}, | |
#define Typelist(__firs, __elem, __last) \ | |
__firs(int, mya, 0) \ | |
__elem(int, myb, 1) \ | |
__elem(int, myc, 2) \ | |
__elem(int, myd, 3) \ | |
__last(int, mye, 4) \ | |
List(CASE_RETURN) | |
myArray = { | |
List(LIST_AS_ARRAY) | |
}; | |
#define PROTO_FOR_TYPELIST_EL(type, name, value) type name, | |
#define PROTO_FOR_TYPELIST_E(type, name, value) type name | |
#define PROTO_FOR_TYPELIST(RetType, name, Typelist) \ | |
RetType name(Typelist(PROTO_FOR_TYPELIST_EL, PROTO_FOR_TYPELIST_EL, PROTO_FOR_TYPELIST_E)) | |
#define CALL_WITH_TYPELIST_EL(type, name, value) name, | |
#define CALL_WITH_TYPELIST_E(type, name, value) name | |
#define CALL_WITH_TYPELIST(name, Typelist) \ | |
name(Typelist(CALL_WITH_TYPELIST_EL, CALL_WITH_TYPELIST_EL, CALL_WITH_TYPELIST_E)) | |
#define INIT_FOR_TYPELIST_A(t, name, val) : name(val) | |
#define INIT_FOR_TYPELIST_EL(t, name, val) , name(val) | |
#define INIT_FOR_TYPELIST(Typelist) \ | |
Typelist(INIT_FOR_TYPELIST_A, INIT_FOR_TYPELIST_EL, INIT_FOR_TYPELIST_EL) | |
#define DECL_FOR_TYPELIST_EL(t, name, val) t name; | |
#define DECL_FOR_TYPELIST(Typelist) \ | |
Typelist(DECL_FOR_TYPELIST_EL, DECL_FOR_TYPELIST_EL, DECL_FOR_TYPELIST_EL) | |
#define LAMBDA_INIT_FOR_TYPELIST_A(t, name, val) : name(arg_##name) | |
#define LAMBDA_INIT_FOR_TYPELIST_EL(t, name, val) , name(arg_##name) | |
#define LAMBDA_INIT_FOR_TYPELIST(Typelist) \ | |
Typelist(LAMBDA_INIT_FOR_TYPELIST_A, LAMBDA_INIT_FOR_TYPELIST_EL, LAMBDA_INIT_FOR_TYPELIST_EL) | |
#define LAMBDA_CONPROTO_FOR_TYPELIST_EL(type, name, value) type arg_##name, | |
#define LAMBDA_CONPROTO_FOR_TYPELIST_E(type, name, value) type arg_##name | |
#define LAMBDA_CONPROTO_FOR_TYPELIST(RetType, name, Typelist) \ | |
RetType name(Typelist(LAMBDA_CONPROTO_FOR_TYPELIST_EL, LAMBDA_CONPROTO_FOR_TYPELIST_EL, LAMBDA_CONPROTO_FOR_TYPELIST_E)) | |
#define LAMBDA_FOR_TYPELIST(RetType, name, Typelist, code, ...) \ | |
class name##Class { \ | |
public: \ | |
LAMBDA_CONPROTO_FOR_TYPELIST(NONE, name##Class, Typelist) \ | |
LAMBDA_INIT_FOR_TYPELIST(Typelist) {} \ | |
\ | |
RetType operator()(__VA_ARGS__) { code } \ | |
private: \ | |
DECL_FOR_TYPELIST(Typelist) \ | |
}; \ | |
CALL_WITH_TYPELIST(name##Class, Typelist); \ | |
PROTO_FOR_TYPELIST(int, myfun, Typelist) | |
INIT_FOR_TYPELIST(Typelist) | |
LAMBDA_FOR_TYPELIST(int, mylambda, Typelist, { return 1 +2 }) | |
// Practical Lambda | |
#define capture(A,O,E) \ | |
A(int, a, 0) \ | |
E(int, b, 0) \ | |
LAMBDA_FOR_TYPELIST(int, aTestLambda, capture, { return a+b+c }, int c) | |
// anonymous function | |
#define ANON(name, code) \ | |
class name##Class { \ | |
public: \ | |
RetType operator()(__VA_ARGS__) { code } \ | |
}; \ | |
name##Class name; \ | |
ANON(anonymous, {return 3+4;}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment