#pragma once #ifndef PP_DEBUG #include #include #include #endif #include #include #include #define CONFIG(name, ...) \ struct name {\ __VA_ARGS__\ }; #define SECTION(name, type_name, ...) \ struct type_name {\ __VA_ARGS__\ } name; #define SECTION_LIST(name, type) std::vector name; #define VAR_UINT(section, name) uint name; #define VAR_UINT_P(section, name, prefix) VAR_UINT(section, name) #define VAR_UINT_D(section, name, default) uint name = default; #define VAR_INT(section, name) int name; #define VAR_INT_P(section, name, prefix) VAR_INT(section, name) #define VAR_INT_D(section, name, default) int name = default; #define VAR_STRING(section, name) std::string name; #define VAR_STRING_P(section, name, prefix) VAR_STRING(section, name) #define VAR_STRING_D(section, name, default) std::string name = default; #define VAR_BOOL(section, name) bool name; #define VAR_BOOL_P(section, name, prefix) VAR_BOOL(section, name) #define VAR_BOOL_D(section, name, default) bool name = default; #define VAR_FLOAT(section, name) double name; #define VAR_FLOAT_P(section, name, prefix) VAR_FLOAT(section, name) #define VAR_FLOAT_D(section, name, default) double name = default; #define VAR_COLOUR(section, name) sf::Color name; #define VAR_COLOUR_P(section, name, prefix) VAR_COLOUR(section, name) #define VAR_COLOUR_D(section, name, default) sf::Color 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_SEP_P(section, name, type, sep, prefix) std::vector name; #define VAR_LIST_NUMBERED(section, name, type) std::vector name; #define ENUM(name, ...) \ enum class name {\ __VA_ARGS__\ };\ ENUM_STREAM_OPS(name, __VA_ARGS__) #define VAR_ENUM(section, name, enum_type) enum_type name; #define VAR_ENUM_P(section, name, prefix) VAR_ENUM(section, name) #define VAR_ENUM_D(section, name, enum_type, default) enum_type name = enum_type::default; #define ENUM_TO_STRING_CASE(name, e) case name::e: os << #e; break; #define ENUM_FROM_STRING(name, e) if (input == #e) { en = name::e; hasBeenSet = true; } #define ENUM_STREAM_OPS(name, ...) \ 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;\ if (isInt(input)) {\ try {\ int inputNum = std::stoul(input);\ if (inputNum >= ARG_COUNT(__VA_ARGS__)) {\ /* TODO this and the comment below give me -Wmaybe-uninitialized * which I would say is the expected outcome in this case * but what do I know; find a way to silence the warning * while still retaining this behaviour */\ is.setstate(std::ios_base::failbit);\ } else {\ en = static_cast(inputNum);\ }\ } catch (std::invalid_argument const&) {\ /* the comment below */\ is.setstate(std::ios_base::failbit);\ }\ } else {\ toUpper(input);\ bool hasBeenSet = false;\ FOR_EACH(ENUM_FROM_STRING, name, __VA_ARGS__)\ if (!hasBeenSet) {\ is.setstate(std::ios_base::failbit);\ }\ }\ return is;\ } #define STRUCT(name, ...) \ struct name {\ __VA_ARGS__\ }; #define VAR_STRUCT(section, name, struct_type) struct_type name; #define VAR_STRUCT_P(section, name, prefix) VAR_STRUCT(section, name) #define VAR_STRUCT_D(section, name, struct_type, default) struct_type name = default; #define STRUCT_FIELD_TO_STRING(name, field) os << " " << #field << ": " << str.field << "\n"; #define STRUCT_FROM_STRING(name, field) \ std::getline(is, input, ',');\ ss = std::stringstream(input);\ ss >> str.field; #define STRUCT_INPUT_STREAM_OP(name, ...) \ inline std::istream &operator>>(std::istream &is, name &str) {\ std::string input;\ std::stringstream ss;\ FOR_EACH(STRUCT_FROM_STRING, name, __VA_ARGS__)\ return is;\ } #define STRUCT_OUTPUT_STREAM_OP(name, ...) \ inline std::ostream &operator<<(std::ostream &os, const name &str) {\ os << #name << " {\n";\ FOR_EACH(STRUCT_FIELD_TO_STRING, name, __VA_ARGS__)\ os << "}";\ return os;\ } #define STRUCT_STREAM_OPS(name, ...) \ STRUCT_INPUT_STREAM_OP(name, __VA_ARGS__) \ STRUCT_OUTPUT_STREAM_OP(name, __VA_ARGS__) #include #undef CONFIG #undef SECTION #undef SECTION_LIST #undef VAR_UINT #undef VAR_UINT_P #undef VAR_UINT_D #undef VAR_INT #undef VAR_INT_P #undef VAR_INT_D #undef VAR_STRING #undef VAR_STRING_P #undef VAR_STRING_D #undef VAR_BOOL #undef VAR_BOOL_P #undef VAR_BOOL_D #undef VAR_FLOAT #undef VAR_FLOAT_P #undef VAR_FLOAT_D #undef VAR_COLOUR #undef VAR_COLOUR_P #undef VAR_COLOUR_D #undef ENUM #undef VAR_ENUM #undef VAR_ENUM_P #undef VAR_ENUM_D #undef ENUM_TO_STRING_CASE #undef ENUM_FROM_STRING #undef ENUM_STREAM_OPS #undef STRUCT #undef VAR_STRUCT #undef VAR_STRUCT_P #undef VAR_STRUCT_D #undef STRUCT_FIELD_TO_STRING #undef STRUCT_FROM_STRING #undef STRUCT_INPUT_STREAM_OP #undef STRUCT_OUTPUT_STREAM_OP #undef STRUCT_STREAM_OPS #undef VAR_LIST #undef VAR_LIST_SEP #undef VAR_LIST_SEP_P #undef VAR_LIST_NUMBERED