1 #ifndef libjmmcg_core_enum_as_char_array_hpp
2 #define libjmmcg_core_enum_as_char_array_hpp
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 #include <boost/mpl/assert.hpp>
25
26 #include <cstdint>
27 #include <type_traits>
28
29 namespace jmmcg {
30
31
32 namespace enum_tags {
33
34 namespace mpl {
35
36 namespace private_ {
37
38 template<char c1, char c2='\0', char c3='\0', char c4='\0', char c5='\0', char c6='\0', char c7='\0', char c8='\0'>
39 struct select_underlying_type {
40 using type=std::uint64_t;
41 };
42 template<char c1, char c2, char c3, char c4, char c5, char c6, char c7>
43 struct select_underlying_type<c1, c2, c3, c4, c5, c6, c7, '\0'> {
44 using type=std::uint64_t;
45 };
46 template<char c1, char c2, char c3, char c4, char c5, char c6>
47 struct select_underlying_type<c1, c2, c3, c4, c5, c6, '\0', '\0'> {
48 using type=std::uint64_t;
49 };
50 template<char c1, char c2, char c3, char c4, char c5>
51 struct select_underlying_type<c1, c2, c3, c4, c5, '\0', '\0', '\0'> {
52 using type=std::uint64_t;
53 };
54 template<char c1, char c2, char c3, char c4>
55 struct select_underlying_type<c1, c2, c3, c4, '\0', '\0', '\0', '\0'> {
56 using type=std::uint32_t;
57 };
58 template<char c1, char c2, char c3>
59 struct select_underlying_type<c1, c2, c3, '\0', '\0', '\0', '\0', '\0'> {
60 using type=std::uint32_t;
61 };
62 template<char c1, char c2>
63 struct select_underlying_type<c1, c2, '\0', '\0', '\0', '\0', '\0', '\0'> {
64 using type=std::uint16_t;
65 };
66 template<char c1>
67 struct select_underlying_type<c1, '\0', '\0', '\0', '\0', '\0', '\0', '\0'> {
68 using type=std::uint8_t;
69 };
70
71 template<
72 class EnumT,
73 EnumT t,
74 typename std::underlying_type<EnumT>::type i=(static_cast<typename std::underlying_type<EnumT>::type>(t)>>8),
75 bool is_digit=(static_cast<bool>(i))
76 >
77 struct count_digits {
78 enum : typename std::underlying_type<EnumT>::type {
79 value=1+count_digits<EnumT, t, (i>>8)>::value
80 };
81 };
82 template<
83 class EnumT,
84 EnumT t,
85 typename std::underlying_type<EnumT>::type i
86 >
87 struct count_digits<EnumT, t, i, false> {
88 enum : typename std::underlying_type<EnumT>::type {
89 value=1
90 };
91 };
92
93 }
94
95
96
97
98
99 template<char c1, char c2='\0', char c3='\0', char c4='\0', char c5='\0', char c6='\0', char c7='\0', char c8='\0'>
100 struct to_tag {
101 using element_type=typename private_::select_underlying_type<c1, c2, c3, c4, c5, c6, c7, c8>::type;
102
103 enum : element_type {
104 value=
105 (static_cast<element_type>(c1)<<56)
106 +(static_cast<element_type>(c2)<<48)
107 +(static_cast<element_type>(c3)<<40)
108 +(static_cast<element_type>(c4)<<32)
109 +(static_cast<element_type>(c5)<<24)
110 +(static_cast<element_type>(c6)<<16)
111 +(static_cast<element_type>(c7)<<8)
112 +static_cast<element_type>(c8)
113 };
114 };
115 template<char c1, char c2, char c3, char c4, char c5, char c6, char c7>
116 struct to_tag<c1, c2, c3, c4, c5, c6, c7, '\0'> {
117 using element_type=typename private_::select_underlying_type<c1, c2, c3, c4, c5, c6, c7>::type;
118
119 enum : element_type {
120 value=
121 (static_cast<element_type>(c1)<<48)
122 +(static_cast<element_type>(c2)<<40)
123 +(static_cast<element_type>(c3)<<32)
124 +(static_cast<element_type>(c4)<<24)
125 +(static_cast<element_type>(c5)<<16)
126 +(static_cast<element_type>(c6)<<8)
127 +static_cast<element_type>(c7)
128 };
129 };
130 template<char c1, char c2, char c3, char c4, char c5, char c6>
131 struct to_tag<c1, c2, c3, c4, c5, c6, '\0', '\0'> {
132 using element_type=typename private_::select_underlying_type<c1, c2, c3, c4, c5, c6>::type;
133
134 enum : element_type {
135 value=
136 (static_cast<element_type>(c1)<<40)
137 +(static_cast<element_type>(c2)<<32)
138 +(static_cast<element_type>(c3)<<24)
139 +(static_cast<element_type>(c4)<<16)
140 +(static_cast<element_type>(c5)<<8)
141 +static_cast<element_type>(c6)
142 };
143 };
144 template<char c1, char c2, char c3, char c4, char c5>
145 struct to_tag<c1, c2, c3, c4, c5, '\0', '\0', '\0'> {
146 using element_type=typename private_::select_underlying_type<c1, c2, c3, c4, c5>::type;
147
148 enum : element_type {
149 value=
150 (static_cast<element_type>(c1)<<32)
151 +(static_cast<element_type>(c2)<<24)
152 +(static_cast<element_type>(c3)<<16)
153 +(static_cast<element_type>(c4)<<8)
154 +static_cast<element_type>(c5)
155 };
156 };
157 template<char c1, char c2, char c3, char c4>
158 struct to_tag<c1, c2, c3, c4, '\0', '\0', '\0', '\0'> {
159 using element_type=typename private_::select_underlying_type<c1, c2, c3, c4>::type;
160
161 enum : element_type {
162 value=
163 (static_cast<element_type>(c1)<<24)
164 +(static_cast<element_type>(c2)<<16)
165 +(static_cast<element_type>(c3)<<8)
166 +static_cast<element_type>(c4)
167 };
168 };
169 template<char c1, char c2, char c3>
170 struct to_tag<c1, c2, c3, '\0', '\0', '\0', '\0', '\0'> {
171 using element_type=typename private_::select_underlying_type<c1, c2, c3>::type;
172
173 enum : element_type {
174 value=
175 (static_cast<element_type>(c1)<<16)
176 +(static_cast<element_type>(c2)<<8)
177 +static_cast<element_type>(c3)
178 };
179 };
180 template<char c1, char c2>
181 struct to_tag<c1, c2, '\0', '\0', '\0', '\0', '\0', '\0'> {
182 using element_type=typename private_::select_underlying_type<c1, c2>::type;
183
184 enum : element_type {
185 value=
186 (static_cast<element_type>(c1)<<8)
187 +static_cast<element_type>(c2)
188 };
189 };
190 template<char c1>
191 struct to_tag<c1, '\0', '\0', '\0', '\0', '\0', '\0', '\0'> {
192 using element_type=typename private_::select_underlying_type<c1>::type;
193
194 enum : element_type {
195 value=static_cast<element_type>(c1)
196 };
197 };
198
199
200
201
202
203 template<
204 class EnumT,
205 EnumT t,
206 unsigned num_digits=private_::count_digits<EnumT, t>::value
207 >
208 struct to_array;
209 template<
210 class EnumT,
211 EnumT t
212 >
213 struct to_array<EnumT, t, 8u> {
214 enum : std::size_t {
215 size=private_::count_digits<EnumT, t>::value
216 };
217 enum : typename std::underlying_type<EnumT>::type {
218 value_as_int=static_cast<typename std::underlying_type<EnumT>::type>(t)
219 };
220 using const_element_type=const char [size];
221 using element_type=char [size];
222 static constexpr EnumT tag=t;
223
224 static constexpr const_element_type value={
225 static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>56)&0xFF),
226 static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>48)&0xFF),
227 static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>40)&0xFF),
228 static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>32)&0xFF),
229 static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>24)&0xFF),
230 static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>16)&0xFF),
231 static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>8)&0xFF),
232 static_cast<char>(static_cast<typename std::underlying_type<EnumT>::type>(t)&0xFF)
233 };
234 };
235 template<
236 class EnumT,
237 EnumT t
238 >
239 struct to_array<EnumT, t, 7u> {
240 enum : std::size_t {
241 size=private_::count_digits<EnumT, t>::value
242 };
243 enum : typename std::underlying_type<EnumT>::type {
244 value_as_int=static_cast<typename std::underlying_type<EnumT>::type>(t)
245 };
246 using const_element_type=const char [size];
247 using element_type=char [size];
248 static constexpr EnumT tag=t;
249
250 static constexpr const_element_type value={
251 static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>48)&0xFF),
252 static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>40)&0xFF),
253 static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>32)&0xFF),
254 static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>24)&0xFF),
255 static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>16)&0xFF),
256 static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>8)&0xFF),
257 static_cast<char>(static_cast<typename std::underlying_type<EnumT>::type>(t)&0xFF)
258 };
259 };
260 template<
261 class EnumT,
262 EnumT t
263 >
264 struct to_array<EnumT, t, 6u> {
265 enum : std::size_t {
266 size=private_::count_digits<EnumT, t>::value
267 };
268 enum : typename std::underlying_type<EnumT>::type {
269 value_as_int=static_cast<typename std::underlying_type<EnumT>::type>(t)
270 };
271 using const_element_type=const char [size];
272 using element_type=char [size];
273 static constexpr EnumT tag=t;
274
275 static constexpr const_element_type value={
276 static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>40)&0xFF),
277 static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>32)&0xFF),
278 static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>24)&0xFF),
279 static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>16)&0xFF),
280 static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>8)&0xFF),
281 static_cast<char>(static_cast<typename std::underlying_type<EnumT>::type>(t)&0xFF)
282 };
283 };
284 template<
285 class EnumT,
286 EnumT t
287 >
288 struct to_array<EnumT, t, 5u> {
289 enum : std::size_t {
290 size=private_::count_digits<EnumT, t>::value
291 };
292 enum : typename std::underlying_type<EnumT>::type {
293 value_as_int=static_cast<typename std::underlying_type<EnumT>::type>(t)
294 };
295 using const_element_type=const char [size];
296 using element_type=char [size];
297 static constexpr EnumT tag=t;
298
299 static constexpr const_element_type value={
300 static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>32)&0xFF),
301 static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>24)&0xFF),
302 static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>16)&0xFF),
303 static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>8)&0xFF),
304 static_cast<char>(static_cast<typename std::underlying_type<EnumT>::type>(t)&0xFF)
305 };
306 };
307 template<
308 class EnumT,
309 EnumT t
310 >
311 struct to_array<EnumT, t, 4u> {
312 enum : std::size_t {
313 size=private_::count_digits<EnumT, t>::value
314 };
315 enum : typename std::underlying_type<EnumT>::type {
316 value_as_int=static_cast<typename std::underlying_type<EnumT>::type>(t)
317 };
318 using const_element_type=const char [size];
319 using element_type=char [size];
320 static constexpr EnumT tag=t;
321 static constexpr const_element_type value={
322 static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>24)&0xFF),
323 static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>16)&0xFF),
324 static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>8)&0xFF),
325 static_cast<char>(static_cast<typename std::underlying_type<EnumT>::type>(t)&0xFF)
326 };
327 };
328 template<
329 class EnumT,
330 EnumT t
331 >
332 struct to_array<EnumT, t, 3u> {
333 enum : std::size_t {
334 size=private_::count_digits<EnumT, t>::value
335 };
336 enum : typename std::underlying_type<EnumT>::type {
337 value_as_int=static_cast<typename std::underlying_type<EnumT>::type>(t)
338 };
339 using const_element_type=const char [size];
340 using element_type=char [size];
341 static constexpr EnumT tag=t;
342 static constexpr const_element_type value={
343 static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>16)&0xFF),
344 static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>8)&0xFF),
345 static_cast<char>(static_cast<typename std::underlying_type<EnumT>::type>(t)&0xFF)
346 };
347 };
348 template<
349 class EnumT,
350 EnumT t
351 >
352 struct to_array<EnumT, t, 2u> {
353 enum : std::size_t {
354 size=private_::count_digits<EnumT, t>::value
355 };
356 enum : typename std::underlying_type<EnumT>::type {
357 value_as_int=static_cast<typename std::underlying_type<EnumT>::type>(t)
358 };
359 using const_element_type=const char [size];
360 using element_type=char [size];
361 static constexpr EnumT tag=t;
362 static constexpr const_element_type value={
363 static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>8)&0xFF),
364 static_cast<char>(static_cast<typename std::underlying_type<EnumT>::type>(t)&0xFF)
365 };
366 };
367 template<
368 class EnumT,
369 EnumT t
370 >
371 struct to_array<EnumT, t, 1u> {
372 enum : std::size_t {
373 size=1
374 };
375 enum : typename std::underlying_type<EnumT>::type {
376 value_as_int=static_cast<typename std::underlying_type<EnumT>::type>(t)
377 };
378 using const_element_type=const char [size];
379 using element_type=char [size];
380 static constexpr EnumT tag=t;
381 static constexpr const_element_type value={
382 static_cast<char>(static_cast<typename std::underlying_type<EnumT>::type>(t)&0xFF)
383 };
384 };
385
386 template<class EnumT, EnumT t>
387 constexpr typename to_array<EnumT, t, 8u>::const_element_type to_array<EnumT, t, 8>::value;
388 template<class EnumT, EnumT t>
389 constexpr typename to_array<EnumT, t, 7u>::const_element_type to_array<EnumT, t, 7>::value;
390 template<class EnumT, EnumT t>
391 constexpr typename to_array<EnumT, t, 6u>::const_element_type to_array<EnumT, t, 6>::value;
392 template<class EnumT, EnumT t>
393 constexpr typename to_array<EnumT, t, 5u>::const_element_type to_array<EnumT, t, 5>::value;
394 template<class EnumT, EnumT t>
395 constexpr typename to_array<EnumT, t, 4u>::const_element_type to_array<EnumT, t, 4>::value;
396 template<class EnumT, EnumT t>
397 constexpr typename to_array<EnumT, t, 3u>::const_element_type to_array<EnumT, t, 3>::value;
398 template<class EnumT, EnumT t>
399 constexpr typename to_array<EnumT, t, 2u>::const_element_type to_array<EnumT, t, 2>::value;
400 template<class EnumT, EnumT t>
401 constexpr typename to_array<EnumT, t, 1u>::const_element_type to_array<EnumT, t, 1>::value;
402
403
404
405
406 namespace tests {
407
408 enum class enum_tags_as_strs1 : uint16_t {
409 e1=to_tag<'0', '0'>::value,
410 e2=to_tag<'1', '2'>::value,
411 e3=to_tag<'3'>::value
412 };
413
414 static_assert((to_array<enum_tags_as_strs1, enum_tags_as_strs1::e1>::tag)==enum_tags_as_strs1::e1, "The two tags must be equal.");
415 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs1, enum_tags_as_strs1::e1>::size), ==, 2);
416 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs1, enum_tags_as_strs1::e1>::value[0]), ==, '0');
417 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs1, enum_tags_as_strs1::e1>::value[1]), ==, '0');
418
419 static_assert((to_array<enum_tags_as_strs1, enum_tags_as_strs1::e2>::tag)==enum_tags_as_strs1::e2, "The two tags must be equal.");
420 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs1, enum_tags_as_strs1::e2>::size), ==, 2);
421 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs1, enum_tags_as_strs1::e2>::value[0]), ==, '1');
422 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs1, enum_tags_as_strs1::e2>::value[1]), ==, '2');
423
424 static_assert((to_array<enum_tags_as_strs1, enum_tags_as_strs1::e3>::tag)==enum_tags_as_strs1::e3, "The two tags must be equal.");
425 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs1, enum_tags_as_strs1::e3>::size), ==, 1);
426 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs1, enum_tags_as_strs1::e3>::value[0]), ==, '3');
427
428 enum class enum_tags_as_strs2 : uint64_t {
429 e8=to_tag<'2', '.', '7', '1', '8', '2', '8', '1'>::value,
430 e7=to_tag<'1', '2', '3', '4', '5', '6', '7'>::value,
431 e6=to_tag<'1', '2', '3', '4', '5', '6'>::value,
432 e5=to_tag<'1', '2', '3', '4', '5'>::value,
433 e4=to_tag<'1', '2', '3', '4'>::value,
434 e3=to_tag<'3', '1', '4'>::value,
435 e2=to_tag<'3', '1'>::value,
436 e1=to_tag<'3'>::value
437 };
438
439 static_assert((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e8>::tag)==enum_tags_as_strs2::e8, "The two tags must be equal.");
440 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e8>::size), ==, 8);
441 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e8>::value[0]), ==, '2');
442 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e8>::value[1]), ==, '.');
443 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e8>::value[2]), ==, '7');
444 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e8>::value[3]), ==, '1');
445 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e8>::value[4]), ==, '8');
446 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e8>::value[5]), ==, '2');
447 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e8>::value[6]), ==, '8');
448 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e8>::value[7]), ==, '1');
449 static_assert((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e7>::tag)==enum_tags_as_strs2::e7, "The two tags must be equal.");
450 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e7>::size), ==, 7);
451 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e7>::value[0]), ==, '1');
452 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e7>::value[1]), ==, '2');
453 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e7>::value[2]), ==, '3');
454 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e7>::value[3]), ==, '4');
455 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e7>::value[4]), ==, '5');
456 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e7>::value[5]), ==, '6');
457 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e7>::value[6]), ==, '7');
458 static_assert((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e6>::tag)==enum_tags_as_strs2::e6, "The two tags must be equal.");
459 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e6>::size), ==, 6);
460 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e6>::value[0]), ==, '1');
461 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e6>::value[1]), ==, '2');
462 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e6>::value[2]), ==, '3');
463 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e6>::value[3]), ==, '4');
464 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e6>::value[4]), ==, '5');
465 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e6>::value[5]), ==, '6');
466 static_assert((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e5>::tag)==enum_tags_as_strs2::e5, "The two tags must be equal.");
467 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e5>::size), ==, 5);
468 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e5>::value[0]), ==, '1');
469 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e5>::value[1]), ==, '2');
470 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e5>::value[2]), ==, '3');
471 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e5>::value[3]), ==, '4');
472 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e5>::value[4]), ==, '5');
473 static_assert((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e4>::tag)==enum_tags_as_strs2::e4, "The two tags must be equal.");
474 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e4>::size), ==, 4);
475 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e4>::value[0]), ==, '1');
476 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e4>::value[1]), ==, '2');
477 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e4>::value[2]), ==, '3');
478 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e4>::value[3]), ==, '4');
479 static_assert((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e3>::tag)==enum_tags_as_strs2::e3, "The two tags must be equal.");
480 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e3>::size), ==, 3);
481 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e3>::value[0]), ==, '3');
482 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e3>::value[1]), ==, '1');
483 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e3>::value[2]), ==, '4');
484 static_assert((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e2>::tag)==enum_tags_as_strs2::e2, "The two tags must be equal.");
485 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e2>::size), ==, 2);
486 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e2>::value[0]), ==, '3');
487 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e2>::value[1]), ==, '1');
488 static_assert((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e1>::tag)==enum_tags_as_strs2::e1, "The two tags must be equal.");
489 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e1>::size), ==, 1);
490 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e2>::value[0]), ==, '3');
491
492 }
493
494 }
495
496 } }
497
498 #endif