#pragma once #include #include #include #include // https://stackoverflow.com/a/11994395 modified to fit my needs #define FE_0(WHAT) #define FE_1(WHAT, extra_arg, X) WHAT(extra_arg, X) #define FE_2(WHAT, extra_arg, X, ...) WHAT(extra_arg, X)FE_1(WHAT, extra_arg, __VA_ARGS__) #define FE_3(WHAT, extra_arg, X, ...) WHAT(extra_arg, X)FE_2(WHAT, extra_arg, __VA_ARGS__) #define FE_4(WHAT, extra_arg, X, ...) WHAT(extra_arg, X)FE_3(WHAT, extra_arg, __VA_ARGS__) #define FE_5(WHAT, extra_arg, X, ...) WHAT(extra_arg, X)FE_4(WHAT, extra_arg, __VA_ARGS__) #define FE_6(WHAT, extra_arg, X, ...) WHAT(extra_arg, X)FE_5(WHAT, extra_arg, __VA_ARGS__) #define FE_7(WHAT, extra_arg, X, ...) WHAT(extra_arg, X)FE_6(WHAT, extra_arg, __VA_ARGS__) #define FE_8(WHAT, extra_arg, X, ...) WHAT(extra_arg, X)FE_7(WHAT, extra_arg, __VA_ARGS__) #define FE_9(WHAT, extra_arg, X, ...) WHAT(extra_arg, X)FE_8(WHAT, extra_arg, __VA_ARGS__) #define GET_MACRO(_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,NAME,...) NAME #define FOR_EACH(action,extra_arg,...) \ GET_MACRO(_0,__VA_ARGS__,FE_9,FE_8,FE_7,FE_6,FE_5,FE_4,FE_3,FE_2,FE_1,FE_0)(action,extra_arg,__VA_ARGS__) #define CONFIG(name, ...) \ struct name {\ __VA_ARGS__\ }; #define SECTION(name, ...) \ struct {\ __VA_ARGS__\ } name; #define UINT uintmax_t #define VAR_UINT(section, name) UINT name; #define VAR_UINT_D(section, name, default) UINT name = default; #define INT intmax_t #define VAR_INT(section, name) INT name; #define VAR_INT_D(section, name, default) INT name = default; #define STRING std::string #define VAR_STRING(section, name) STRING name; #define VAR_STRING_D(section, name, default) STRING name = default; #define BOOL bool #define VAR_BOOL(section, name) BOOL name; #define VAR_BOOL_D(section, name, default) BOOL name = default; #define FLOAT double #define VAR_FLOAT(section, name) FLOAT name; #define VAR_FLOAT_D(section, name, default) FLOAT name = default; #define COLOUR sf::Color #define VAR_COLOUR(section, name) COLOUR name; #define VAR_COLOUR_D(section, name, default) COLOUR name = default; #define VAR_LIST(section, name, type) std::vector name; #define VAR_LIST_SEP(section, name, type, sep) std::vector name; #define VAR_LIST_NUMBERED(section, name, type) std::vector name; #define ENUM_TO_STRING_CASE(name, e) case name::e: os << #e; #define ENUM_FROM_STRING(name, e) if (input == #e) en = name::e; #define ENUM(name, ...) \ enum class name {\ __VA_ARGS__\ };\ \ inline std::ostream &operator<<(std::ostream &os, const name &en) {\ switch (en) {\ FOR_EACH(ENUM_TO_STRING_CASE, name, __VA_ARGS__)\ }\ return os;\ }\ \ inline std::istream &operator>>(std::istream &is, name &en) {\ std::string input;\ is >> input;\ FOR_EACH(ENUM_FROM_STRING, name, __VA_ARGS__)\ return is;\ } #define VAR_ENUM(section, name, enum_type) enum_type name; #define VAR_ENUM_D(section, name, enum_type, default) enum_type name = enum_type::default; #define VAR_BITS(section, name, amount, offset) unsigned int name : amount; #define STRUCT_FIELD_TO_STRING(name, field) os << #field << ": " << str.field << "\n"; #define STRUCT_FROM_STRING(name, field) \ std::getline(is, input, ",");\ std::stringstream ss(input);\ ss >> str.field; #define STRUCT(name, ...) \ struct name {\ __VA_ARGS__\ };\ \ inline std::ostream &operator<<(std::ostream &os, const name &str) {\ os << #name << " {\n";\ FOR_EACH(STRUCT_FIELD_TO_STRING, name, __VA_ARGS__)\ os << "}\n";\ return os;\ }\ \ inline std::istream &operator>>(std::istream &is, name &str) {\ std::string input;\ FOR_EACH(STRUCT_FROM_STRING, name, __VA_ARGS__)\ return is;\ } #define VAR_STRUCT(section, name, struct_type) struct_type name; #define VAR_STRUCT_D(section, name, struct_type, default) struct_type name = default; #include #undef FE_0 #undef FE_1 #undef FE_2 #undef FE_3 #undef FE_4 #undef FE_5 #undef GET_MACRO #undef FOR_EACH #undef CONFIG #undef SECTION #undef UINT #undef VAR_UINT #undef VAR_UINT_D #undef INT #undef VAR_INT #undef VAR_INT_D #undef STRING #undef VAR_STRING #undef VAR_STRING_D #undef BOOL #undef VAR_BOOL #undef VAR_BOOL_D #undef FLOAT #undef VAR_FLOAT #undef VAR_FLOAT_D #undef COLOUR #undef VAR_COLOUR #undef VAR_COLOUR_D #undef ENUM_TO_STRING_CASE #undef ENUM_FROM_STRING #undef ENUM #undef VAR_ENUM #undef VAR_ENUM_D #undef VAR_BITS #undef STRUCT #undef VAR_STRUCT #undef VAR_STRUCT_D #undef VAR_LIST #undef VAR_LIST_SEP #undef VAR_LIST_NUMBERED