cpp-common/bt2c/fmt.hpp: use `wise_enum::string_type` in `EnableIfIsWiseEnum` definition
[babeltrace.git] / src / cpp-common / vendor / wise-enum / wise_enum_detail.h
1 #pragma once
2
3 #include <array>
4 #include <type_traits>
5 #include <utility>
6
7 // optional type needed for interface
8 #ifndef WISE_ENUM_OPTIONAL_TYPE
9 #if __cplusplus >= 201703L
10 #include <optional>
11 namespace wise_enum {
12 template <class T>
13 using optional_type = std::optional<T>;
14 }
15 #else
16 #include "optional.h"
17 namespace wise_enum {
18 template <class T>
19 using optional_type = wise_enum::optional<T>;
20 }
21 #endif
22 #else
23 namespace wise_enum {
24 template <class T>
25 using optional_type = WISE_ENUM_OPTIONAL_TYPE<T>;
26 }
27 #endif
28
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>
33 namespace wise_enum {
34 using string_type = std::string_view;
35 }
36 #else
37 namespace wise_enum {
38 using string_type = const char *;
39 }
40 #endif
41 #else
42 namespace wise_enum {
43 using string_type = WISE_ENUM_STRING_TYPE;
44 }
45 #endif
46
47 #if __cplusplus == 201103
48 #define WISE_ENUM_CONSTEXPR_14
49 #else
50 #define WISE_ENUM_CONSTEXPR_14 constexpr
51 #endif
52
53 namespace wise_enum {
54 namespace detail {
55
56 template <class T>
57 struct value_and_name {
58 T value;
59 string_type name;
60 };
61
62 template <class T>
63 struct Tag {};
64
65 constexpr void wise_enum_detail_array(...);
66
67 template <class T>
68 struct is_wise_enum
69 : std::integral_constant<
70 bool, !std::is_same<void, decltype(wise_enum_detail_array(
71 Tag<T>{}))>::value> {};
72
73 WISE_ENUM_CONSTEXPR_14 inline int strcmp(const char *s1, const char *s2) {
74 while (*s1 && (*s1 == *s2))
75 s1++, s2++;
76 if (*s1 < *s2) {
77 return -1;
78 }
79 if (*s1 > *s2) {
80 return 1;
81 } else {
82 return 0;
83 }
84 }
85
86 WISE_ENUM_CONSTEXPR_14 inline bool compare(const char *s1, const char *s2) {
87 return strcmp(s1, s2) == 0;
88 }
89
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) {
93 return u1 == u2;
94 }
95 } // namespace detail
96 } // namespace wise_enum
97
98
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
102
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__))
106
107 // ARG_N and RSEQ_N defined in wise_enum_generated.h
108
109 // Building blocks; credit to:
110 // https://github.com/pfultz2/Cloak/wiki/C-Preprocessor-tricks,-tips,-and-idioms
111
112 #define WISE_ENUM_IMPL_COMMA() ,
113 #define WISE_ENUM_IMPL_NOTHING()
114
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__
117
118 #define WISE_ENUM_IMPL_XSTR(s) #s
119 #define WISE_ENUM_IMPL_STR(s) WISE_ENUM_IMPL_XSTR(s)
120
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
124
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,
129
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(~)
133
134 #define WISE_ENUM_IMPL_FIRST_ARG(x, ...) x
135
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)
139
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)
146
147 #define WISE_ENUM_IMPL_ENUM_STR(x) \
148 WISE_ENUM_IMPL_STR(WISE_ENUM_IMPL_ONLY_OR_FIRST(x))
149
150 #define WISE_ENUM_IMPL_DESC_PAIR(name, x) \
151 { name::WISE_ENUM_IMPL_ONLY_OR_FIRST(x), WISE_ENUM_IMPL_ENUM_STR(x) }
152
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);
156
157 #define WISE_ENUM_IMPL_STORAGE_2(x, y) y
158
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, )
162
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__)
167
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), \
171 __VA_ARGS__)
172
173
174 #define WISE_ENUM_IMPL_3(type, name, storage, friendly, num_enums, loop, ...) \
175 type name storage{ \
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__)
179
180 #define WISE_ENUM_IMPL_ADAPT(name, ...) \
181 namespace wise_enum { \
182 namespace detail { \
183 WISE_ENUM_IMPL_ADAPT_2(name, WISE_ENUM_IMPL_NARG(__VA_ARGS__), __VA_ARGS__) \
184 } \
185 }
186
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), \
190 __VA_ARGS__)
191
192 #define WISE_ENUM_IMPL_ADAPT_3(name, friendly, num_enums, loop, ...) \
193 friendly constexpr std::array<::wise_enum::detail::value_and_name<name>, \
194 num_enums> \
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__))}}; \
198 } \
199 \
200 template <class T> \
201 friendly WISE_ENUM_CONSTEXPR_14 ::wise_enum::string_type \
202 wise_enum_detail_to_string(T e, ::wise_enum::detail::Tag<name>) { \
203 switch (e) { \
204 WISE_ENUM_IMPL_EXPAND(loop(WISE_ENUM_IMPL_SWITCH_CASE, name, \
205 WISE_ENUM_IMPL_NOTHING, __VA_ARGS__)) \
206 } \
207 return {}; \
208 }
This page took 0.052975 seconds and 4 git commands to generate.