Go to the documentation of this file.
22 #include <farm_pp/preprocessor/comparison/equal.hpp>
23 #include <farm_pp/preprocessor/control/if.hpp>
24 #include <farm_pp/preprocessor/punctuation/remove_parens.hpp>
25 #include <farm_pp/preprocessor/seq/for_each.hpp>
26 #include <farm_pp/preprocessor/seq/for_each_i.hpp>
27 #include <farm_pp/preprocessor/seq/pop_front.hpp>
28 #include <farm_pp/preprocessor/stringize.hpp>
29 #include <farm_pp/preprocessor/tuple/elem.hpp>
30 #include <farm_pp/preprocessor/tuple/size.hpp>
31 #include <farm_pp/preprocessor/tuple/to_seq.hpp>
35 #include <string_view>
39 #define FARM_ENUM_DETAILS_OP_MAKE_TUPLE(dummy1, dummy2, ENUM) \
40 ((FARM_PP_REMOVE_PARENS(ENUM)))
44 #define FARM_ENUM_DETAILS_TO_SEQ_OF_TUPLES(...) \
45 FARM_PP_SEQ_FOR_EACH( \
46 FARM_ENUM_DETAILS_OP_MAKE_TUPLE, _, FARM_PP_TUPLE_TO_SEQ(__VA_ARGS__))
53 #define FARM_ENUM_DETAILS_GET_INT_TYPE(...) \
55 FARM_PP_EQUAL(FARM_PP_TUPLE_SIZE((__VA_ARGS__)), 2), \
56 FARM_PP_TUPLE_ELEM(0, (__VA_ARGS__)), \
64 #define FARM_ENUM_DETAILS_GET_VARS(...) \
65 FARM_PP_REMOVE_PARENS(FARM_PP_IF( \
66 FARM_PP_EQUAL(FARM_PP_TUPLE_SIZE((__VA_ARGS__)), 2), \
67 (FARM_PP_TUPLE_ELEM(1, (__VA_ARGS__))), \
72 #define FARM_ENUM_DETAILS_OP_VALUE_WITH_INIT(PAIR) \
74 FARM_PP_EQUAL(FARM_PP_TUPLE_SIZE(PAIR), 1), \
75 FARM_PP_TUPLE_ELEM(0, PAIR), \
76 FARM_PP_TUPLE_ELEM(0, PAIR) = FARM_PP_TUPLE_ELEM(1, PAIR))
80 #define FARM_ENUM_DETAILS_ENUM_NS_OP(NAME, PAIR) \
81 NAME##Impl::FARM_PP_TUPLE_ELEM(0, PAIR)
85 #define FARM_ENUM_DETAILS_OP_COMMA_VALUE(dummy1, dummy2, PAIR) \
86 , FARM_ENUM_DETAILS_OP_VALUE_WITH_INIT(PAIR)
90 #define FARM_ENUM_DETAILS_NS_OP_COMMA(dummy1, NAME, PAIR) \
91 , FARM_ENUM_DETAILS_ENUM_NS_OP(NAME, PAIR)
95 #define FARM_ENUM_DETAILS_CSV(...) \
96 FARM_ENUM_DETAILS_OP_VALUE_WITH_INIT( \
97 FARM_PP_SEQ_ELEM(0, FARM_ENUM_DETAILS_TO_SEQ_OF_TUPLES(__VA_ARGS__))) \
98 FARM_PP_SEQ_FOR_EACH( \
99 FARM_ENUM_DETAILS_OP_COMMA_VALUE, \
101 FARM_PP_SEQ_POP_FRONT(FARM_ENUM_DETAILS_TO_SEQ_OF_TUPLES(__VA_ARGS__)))
105 #define FARM_ENUM_NS_ENUM_CSV(NAME, ...) \
106 FARM_ENUM_DETAILS_ENUM_NS_OP( \
108 FARM_PP_SEQ_ELEM(0, FARM_ENUM_DETAILS_TO_SEQ_OF_TUPLES(__VA_ARGS__))) \
109 FARM_PP_SEQ_FOR_EACH( \
110 FARM_ENUM_DETAILS_NS_OP_COMMA, \
112 FARM_PP_SEQ_POP_FRONT(FARM_ENUM_DETAILS_TO_SEQ_OF_TUPLES(__VA_ARGS__)))
118 #define FARM_ENUM_DETAILS_OP_TO_STRING_CASE(dummy1, TYPE, PAIR) \
119 case TYPE::FARM_PP_TUPLE_ELEM(0, PAIR): { \
120 return FARM_PP_STRINGIZE(FARM_PP_TUPLE_ELEM(0, PAIR)); \
128 #define FARM_ENUM_DETAILS_OP_TO_PRETTY_CASE(dummy, types, PAIR) \
129 case FARM_PP_TUPLE_ELEM(0, types)::FARM_PP_TUPLE_ELEM(0, PAIR): { \
130 return FARM_PP_STRINGIZE(FARM_PP_TUPLE_ELEM(0, PAIR)) + \
131 std::string(" (=") + \
132 std::to_string(FARM_PP_TUPLE_ELEM(1, types)(value)) + \
141 #define FARM_ENUM_DETAILS_OP_SET_VALUE_CASES(dummy1, TYPE, PAIR) \
142 if (str == FARM_PP_STRINGIZE(FARM_PP_TUPLE_ELEM(0, PAIR))) { \
143 value = TYPE::FARM_PP_TUPLE_ELEM(0, PAIR); \
148 #define FARM_ENUM_DETAILS_OP_COMMA_STRING(dummy1, dummy2, PAIR) \
149 , FARM_PP_STRINGIZE(FARM_PP_TUPLE_ELEM(0, PAIR))
153 #define FARM_ENUM_DETAILS_COMMA_SEP_STRINGS(...) \
154 FARM_PP_STRINGIZE(FARM_PP_TUPLE_ELEM( \
156 FARM_PP_SEQ_ELEM(0, FARM_ENUM_DETAILS_TO_SEQ_OF_TUPLES(__VA_ARGS__)))) \
157 FARM_PP_SEQ_FOR_EACH( \
158 FARM_ENUM_DETAILS_OP_COMMA_STRING, \
160 FARM_PP_SEQ_POP_FRONT(FARM_ENUM_DETAILS_TO_SEQ_OF_TUPLES(__VA_ARGS__)))
163 #define FARM_ENUM_DETAILS_OP_COMMA_VALUE_STRING(dummy1, dummy2, PAIR) \
164 ", " FARM_PP_STRINGIZE(FARM_PP_TUPLE_ELEM(0, PAIR))
167 #define FARM_ENUM_DETAILS_OP_POSITION_ICASE(dummy, TYPE, I, PAIR) \
168 case TYPE::FARM_PP_TUPLE_ELEM(0, PAIR): { \
174 #define FARM_ENUM_DETAILS_CSV_STRING(...) \
175 FARM_PP_STRINGIZE(FARM_PP_TUPLE_ELEM( \
177 FARM_PP_SEQ_ELEM(0, FARM_ENUM_DETAILS_TO_SEQ_OF_TUPLES(__VA_ARGS__)))) \
178 FARM_PP_SEQ_FOR_EACH( \
179 FARM_ENUM_DETAILS_OP_COMMA_VALUE_STRING, \
181 FARM_PP_SEQ_POP_FRONT(FARM_ENUM_DETAILS_TO_SEQ_OF_TUPLES(__VA_ARGS__)))
184 #define FARM_ENUM_DETAILS_OP_INTS(dummy, TYPES, PAIR) \
185 , FARM_PP_TUPLE_ELEM( \
186 1, TYPES)(FARM_PP_TUPLE_ELEM(0, TYPES)::FARM_PP_TUPLE_ELEM(0, PAIR))
192 #define FARM_ENUM_DETAILS_COMMA_SEP_INTS(TYPE, INT_TYPE, ...) \
193 INT_TYPE(TYPE::FARM_PP_TUPLE_ELEM( \
195 FARM_PP_SEQ_ELEM(0, FARM_ENUM_DETAILS_TO_SEQ_OF_TUPLES(__VA_ARGS__)))) \
196 FARM_PP_SEQ_FOR_EACH( \
197 FARM_ENUM_DETAILS_OP_INTS, \
199 FARM_PP_SEQ_POP_FRONT(FARM_ENUM_DETAILS_TO_SEQ_OF_TUPLES(__VA_ARGS__)))
201 #define FARM_ENUM_DEF_IMPL(NAME, ...) \
202 namespace enum_wrapper_ { \
203 enum class NAME##Impl : FARM_ENUM_DETAILS_GET_INT_TYPE(__VA_ARGS__){ \
204 FARM_ENUM_DETAILS_CSV(FARM_ENUM_DETAILS_GET_VARS(__VA_ARGS__))}; \
206 [[maybe_unused]] inline auto toString(NAME##Impl value) -> std::string { \
208 FARM_PP_SEQ_FOR_EACH( \
209 FARM_ENUM_DETAILS_OP_TO_STRING_CASE, \
211 FARM_ENUM_DETAILS_TO_SEQ_OF_TUPLES( \
212 FARM_ENUM_DETAILS_GET_VARS(__VA_ARGS__))) \
217 [[maybe_unused]] inline auto constexpr toStringView(NAME##Impl value) \
218 -> std::string_view { \
220 FARM_PP_SEQ_FOR_EACH( \
221 FARM_ENUM_DETAILS_OP_TO_STRING_CASE, \
223 FARM_ENUM_DETAILS_TO_SEQ_OF_TUPLES( \
224 FARM_ENUM_DETAILS_GET_VARS(__VA_ARGS__))) \
229 [[maybe_unused]] inline auto toPretty(NAME##Impl value) -> std::string { \
231 FARM_PP_SEQ_FOR_EACH( \
232 FARM_ENUM_DETAILS_OP_TO_PRETTY_CASE, \
233 (NAME##Impl, FARM_ENUM_DETAILS_GET_INT_TYPE(__VA_ARGS__)), \
234 FARM_ENUM_DETAILS_TO_SEQ_OF_TUPLES( \
235 FARM_ENUM_DETAILS_GET_VARS(__VA_ARGS__))) \
240 [[maybe_unused]] [[nodiscard]] inline auto trySetFromString( \
241 NAME##Impl &value, std::string const &str) -> bool { \
242 FARM_PP_SEQ_FOR_EACH( \
243 FARM_ENUM_DETAILS_OP_SET_VALUE_CASES, \
245 FARM_ENUM_DETAILS_TO_SEQ_OF_TUPLES( \
246 FARM_ENUM_DETAILS_GET_VARS(__VA_ARGS__))) \
250 [[maybe_unused]] [[nodiscard]] auto constexpr getCount(NAME##Impl) \
252 return FARM_PP_TUPLE_SIZE(FARM_ENUM_DETAILS_GET_VARS(__VA_ARGS__)); \
255 [[maybe_unused]] [[nodiscard]] inline auto getStrings(NAME##Impl) \
258 FARM_PP_TUPLE_SIZE(FARM_ENUM_DETAILS_GET_VARS(__VA_ARGS__))> { \
259 return {FARM_ENUM_DETAILS_COMMA_SEP_STRINGS( \
260 FARM_ENUM_DETAILS_GET_VARS(__VA_ARGS__))}; \
263 [[maybe_unused]] [[nodiscard]] inline auto getStringOfNames(NAME##Impl) \
264 -> std::string_view { \
265 return FARM_ENUM_DETAILS_CSV_STRING( \
266 FARM_ENUM_DETAILS_GET_VARS(__VA_ARGS__)); \
269 [[maybe_unused]] [[nodiscard]] auto constexpr getValues(NAME##Impl) \
271 FARM_ENUM_DETAILS_GET_INT_TYPE(__VA_ARGS__), \
272 FARM_PP_TUPLE_SIZE(FARM_ENUM_DETAILS_GET_VARS(__VA_ARGS__))> { \
273 return {FARM_ENUM_DETAILS_COMMA_SEP_INTS( \
275 FARM_ENUM_DETAILS_GET_INT_TYPE(__VA_ARGS__), \
276 FARM_ENUM_DETAILS_GET_VARS(__VA_ARGS__))}; \
279 [[maybe_unused]] [[nodiscard]] auto constexpr getAll(NAME##Impl) \
282 FARM_PP_TUPLE_SIZE(FARM_ENUM_DETAILS_GET_VARS(__VA_ARGS__))> { \
285 FARM_ENUM_NS_ENUM_CSV(NAME, FARM_ENUM_DETAILS_GET_VARS(__VA_ARGS__))}; \
288 [[maybe_unused]] [[nodiscard]] auto constexpr getPosition(NAME##Impl value) \
291 FARM_PP_SEQ_FOR_EACH_I( \
292 FARM_ENUM_DETAILS_OP_POSITION_ICASE, \
294 FARM_ENUM_DETAILS_TO_SEQ_OF_TUPLES( \
295 FARM_ENUM_DETAILS_GET_VARS(__VA_ARGS__))) \
300 [[maybe_unused]] [[nodiscard]] inline auto getTypeName(NAME##Impl) \
301 -> std::string_view { \
302 return FARM_PP_STRINGIZE(NAME); \
304 } // namespace enum_wrapper_