FlatImage
A configurable Linux containerization system
Loading...
Searching...
No Matches
enum.hpp
Go to the documentation of this file.
1
8
9
#pragma once
10
#include <cstdlib>
11
#include <expected>
12
#include <print>
13
14
// Get size of __VA_ARGS__
15
#define VA_SIZE(...) VA_SIZE_(__VA_ARGS__,VA_SIZE_RSEQ())
16
#define VA_SIZE_(...) VA_SIZE_SEQ(__VA_ARGS__)
17
#define VA_SIZE_SEQ( \
18
_1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \
19
_11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \
20
_21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \
21
_31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \
22
_41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \
23
_51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \
24
_61,_62,_63,N,...) N
25
#define VA_SIZE_RSEQ() \
26
63,62,61,60, \
27
59,58,57,56,55,54,53,52,51,50, \
28
49,48,47,46,45,44,43,42,41,40, \
29
39,38,37,36,35,34,33,32,31,30, \
30
29,28,27,26,25,24,23,22,21,20, \
31
19,18,17,16,15,14,13,12,11,10, \
32
9,8,7,6,5,4,3,2,1,0
33
34
// Pop front of __VA_ARGS__
35
#define VA_DROP(x,...) __VA_ARGS__
36
37
// Create a case statement for enum to string
38
#define ENUM_TO_STRING_EXPR(NAME,value) case enum_t::value: return #value;
39
#define ENUM_CASE_TO_STRING_0(NAME,x) ENUM_TO_STRING_EXPR(NAME,x)
40
#define ENUM_CASE_TO_STRING_1(NAME,x,...) ENUM_TO_STRING_EXPR(NAME,x) ENUM_CASE_TO_STRING_0(NAME,__VA_ARGS__)
41
#define ENUM_CASE_TO_STRING_2(NAME,x,...) ENUM_TO_STRING_EXPR(NAME,x) ENUM_CASE_TO_STRING_1(NAME,__VA_ARGS__)
42
#define ENUM_CASE_TO_STRING_3(NAME,x,...) ENUM_TO_STRING_EXPR(NAME,x) ENUM_CASE_TO_STRING_2(NAME,__VA_ARGS__)
43
#define ENUM_CASE_TO_STRING_4(NAME,x,...) ENUM_TO_STRING_EXPR(NAME,x) ENUM_CASE_TO_STRING_3(NAME,__VA_ARGS__)
44
#define ENUM_CASE_TO_STRING_5(NAME,x,...) ENUM_TO_STRING_EXPR(NAME,x) ENUM_CASE_TO_STRING_4(NAME,__VA_ARGS__)
45
#define ENUM_CASE_TO_STRING_6(NAME,x,...) ENUM_TO_STRING_EXPR(NAME,x) ENUM_CASE_TO_STRING_5(NAME,__VA_ARGS__)
46
#define ENUM_CASE_TO_STRING_7(NAME,x,...) ENUM_TO_STRING_EXPR(NAME,x) ENUM_CASE_TO_STRING_6(NAME,__VA_ARGS__)
47
#define ENUM_CASE_TO_STRING_8(NAME,x,...) ENUM_TO_STRING_EXPR(NAME,x) ENUM_CASE_TO_STRING_7(NAME,__VA_ARGS__)
48
#define ENUM_CASE_TO_STRING_9(NAME,x,...) ENUM_TO_STRING_EXPR(NAME,x) ENUM_CASE_TO_STRING_8(NAME,__VA_ARGS__)
49
#define ENUM_CASE_TO_STRING_10(NAME,x,...) ENUM_TO_STRING_EXPR(NAME,x) ENUM_CASE_TO_STRING_9(NAME,__VA_ARGS__)
50
#define ENUM_CASE_TO_STRING_11(NAME,x,...) ENUM_TO_STRING_EXPR(NAME,x) ENUM_CASE_TO_STRING_10(NAME,__VA_ARGS__)
51
#define ENUM_CASE_TO_STRING_12(NAME,x,...) ENUM_TO_STRING_EXPR(NAME,x) ENUM_CASE_TO_STRING_11(NAME,__VA_ARGS__)
52
#define ENUM_CASE_TO_STRING_13(NAME,x,...) ENUM_TO_STRING_EXPR(NAME,x) ENUM_CASE_TO_STRING_12(NAME,__VA_ARGS__)
53
#define ENUM_CASE_TO_STRING_14(NAME,x,...) ENUM_TO_STRING_EXPR(NAME,x) ENUM_CASE_TO_STRING_13(NAME,__VA_ARGS__)
54
#define ENUM_CASE_TO_STRING_15(NAME,x,...) ENUM_TO_STRING_EXPR(NAME,x) ENUM_CASE_TO_STRING_14(NAME,__VA_ARGS__)
55
#define ENUM_CASE_TO_STRING_16(NAME,x,...) ENUM_TO_STRING_EXPR(NAME,x) ENUM_CASE_TO_STRING_15(NAME,__VA_ARGS__)
56
#define ENUM_CASE_TO_STRING_17(NAME,x,...) ENUM_TO_STRING_EXPR(NAME,x) ENUM_CASE_TO_STRING_16(NAME,__VA_ARGS__)
57
#define ENUM_CASE_TO_STRING_18(NAME,x,...) ENUM_TO_STRING_EXPR(NAME,x) ENUM_CASE_TO_STRING_17(NAME,__VA_ARGS__)
58
#define ENUM_CASE_TO_STRING_19(NAME,x,...) ENUM_TO_STRING_EXPR(NAME,x) ENUM_CASE_TO_STRING_18(NAME,__VA_ARGS__)
59
#define ENUM_CASE_TO_STRING_20(NAME,x,...) ENUM_TO_STRING_EXPR(NAME,x) ENUM_CASE_TO_STRING_19(NAME,__VA_ARGS__)
60
#define ENUM_CASE_TO_STRING_IMPL(i,NAME,...) ENUM_CASE_TO_STRING_##i(NAME,__VA_ARGS__)
61
#define ENUM_CASE_TO_STRING(i,NAME,...) ENUM_CASE_TO_STRING_IMPL(i,NAME,__VA_ARGS__)
62
63
// Create a case statement for string to enum
64
#define ENUM_FROM_STRING_EXPR(NAME,value) if ( str_enum == #value ) { return NAME(value); }
65
#define ENUM_CASE_FROM_STRING_0(NAME,x) ENUM_FROM_STRING_EXPR(NAME,x)
66
#define ENUM_CASE_FROM_STRING_1(NAME,x,...) ENUM_FROM_STRING_EXPR(NAME,x) ENUM_CASE_FROM_STRING_0(NAME,__VA_ARGS__)
67
#define ENUM_CASE_FROM_STRING_2(NAME,x,...) ENUM_FROM_STRING_EXPR(NAME,x) ENUM_CASE_FROM_STRING_1(NAME,__VA_ARGS__)
68
#define ENUM_CASE_FROM_STRING_3(NAME,x,...) ENUM_FROM_STRING_EXPR(NAME,x) ENUM_CASE_FROM_STRING_2(NAME,__VA_ARGS__)
69
#define ENUM_CASE_FROM_STRING_4(NAME,x,...) ENUM_FROM_STRING_EXPR(NAME,x) ENUM_CASE_FROM_STRING_3(NAME,__VA_ARGS__)
70
#define ENUM_CASE_FROM_STRING_5(NAME,x,...) ENUM_FROM_STRING_EXPR(NAME,x) ENUM_CASE_FROM_STRING_4(NAME,__VA_ARGS__)
71
#define ENUM_CASE_FROM_STRING_6(NAME,x,...) ENUM_FROM_STRING_EXPR(NAME,x) ENUM_CASE_FROM_STRING_5(NAME,__VA_ARGS__)
72
#define ENUM_CASE_FROM_STRING_7(NAME,x,...) ENUM_FROM_STRING_EXPR(NAME,x) ENUM_CASE_FROM_STRING_6(NAME,__VA_ARGS__)
73
#define ENUM_CASE_FROM_STRING_8(NAME,x,...) ENUM_FROM_STRING_EXPR(NAME,x) ENUM_CASE_FROM_STRING_7(NAME,__VA_ARGS__)
74
#define ENUM_CASE_FROM_STRING_9(NAME,x,...) ENUM_FROM_STRING_EXPR(NAME,x) ENUM_CASE_FROM_STRING_8(NAME,__VA_ARGS__)
75
#define ENUM_CASE_FROM_STRING_10(NAME,x,...) ENUM_FROM_STRING_EXPR(NAME,x) ENUM_CASE_FROM_STRING_9(NAME,__VA_ARGS__)
76
#define ENUM_CASE_FROM_STRING_11(NAME,x,...) ENUM_FROM_STRING_EXPR(NAME,x) ENUM_CASE_FROM_STRING_10(NAME,__VA_ARGS__)
77
#define ENUM_CASE_FROM_STRING_12(NAME,x,...) ENUM_FROM_STRING_EXPR(NAME,x) ENUM_CASE_FROM_STRING_11(NAME,__VA_ARGS__)
78
#define ENUM_CASE_FROM_STRING_13(NAME,x,...) ENUM_FROM_STRING_EXPR(NAME,x) ENUM_CASE_FROM_STRING_12(NAME,__VA_ARGS__)
79
#define ENUM_CASE_FROM_STRING_14(NAME,x,...) ENUM_FROM_STRING_EXPR(NAME,x) ENUM_CASE_FROM_STRING_13(NAME,__VA_ARGS__)
80
#define ENUM_CASE_FROM_STRING_15(NAME,x,...) ENUM_FROM_STRING_EXPR(NAME,x) ENUM_CASE_FROM_STRING_14(NAME,__VA_ARGS__)
81
#define ENUM_CASE_FROM_STRING_16(NAME,x,...) ENUM_FROM_STRING_EXPR(NAME,x) ENUM_CASE_FROM_STRING_15(NAME,__VA_ARGS__)
82
#define ENUM_CASE_FROM_STRING_17(NAME,x,...) ENUM_FROM_STRING_EXPR(NAME,x) ENUM_CASE_FROM_STRING_16(NAME,__VA_ARGS__)
83
#define ENUM_CASE_FROM_STRING_18(NAME,x,...) ENUM_FROM_STRING_EXPR(NAME,x) ENUM_CASE_FROM_STRING_17(NAME,__VA_ARGS__)
84
#define ENUM_CASE_FROM_STRING_19(NAME,x,...) ENUM_FROM_STRING_EXPR(NAME,x) ENUM_CASE_FROM_STRING_18(NAME,__VA_ARGS__)
85
#define ENUM_CASE_FROM_STRING_20(NAME,x,...) ENUM_FROM_STRING_EXPR(NAME,x) ENUM_CASE_FROM_STRING_19(NAME,__VA_ARGS__)
86
#define ENUM_CASE_FROM_STRING_IMPL(i,NAME,...) ENUM_CASE_FROM_STRING_##i(NAME,__VA_ARGS__)
87
#define ENUM_CASE_FROM_STRING(i,NAME,...) ENUM_CASE_FROM_STRING_IMPL(i,NAME,__VA_ARGS__)
88
89
// Create a static member entry
90
#define ENUM_TO_MEMBER_EXPR(NAME,value) static enum_t const value;
91
#define ENUM_TO_MEMBER_0(NAME,x) ENUM_TO_MEMBER_EXPR(NAME,x)
92
#define ENUM_TO_MEMBER_1(NAME,x,...) ENUM_TO_MEMBER_EXPR(NAME,x) ENUM_TO_MEMBER_0(NAME,__VA_ARGS__)
93
#define ENUM_TO_MEMBER_2(NAME,x,...) ENUM_TO_MEMBER_EXPR(NAME,x) ENUM_TO_MEMBER_1(NAME,__VA_ARGS__)
94
#define ENUM_TO_MEMBER_3(NAME,x,...) ENUM_TO_MEMBER_EXPR(NAME,x) ENUM_TO_MEMBER_2(NAME,__VA_ARGS__)
95
#define ENUM_TO_MEMBER_4(NAME,x,...) ENUM_TO_MEMBER_EXPR(NAME,x) ENUM_TO_MEMBER_3(NAME,__VA_ARGS__)
96
#define ENUM_TO_MEMBER_5(NAME,x,...) ENUM_TO_MEMBER_EXPR(NAME,x) ENUM_TO_MEMBER_4(NAME,__VA_ARGS__)
97
#define ENUM_TO_MEMBER_6(NAME,x,...) ENUM_TO_MEMBER_EXPR(NAME,x) ENUM_TO_MEMBER_5(NAME,__VA_ARGS__)
98
#define ENUM_TO_MEMBER_7(NAME,x,...) ENUM_TO_MEMBER_EXPR(NAME,x) ENUM_TO_MEMBER_6(NAME,__VA_ARGS__)
99
#define ENUM_TO_MEMBER_8(NAME,x,...) ENUM_TO_MEMBER_EXPR(NAME,x) ENUM_TO_MEMBER_7(NAME,__VA_ARGS__)
100
#define ENUM_TO_MEMBER_9(NAME,x,...) ENUM_TO_MEMBER_EXPR(NAME,x) ENUM_TO_MEMBER_8(NAME,__VA_ARGS__)
101
#define ENUM_TO_MEMBER_10(NAME,x,...) ENUM_TO_MEMBER_EXPR(NAME,x) ENUM_TO_MEMBER_9(NAME,__VA_ARGS__)
102
#define ENUM_TO_MEMBER_11(NAME,x,...) ENUM_TO_MEMBER_EXPR(NAME,x) ENUM_TO_MEMBER_10(NAME,__VA_ARGS__)
103
#define ENUM_TO_MEMBER_12(NAME,x,...) ENUM_TO_MEMBER_EXPR(NAME,x) ENUM_TO_MEMBER_11(NAME,__VA_ARGS__)
104
#define ENUM_TO_MEMBER_13(NAME,x,...) ENUM_TO_MEMBER_EXPR(NAME,x) ENUM_TO_MEMBER_12(NAME,__VA_ARGS__)
105
#define ENUM_TO_MEMBER_14(NAME,x,...) ENUM_TO_MEMBER_EXPR(NAME,x) ENUM_TO_MEMBER_13(NAME,__VA_ARGS__)
106
#define ENUM_TO_MEMBER_15(NAME,x,...) ENUM_TO_MEMBER_EXPR(NAME,x) ENUM_TO_MEMBER_14(NAME,__VA_ARGS__)
107
#define ENUM_TO_MEMBER_16(NAME,x,...) ENUM_TO_MEMBER_EXPR(NAME,x) ENUM_TO_MEMBER_15(NAME,__VA_ARGS__)
108
#define ENUM_TO_MEMBER_17(NAME,x,...) ENUM_TO_MEMBER_EXPR(NAME,x) ENUM_TO_MEMBER_16(NAME,__VA_ARGS__)
109
#define ENUM_TO_MEMBER_18(NAME,x,...) ENUM_TO_MEMBER_EXPR(NAME,x) ENUM_TO_MEMBER_17(NAME,__VA_ARGS__)
110
#define ENUM_TO_MEMBER_19(NAME,x,...) ENUM_TO_MEMBER_EXPR(NAME,x) ENUM_TO_MEMBER_18(NAME,__VA_ARGS__)
111
#define ENUM_TO_MEMBER_20(NAME,x,...) ENUM_TO_MEMBER_EXPR(NAME,x) ENUM_TO_MEMBER_19(NAME,__VA_ARGS__)
112
#define ENUM_TO_MEMBER_IMPL(i,NAME,...) ENUM_TO_MEMBER_##i(NAME,__VA_ARGS__)
113
#define ENUM_TO_MEMBER(i,NAME,...) ENUM_TO_MEMBER_IMPL(i, NAME, __VA_ARGS__)
114
115
// Initialize the static member entry
116
#define ENUM_STATIC_INIT_EXPR(NAME,value) inline NAME::enum_t const NAME::value = NAME::enum_t::value;
117
#define ENUM_STATIC_INIT_0(NAME,x) ENUM_STATIC_INIT_EXPR(NAME,x)
118
#define ENUM_STATIC_INIT_1(NAME,x,...) ENUM_STATIC_INIT_EXPR(NAME,x) ENUM_STATIC_INIT_0(NAME,__VA_ARGS__)
119
#define ENUM_STATIC_INIT_2(NAME,x,...) ENUM_STATIC_INIT_EXPR(NAME,x) ENUM_STATIC_INIT_1(NAME,__VA_ARGS__)
120
#define ENUM_STATIC_INIT_3(NAME,x,...) ENUM_STATIC_INIT_EXPR(NAME,x) ENUM_STATIC_INIT_2(NAME,__VA_ARGS__)
121
#define ENUM_STATIC_INIT_4(NAME,x,...) ENUM_STATIC_INIT_EXPR(NAME,x) ENUM_STATIC_INIT_3(NAME,__VA_ARGS__)
122
#define ENUM_STATIC_INIT_5(NAME,x,...) ENUM_STATIC_INIT_EXPR(NAME,x) ENUM_STATIC_INIT_4(NAME,__VA_ARGS__)
123
#define ENUM_STATIC_INIT_6(NAME,x,...) ENUM_STATIC_INIT_EXPR(NAME,x) ENUM_STATIC_INIT_5(NAME,__VA_ARGS__)
124
#define ENUM_STATIC_INIT_7(NAME,x,...) ENUM_STATIC_INIT_EXPR(NAME,x) ENUM_STATIC_INIT_6(NAME,__VA_ARGS__)
125
#define ENUM_STATIC_INIT_8(NAME,x,...) ENUM_STATIC_INIT_EXPR(NAME,x) ENUM_STATIC_INIT_7(NAME,__VA_ARGS__)
126
#define ENUM_STATIC_INIT_9(NAME,x,...) ENUM_STATIC_INIT_EXPR(NAME,x) ENUM_STATIC_INIT_8(NAME,__VA_ARGS__)
127
#define ENUM_STATIC_INIT_10(NAME,x,...) ENUM_STATIC_INIT_EXPR(NAME,x) ENUM_STATIC_INIT_9(NAME,__VA_ARGS__)
128
#define ENUM_STATIC_INIT_11(NAME,x,...) ENUM_STATIC_INIT_EXPR(NAME,x) ENUM_STATIC_INIT_10(NAME,__VA_ARGS__)
129
#define ENUM_STATIC_INIT_12(NAME,x,...) ENUM_STATIC_INIT_EXPR(NAME,x) ENUM_STATIC_INIT_11(NAME,__VA_ARGS__)
130
#define ENUM_STATIC_INIT_13(NAME,x,...) ENUM_STATIC_INIT_EXPR(NAME,x) ENUM_STATIC_INIT_12(NAME,__VA_ARGS__)
131
#define ENUM_STATIC_INIT_14(NAME,x,...) ENUM_STATIC_INIT_EXPR(NAME,x) ENUM_STATIC_INIT_13(NAME,__VA_ARGS__)
132
#define ENUM_STATIC_INIT_15(NAME,x,...) ENUM_STATIC_INIT_EXPR(NAME,x) ENUM_STATIC_INIT_14(NAME,__VA_ARGS__)
133
#define ENUM_STATIC_INIT_16(NAME,x,...) ENUM_STATIC_INIT_EXPR(NAME,x) ENUM_STATIC_INIT_15(NAME,__VA_ARGS__)
134
#define ENUM_STATIC_INIT_17(NAME,x,...) ENUM_STATIC_INIT_EXPR(NAME,x) ENUM_STATIC_INIT_16(NAME,__VA_ARGS__)
135
#define ENUM_STATIC_INIT_18(NAME,x,...) ENUM_STATIC_INIT_EXPR(NAME,x) ENUM_STATIC_INIT_17(NAME,__VA_ARGS__)
136
#define ENUM_STATIC_INIT_19(NAME,x,...) ENUM_STATIC_INIT_EXPR(NAME,x) ENUM_STATIC_INIT_18(NAME,__VA_ARGS__)
137
#define ENUM_STATIC_INIT_20(NAME,x,...) ENUM_STATIC_INIT_EXPR(NAME,x) ENUM_STATIC_INIT_19(NAME,__VA_ARGS__)
138
#define ENUM_STATIC_INIT_IMPL(i,NAME,...) ENUM_STATIC_INIT_##i(NAME,__VA_ARGS__)
139
#define ENUM_STATIC_INIT(i,NAME,...) ENUM_STATIC_INIT_IMPL(i, NAME, __VA_ARGS__)
140
141
#define ENUM_IMPL(NAME, ...) \
142
struct NAME \
143
{ \
144
public: \
145
enum class enum_t : int { __VA_ARGS__ }; \
146
private: \
147
enum_t m_current; \
148
public: \
149
size_t const size = VA_SIZE(__VA_ARGS__); \
150
ENUM_TO_MEMBER(VA_SIZE(VA_DROP(__VA_ARGS__)), NAME, __VA_ARGS__) \
151
NAME() : m_current(enum_t::NONE) {} \
152
NAME(NAME const&) = default;\
153
NAME(NAME&&) = default;\
154
NAME(enum_t entry) : m_current(entry) {}\
155
/* from_string callable (declaration) */
\
156
struct from_string_t { \
157
std::expected<NAME, std::string> operator()(std::string) const; \
158
}; \
159
static inline constexpr from_string_t from_string{}; \
160
operator enum_t() const \
161
{ \
162
return m_current; \
163
} \
164
enum_t get() const \
165
{ \
166
return m_current; \
167
} \
168
std::string lower() const \
169
{ \
170
std::string str{*this}; \
171
std::ranges::transform(str, str.begin(), ::tolower); \
172
return str; \
173
} \
174
operator std::string() const \
175
{ \
176
switch(m_current) \
177
{ \
178
ENUM_CASE_TO_STRING(VA_SIZE(VA_DROP(__VA_ARGS__)), NAME, __VA_ARGS__) \
179
} \
180
return "";
/* Unreachable */
\
181
} \
182
bool operator<(NAME const& other) const \
183
{ \
184
return this->m_current < other.m_current; \
185
} \
186
bool operator==(enum_t const& enum_value) const \
187
{ \
188
return m_current == enum_value; \
189
} \
190
NAME& operator=(NAME const& other) { m_current = other.m_current; return *this; }\
191
NAME& operator=(NAME&& other) { m_current = other.m_current; return *this; }\
192
}; \
193
ENUM_STATIC_INIT(VA_SIZE(VA_DROP(__VA_ARGS__)), NAME, __VA_ARGS__) \
194
/* Define the callable after the class is complete */
\
195
inline std::expected<NAME, std::string> NAME::from_string_t::operator()(std::string str_enum) const { \
196
std::ranges::transform(str_enum, str_enum.begin(), [](unsigned char c){ return static_cast<char>(std::toupper(c)); }); \
197
ENUM_CASE_FROM_STRING(VA_SIZE(VA_DROP(__VA_ARGS__)), NAME, __VA_ARGS__) \
198
return std::unexpected(std::string("Could not determine enum entry from '") + str_enum + "'"); \
199
}
200
201
#define ENUM(NAME, ...) ENUM_IMPL(NAME, __VA_ARGS__, NONE)
202
203
/* vim: set expandtab fdm=marker ts=2 sw=2 tw=100 et :*/
src
std
enum.hpp
Generated by
1.13.2