Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // map-macro: recursive macros (https://github.com/swansontec/map-macro)
- // (you can implement these yourself pretty easily)
- // ((so it's not particularly interesting))
- #include "map.h"
- // static casting from subclass to superclass
- // really?
- #define as .
- // used for pasting macro name and parentheses without ##
- // is needed to make the macro actually expand after
- #define FAKE_CAT2_(X, ...) X __VA_ARGS__
- #define FAKE_CAT2(...) FAKE_CAT2_(__VA_ARGS__)
- // token concatenation/2
- #define CAT2_(X, ...) X ## __VA_ARGS__
- #define CAT2(...) CAT2_(__VA_ARGS__)
- // token concatenation/3
- #define CAT3_(X, Y, ...) X ## Y ## __VA_ARGS__
- #define CAT3(...) CAT3_(__VA_ARGS__)
- // outer generation (top level) of method selectors
- // (this expands to normal class-named functions with class name argument)
- #define OUTER_METHOD_(...) __VA_ARGS__)
- #define OUTER_METHOD(Class, Method, Return, ...) \
- Return CAT3(Class, _, Method)(Class OUTER_METHOD_ __VA_ARGS__
- #define OUTER0_method(...) OUTER_METHOD
- #define OUTER1_method(...) __VA_ARGS__
- // outer generation of property selectors
- // (this expands to nothing)
- #define OUTER_PROPERTY(...)
- #define OUTER0_property(...) OUTER_PROPERTY
- #define OUTER1_property(...) __VA_ARGS__
- // selector for outer generation
- // first gets selector macro args by forming OUTER1_method or OUTER1_property
- // then wraps class name with args in parens and forms OUTER0_method/property
- // FAKE_CAT2 is needed to make this actually expand
- #define CLASS0_(Selector, ...) FAKE_CAT2(OUTER0_ ## Selector, (__VA_ARGS__, OUTER1_ ## Selector))
- // implements inheritance
- // simply makes fields with the same name as the class (Foo Foo;)
- #define EXTENDS_(...) __VA_ARGS__ __VA_ARGS__;
- #define CLASS1_(...) MAP(EXTENDS_, __VA_ARGS__)
- // inner generation (inside struct) of method selectors
- // (this expands to nothing)
- #define INNER_method(...)
- // inner generation of property selectors
- // expands to simple struct fields (Foo foo;)
- #define INNER_property(Property, ...) __VA_ARGS__ Property;
- // selector for inner generation
- // has no need for class name, so simpler than outer (only pasting)
- #define CLASS2_(...) INNER_ ## __VA_ARGS__
- // actual class definition with name, inheritance list, and selectors
- // 1. predeclares class for inner usage
- // 2. defines the class with the inheritance list expanded by CLASS1_...
- // 3. ...and the fields expanded by CLASS2_
- // 4. defines methods as free functions with CLASS0_
- // (can be easily extended to predeclare all functions so order doesn't matter)
- // ((can be easily extended to have actual vtables (maybe "virtual" selector?)))
- #define class(Class, EXTENDS, ...) \
- typedef struct Class Class; \
- struct Class { CLASS1_ EXTENDS MAP(CLASS2_, __VA_ARGS__) }; \
- MAP_UD(CLASS0_, Class, __VA_ARGS__);
- // implements dynamic casting from superclass to subclass
- // basically glorified container_of macro
- // but staged to have type list be separate from parameters
- #define DYNAMIC_CAST_(...) __VA_ARGS__)))
- #define dynamic_cast(From, To) \
- ((To *)(-offsetof(To, From) + (char *)(DYNAMIC_CAST_
Advertisement