7 // optional type needed for interface
8 #ifndef WISE_ENUM_OPTIONAL_TYPE
9 #if __cplusplus >= 201703L
13 using optional_type
= std::optional
<T
>;
19 using optional_type
= wise_enum::optional
<T
>;
25 using optional_type
= WISE_ENUM_OPTIONAL_TYPE
<T
>;
29 // Choice of string_view if type defined, otherwise use string literal
30 #ifndef WISE_ENUM_STRING_TYPE
31 #if __cplusplus >= 201703L
32 #include <string_view>
34 using string_type
= std::string_view
;
38 using string_type
= const char *;
43 using string_type
= WISE_ENUM_STRING_TYPE
;
47 #if __cplusplus == 201103
48 #define WISE_ENUM_CONSTEXPR_14
50 #define WISE_ENUM_CONSTEXPR_14 constexpr
57 struct value_and_name
{
65 constexpr void wise_enum_detail_array(...);
69 : std::integral_constant
<
70 bool, !std::is_same
<void, decltype(wise_enum_detail_array(
71 Tag
<T
>{}))>::value
> {};
73 WISE_ENUM_CONSTEXPR_14
inline int strcmp(const char *s1
, const char *s2
) {
74 while (*s1
&& (*s1
== *s2
))
86 WISE_ENUM_CONSTEXPR_14
inline bool compare(const char *s1
, const char *s2
) {
87 return strcmp(s1
, s2
) == 0;
90 template <class U
, class = typename
std::enable_if
<
91 !std::is_same
<U
, const char *>::value
>::type
>
92 WISE_ENUM_CONSTEXPR_14
bool compare(U u1
, U u2
) {
96 } // namespace wise_enum
99 // Needed for expansion of variadic macro arguments in MSVC
100 // MSVC expands __VA_ARGS__ after passing it, while gcc expands it before
101 #define WISE_ENUM_IMPL_EXPAND(x) x
103 #define WISE_ENUM_IMPL_NARG(...) \
104 WISE_ENUM_IMPL_NARG_(__VA_ARGS__, WISE_ENUM_IMPL_RSEQ_N())
105 #define WISE_ENUM_IMPL_NARG_(...) WISE_ENUM_IMPL_EXPAND(WISE_ENUM_IMPL_ARG_N(__VA_ARGS__))
107 // ARG_N and RSEQ_N defined in wise_enum_generated.h
109 // Building blocks; credit to:
110 // https://github.com/pfultz2/Cloak/wiki/C-Preprocessor-tricks,-tips,-and-idioms
112 #define WISE_ENUM_IMPL_COMMA() ,
113 #define WISE_ENUM_IMPL_NOTHING()
115 #define WISE_ENUM_IMPL_CAT(a, ...) WISE_ENUM_IMPL_PRIMITIVE_CAT(a, __VA_ARGS__)
116 #define WISE_ENUM_IMPL_PRIMITIVE_CAT(a, ...) a##__VA_ARGS__
118 #define WISE_ENUM_IMPL_XSTR(s) #s
119 #define WISE_ENUM_IMPL_STR(s) WISE_ENUM_IMPL_XSTR(s)
121 #define WISE_ENUM_IMPL_IIF(c) WISE_ENUM_IMPL_CAT(WISE_ENUM_IMPL_IIF_, c)
122 #define WISE_ENUM_IMPL_IIF_0(t, f) f
123 #define WISE_ENUM_IMPL_IIF_1(t, f) t
125 #define WISE_ENUM_IMPL_CHECK_N(x, n, ...) n
126 #define WISE_ENUM_IMPL_CHECK(...) \
127 WISE_ENUM_IMPL_EXPAND(WISE_ENUM_IMPL_CHECK_N(__VA_ARGS__, 0, ))
128 #define WISE_ENUM_IMPL_PROBE(x) x, 1,
130 #define WISE_ENUM_IMPL_IS_PAREN(x) \
131 WISE_ENUM_IMPL_CHECK(WISE_ENUM_IMPL_IS_PAREN_PROBE x)
132 #define WISE_ENUM_IMPL_IS_PAREN_PROBE(...) WISE_ENUM_IMPL_PROBE(~)
134 #define WISE_ENUM_IMPL_FIRST_ARG(x, ...) x
136 #define WISE_ENUM_IMPL_ONLY_OR_FIRST(x) \
137 WISE_ENUM_IMPL_IIF(WISE_ENUM_IMPL_IS_PAREN(x)) \
138 (WISE_ENUM_IMPL_FIRST_ARG x, x)
140 // Use building blocks to conditionally process enumerators; they can either be
141 // just an identifier, or (identifier, value)
142 #define WISE_ENUM_IMPL_ENUM_INIT_2(x, ...) x = __VA_ARGS__
143 #define WISE_ENUM_IMPL_ENUM_INIT(name, x) \
144 WISE_ENUM_IMPL_IIF(WISE_ENUM_IMPL_IS_PAREN(x)) \
145 (WISE_ENUM_IMPL_ENUM_INIT_2 x, x)
147 #define WISE_ENUM_IMPL_ENUM_STR(x) \
148 WISE_ENUM_IMPL_STR(WISE_ENUM_IMPL_ONLY_OR_FIRST(x))
150 #define WISE_ENUM_IMPL_DESC_PAIR(name, x) \
151 { name::WISE_ENUM_IMPL_ONLY_OR_FIRST(x), WISE_ENUM_IMPL_ENUM_STR(x) }
153 #define WISE_ENUM_IMPL_SWITCH_CASE(name, x) \
154 case name::WISE_ENUM_IMPL_ONLY_OR_FIRST(x): \
155 return WISE_ENUM_IMPL_ENUM_STR(x);
157 #define WISE_ENUM_IMPL_STORAGE_2(x, y) y
159 #define WISE_ENUM_IMPL_STORAGE(x) \
160 WISE_ENUM_IMPL_IIF(WISE_ENUM_IMPL_IS_PAREN(x)) \
161 ( : WISE_ENUM_IMPL_STORAGE_2 x, )
163 #define WISE_ENUM_IMPL(type, name_storage, friendly, ...) \
164 WISE_ENUM_IMPL_2(type, WISE_ENUM_IMPL_ONLY_OR_FIRST(name_storage), \
165 WISE_ENUM_IMPL_STORAGE(name_storage), friendly, \
166 WISE_ENUM_IMPL_NARG(__VA_ARGS__), __VA_ARGS__)
168 #define WISE_ENUM_IMPL_2(type, name, storage, friendly, num_enums, ...) \
169 WISE_ENUM_IMPL_3(type, name, storage, friendly, num_enums, \
170 WISE_ENUM_IMPL_CAT(WISE_ENUM_IMPL_LOOP_, num_enums), \
174 #define WISE_ENUM_IMPL_3(type, name, storage, friendly, num_enums, loop, ...) \
176 WISE_ENUM_IMPL_EXPAND(loop(WISE_ENUM_IMPL_ENUM_INIT, _, \
177 WISE_ENUM_IMPL_COMMA, __VA_ARGS__))}; \
178 WISE_ENUM_IMPL_ADAPT_3(name, friendly, num_enums, loop, __VA_ARGS__)
180 #define WISE_ENUM_IMPL_ADAPT(name, ...) \
181 namespace wise_enum { \
183 WISE_ENUM_IMPL_ADAPT_2(name, WISE_ENUM_IMPL_NARG(__VA_ARGS__), __VA_ARGS__) \
187 #define WISE_ENUM_IMPL_ADAPT_2(name, num_enums, ...) \
188 WISE_ENUM_IMPL_ADAPT_3(name, , num_enums, \
189 WISE_ENUM_IMPL_CAT(WISE_ENUM_IMPL_LOOP_, num_enums), \
192 #define WISE_ENUM_IMPL_ADAPT_3(name, friendly, num_enums, loop, ...) \
193 friendly constexpr std::array<::wise_enum::detail::value_and_name<name>, \
195 wise_enum_detail_array(::wise_enum::detail::Tag<name>) { \
196 return {{WISE_ENUM_IMPL_EXPAND(loop(WISE_ENUM_IMPL_DESC_PAIR, name, \
197 WISE_ENUM_IMPL_COMMA, __VA_ARGS__))}}; \
201 friendly WISE_ENUM_CONSTEXPR_14 ::wise_enum::string_type \
202 wise_enum_detail_to_string(T e, ::wise_enum::detail::Tag<name>) { \
204 WISE_ENUM_IMPL_EXPAND(loop(WISE_ENUM_IMPL_SWITCH_CASE, name, \
205 WISE_ENUM_IMPL_NOTHING, __VA_ARGS__)) \
This page took 0.034264 seconds and 4 git commands to generate.