libjmmcg  release_579_6_g8cffd
A C++ library containing an eclectic mix of useful, advanced components.
enum_as_char_array.hpp
Go to the documentation of this file.
1 #ifndef LIBJMMCG_CORE_ENUM_AS_CHAR_ARRAY_HPP
2 #define LIBJMMCG_CORE_ENUM_AS_CHAR_ARRAY_HPP
3 
4 /******************************************************************************
5 ** Copyright © 2015 by J.M.McGuiness, libjmmcg@hussar.me.uk
6 **
7 ** This library is free software; you can redistribute it and/or
8 ** modify it under the terms of the GNU Lesser General Public
9 ** License as published by the Free Software Foundation; either
10 ** version 2.1 of the License, or (at your option) any later version.
11 **
12 ** This library is distributed in the hope that it will be useful,
13 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 ** Lesser General Public License for more details.
16 **
17 ** You should have received a copy of the GNU Lesser General Public
18 ** License along with this library; if not, write to the Free Software
19 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21 
22 #include "config.h"
23 
24 #include <boost/mpl/assert.hpp>
25 
26 #include <array>
27 #include <cstdint>
28 #include <type_traits>
29 
30 namespace jmmcg { namespace LIBJMMCG_VER_NAMESPACE {
31 
32 /// Construct enum-tag values from a sequence of chars, and extract from the tag-value the string that was encoded.
33 namespace enum_tags {
34 
35 /// A function to convert a string-literal or C-style string or array of chars into one of these magic enum-tags-as-a-string.
36 template<class EnumT, std::size_t N>
37 constexpr inline typename std::enable_if<N>=sizeof(EnumT), EnumT>::type
38 convert(const char (&s)[N]) noexcept(true) {
39  using u_t=typename std::underlying_type<EnumT>::type;
40 
41  std::size_t n=sizeof(EnumT);
42  u_t t=0;
43  do {
44  t+=static_cast<u_t>(s[n-1])<<((n-1)*8);
45  } while (--n>0);
46  return static_cast<EnumT>(t);
47 }
48 
49 /// A function to convert, even faster, a correctly sized array of chars into one of these magic enum-tags-as-a-string.
50 /**
51  * \param s A correctly sized array of chars means that the number of characters must exactly match the number of chars in the size of the underlying type of the enum.
52  */
53 template<class EnumT>
54 constexpr inline EnumT
55 convert(std::array<char, sizeof(EnumT)> const &s) noexcept(true) {
56  using u_t=typename std::underlying_type<EnumT>::type;
57  union conv_t {
58  std::array<char, sizeof(EnumT)> str;
59  u_t t;
60 
61  conv_t() noexcept(true)
62  : str() {}
63  } conv;
64  conv.str=s;
65  return static_cast<EnumT>(conv.t);
66 }
67 
68 namespace mpl {
69 
70 namespace private_ {
71 
72 template<char c1, char c2='\0', char c3='\0', char c4='\0', char c5='\0', char c6='\0', char c7='\0', char c8='\0'>
74  using type=std::uint64_t;
75 };
76 template<char c1, char c2, char c3, char c4, char c5, char c6, char c7>
77 struct select_underlying_type<c1, c2, c3, c4, c5, c6, c7, '\0'> {
78  using type=std::uint64_t;
79 };
80 template<char c1, char c2, char c3, char c4, char c5, char c6>
81 struct select_underlying_type<c1, c2, c3, c4, c5, c6, '\0', '\0'> {
82  using type=std::uint64_t;
83 };
84 template<char c1, char c2, char c3, char c4, char c5>
85 struct select_underlying_type<c1, c2, c3, c4, c5, '\0', '\0', '\0'> {
86  using type=std::uint64_t;
87 };
88 template<char c1, char c2, char c3, char c4>
89 struct select_underlying_type<c1, c2, c3, c4, '\0', '\0', '\0', '\0'> {
90  using type=std::uint32_t;
91 };
92 template<char c1, char c2, char c3>
93 struct select_underlying_type<c1, c2, c3, '\0', '\0', '\0', '\0', '\0'> {
94  using type=std::uint32_t;
95 };
96 template<char c1, char c2>
97 struct select_underlying_type<c1, c2, '\0', '\0', '\0', '\0', '\0', '\0'> {
98  using type=std::uint16_t;
99 };
100 template<char c1>
101 struct select_underlying_type<c1, '\0', '\0', '\0', '\0', '\0', '\0', '\0'> {
102  using type=std::uint8_t;
103 };
104 
105 template<
106  class EnumT,
107  EnumT t,
108  typename std::underlying_type<EnumT>::type i=(static_cast<typename std::underlying_type<EnumT>::type>(t)>>8),
109  bool is_digit=(static_cast<bool>(i))
110 >
111 struct count_digits {
112  enum : typename std::underlying_type<EnumT>::type {
113  value=1+count_digits<EnumT, t, (i>>8)>::value
114  };
115 };
116 template<
117  class EnumT,
118  EnumT t,
119  typename std::underlying_type<EnumT>::type i
120 >
121 struct count_digits<EnumT, t, i, false> {
122  enum : typename std::underlying_type<EnumT>::type {
123  value=1
124  };
125 };
126 
127 }
128 
129 /// Convert the chars into a suitable enum-tag.
130 /**
131  \see to_array
132 */
133 template<char c1, char c2='\0', char c3='\0', char c4='\0', char c5='\0', char c6='\0', char c7='\0', char c8='\0'>
134 struct to_tag {
135  using element_type=typename private_::select_underlying_type<c1, c2, c3, c4, c5, c6, c7, c8>::type;
136 
137  enum : element_type {
138  value=
139  (static_cast<element_type>(c8)<<56)
140  +(static_cast<element_type>(c7)<<48)
141  +(static_cast<element_type>(c6)<<40)
142  +(static_cast<element_type>(c5)<<32)
143  +(static_cast<element_type>(c4)<<24)
144  +(static_cast<element_type>(c3)<<16)
145  +(static_cast<element_type>(c2)<<8)
146  +static_cast<element_type>(c1)
147  };
148 };
149 template<char c1, char c2, char c3, char c4, char c5, char c6, char c7>
150 struct to_tag<c1, c2, c3, c4, c5, c6, c7, '\0'> {
152 
153  enum : element_type {
154  value=
155  (static_cast<element_type>(c7)<<48)
156  +(static_cast<element_type>(c6)<<40)
157  +(static_cast<element_type>(c5)<<32)
158  +(static_cast<element_type>(c4)<<24)
159  +(static_cast<element_type>(c3)<<16)
160  +(static_cast<element_type>(c2)<<8)
161  +static_cast<element_type>(c1)
162  };
163 };
164 template<char c1, char c2, char c3, char c4, char c5, char c6>
165 struct to_tag<c1, c2, c3, c4, c5, c6, '\0', '\0'> {
167 
168  enum : element_type {
169  value=
170  (static_cast<element_type>(c6)<<40)
171  +(static_cast<element_type>(c5)<<32)
172  +(static_cast<element_type>(c4)<<24)
173  +(static_cast<element_type>(c3)<<16)
174  +(static_cast<element_type>(c2)<<8)
175  +static_cast<element_type>(c1)
176  };
177 };
178 template<char c1, char c2, char c3, char c4, char c5>
179 struct to_tag<c1, c2, c3, c4, c5, '\0', '\0', '\0'> {
181 
182  enum : element_type {
183  value=
184  (static_cast<element_type>(c5)<<32)
185  +(static_cast<element_type>(c4)<<24)
186  +(static_cast<element_type>(c3)<<16)
187  +(static_cast<element_type>(c2)<<8)
188  +static_cast<element_type>(c1)
189  };
190 };
191 template<char c1, char c2, char c3, char c4>
192 struct to_tag<c1, c2, c3, c4, '\0', '\0', '\0', '\0'> {
194 
195  enum : element_type {
196  value=
197  (static_cast<element_type>(c4)<<24)
198  +(static_cast<element_type>(c3)<<16)
199  +(static_cast<element_type>(c2)<<8)
200  +static_cast<element_type>(c1)
201  };
202 };
203 template<char c1, char c2, char c3>
204 struct to_tag<c1, c2, c3, '\0', '\0', '\0', '\0', '\0'> {
206 
207  enum : element_type {
208  value=
209  (static_cast<element_type>(c3)<<16)
210  +(static_cast<element_type>(c2)<<8)
211  +static_cast<element_type>(c1)
212  };
213 };
214 template<char c1, char c2>
215 struct to_tag<c1, c2, '\0', '\0', '\0', '\0', '\0', '\0'> {
217 
218  enum : element_type {
219  value=
220  (static_cast<element_type>(c2)<<8)
221  +static_cast<element_type>(c1)
222  };
223 };
224 template<char c1>
225 struct to_tag<c1, '\0', '\0', '\0', '\0', '\0', '\0', '\0'> {
227 
228  enum : element_type {
229  value=static_cast<element_type>(c1)
230  };
231 };
232 
233 /// Convert the suitably-created enum-tag into a char array.
234 /**
235  \see to_tag
236 */
237 template<
238  class EnumT,
239  EnumT t,
240  unsigned num_digits=private_::count_digits<EnumT, t>::value
241 >
242 struct to_array;
243 template<
244  class EnumT,
245  EnumT t
246 >
247 struct to_array<EnumT, t, 8u> {
248  enum : std::size_t {
249  size=private_::count_digits<EnumT, t>::value ///< The size of the extracted string, excluding the terminal NULL.
250  };
251  enum : typename std::underlying_type<EnumT>::type {
252  value_as_int=static_cast<typename std::underlying_type<EnumT>::type>(t)
253  };
254  using const_element_type=const char [size+1]; ///< The type of the const char-array of the extracted string.
255  using element_type=char [size+1]; ///< The type of the char-array of the extracted string.
256  using element_type_no_null=char [size]; ///< The type of the char-array of the extracted string without the terminating NULL.
257  static inline constexpr EnumT tag=t; ///< The enum-tag associated the with the encoded string.
258  /// The array of chars extracted from the enum-tag as a NULL-terminated string.
259  static inline constexpr const_element_type value={
260  static_cast<char>(static_cast<typename std::underlying_type<EnumT>::type>(t)&0xFF),
261  static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>8)&0xFF),
262  static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>16)&0xFF),
263  static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>24)&0xFF),
264  static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>32)&0xFF),
265  static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>40)&0xFF),
266  static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>48)&0xFF),
267  static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>56)&0xFF),
268  '\0'
269  };
270 };
271 template<
272  class EnumT,
273  EnumT t
274 >
275 struct to_array<EnumT, t, 7u> {
276  enum : std::size_t {
277  size=private_::count_digits<EnumT, t>::value ///< The size of the extracted string, excluding the terminal NULL.
278  };
279  enum : typename std::underlying_type<EnumT>::type {
280  value_as_int=static_cast<typename std::underlying_type<EnumT>::type>(t)
281  };
282  using const_element_type=const char [size+1]; ///< The type of the const char-array of the extracted string.
283  using element_type=char [size+1]; ///< The type of the char-array of the extracted string.
284  using element_type_no_null=char [size]; ///< The type of the char-array of the extracted string without the terminating NULL.
285  static inline constexpr EnumT tag=t; ///< The enum-tag associated the with the encoded string.
286  /// The array of chars extracted from the enum-tag as a NULL-terminated string.
287  static inline constexpr const_element_type value={
288  static_cast<char>(static_cast<typename std::underlying_type<EnumT>::type>(t)&0xFF),
289  static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>8)&0xFF),
290  static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>16)&0xFF),
291  static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>24)&0xFF),
292  static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>32)&0xFF),
293  static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>40)&0xFF),
294  static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>48)&0xFF),
295  '\0'
296  };
297 };
298 template<
299  class EnumT,
300  EnumT t
301 >
302 struct to_array<EnumT, t, 6u> {
303  enum : std::size_t {
304  size=private_::count_digits<EnumT, t>::value ///< The size of the extracted string, excluding the terminal NULL.
305  };
306  enum : typename std::underlying_type<EnumT>::type {
307  value_as_int=static_cast<typename std::underlying_type<EnumT>::type>(t)
308  };
309  using const_element_type=const char [size+1]; ///< The type of the const char-array of the extracted string.
310  using element_type=char [size+1]; ///< The type of the char-array of the extracted string.
311  using element_type_no_null=char [size]; ///< The type of the char-array of the extracted string without the terminating NULL.
312  static inline constexpr EnumT tag=t; ///< The enum-tag associated the with the encoded string.
313  /// The array of chars extracted from the enum-tag as a NULL-terminated string.
314  static inline constexpr const_element_type value={
315  static_cast<char>(static_cast<typename std::underlying_type<EnumT>::type>(t)&0xFF),
316  static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>8)&0xFF),
317  static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>16)&0xFF),
318  static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>24)&0xFF),
319  static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>32)&0xFF),
320  static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>40)&0xFF),
321  '\0'
322  };
323 };
324 template<
325  class EnumT,
326  EnumT t
327 >
328 struct to_array<EnumT, t, 5u> {
329  enum : std::size_t {
330  size=private_::count_digits<EnumT, t>::value ///< The size of the extracted string, excluding the terminal NULL.
331  };
332  enum : typename std::underlying_type<EnumT>::type {
333  value_as_int=static_cast<typename std::underlying_type<EnumT>::type>(t)
334  };
335  using const_element_type=const char [size+1]; ///< The type of the const char-array of the extracted string.
336  using element_type=char [size+1]; ///< The type of the char-array of the extracted string.
337  using element_type_no_null=char [size]; ///< The type of the char-array of the extracted string without the terminating NULL.
338  static inline constexpr EnumT tag=t; ///< The enum-tag associated the with the encoded string.
339  /// The array of chars extracted from the enum-tag as a NULL-terminated string.
340  static inline constexpr const_element_type value={
341  static_cast<char>(static_cast<typename std::underlying_type<EnumT>::type>(t)&0xFF),
342  static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>8)&0xFF),
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)>>24)&0xFF),
345  static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>32)&0xFF),
346  '\0'
347  };
348 };
349 template<
350  class EnumT,
351  EnumT t
352 >
353 struct to_array<EnumT, t, 4u> {
354  enum : std::size_t {
355  size=private_::count_digits<EnumT, t>::value ///< The size of the extracted string, excluding the terminal NULL.
356  };
357  enum : typename std::underlying_type<EnumT>::type {
358  value_as_int=static_cast<typename std::underlying_type<EnumT>::type>(t)
359  };
360  using const_element_type=const char [size+1]; ///< The type of the const char-array of the extracted string.
361  using element_type=char [size+1]; ///< The type of the char-array of the extracted string.
362  using element_type_no_null=char [size]; ///< The type of the char-array of the extracted string without the terminating NULL.
363  static inline constexpr EnumT tag=t; ///< The enum-tag associated the with the encoded string.
364  /// The array of chars extracted from the enum-tag as a NULL-terminated string.
365  /// The array of chars extracted from the enum-tag as a NULL-terminated string.
366  static inline constexpr const_element_type value={
367  static_cast<char>(static_cast<typename std::underlying_type<EnumT>::type>(t)&0xFF),
368  static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>8)&0xFF),
369  static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>16)&0xFF),
370  static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>24)&0xFF),
371  '\0'
372  };
373 };
374 template<
375  class EnumT,
376  EnumT t
377 >
378 struct to_array<EnumT, t, 3u> {
379  enum : std::size_t {
380  size=private_::count_digits<EnumT, t>::value ///< The size of the extracted string, excluding the terminal NULL.
381  };
382  enum : typename std::underlying_type<EnumT>::type {
383  value_as_int=static_cast<typename std::underlying_type<EnumT>::type>(t)
384  };
385  using const_element_type=const char [size+1]; ///< The type of the const char-array of the extracted string.
386  using element_type=char [size+1]; ///< The type of the char-array of the extracted string.
387  using element_type_no_null=char [size]; ///< The type of the char-array of the extracted string without the terminating NULL.
388  static inline constexpr EnumT tag=t; ///< The enum-tag associated the with the encoded string.
389  /// The array of chars extracted from the enum-tag as a NULL-terminated string.
390  /// The array of chars extracted from the enum-tag as a NULL-terminated string.
391  static inline constexpr const_element_type value={
392  static_cast<char>(static_cast<typename std::underlying_type<EnumT>::type>(t)&0xFF),
393  static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>8)&0xFF),
394  static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>16)&0xFF),
395  '\0'
396  };
397 };
398 template<
399  class EnumT,
400  EnumT t
401 >
402 struct to_array<EnumT, t, 2u> {
403  enum : std::size_t {
404  size=private_::count_digits<EnumT, t>::value ///< The size of the extracted string, excluding the terminal NULL.
405  };
406  enum : typename std::underlying_type<EnumT>::type {
407  value_as_int=static_cast<typename std::underlying_type<EnumT>::type>(t)
408  };
409  using const_element_type=const char [size+1]; ///< The type of the const char-array of the extracted string.
410  using element_type=char [size+1]; ///< The type of the char-array of the extracted string.
411  using element_type_no_null=char [size]; ///< The type of the char-array of the extracted string without the terminating NULL.
412  static inline constexpr EnumT tag=t; ///< The enum-tag associated the with the encoded string.
413  /// The array of chars extracted from the enum-tag as a NULL-terminated string.
414  /// The array of chars extracted from the enum-tag as a NULL-terminated string.
415  static inline constexpr const_element_type value={
416  static_cast<char>(static_cast<typename std::underlying_type<EnumT>::type>(t)&0xFF),
417  static_cast<char>((static_cast<typename std::underlying_type<EnumT>::type>(t)>>8)&0xFF),
418  '\0'
419  };
420 };
421 template<
422  class EnumT,
423  EnumT t
424 >
425 struct to_array<EnumT, t, 1u> {
426  enum : std::size_t {
427  size=1 ///< The size of the extracted string, excluding the terminal NULL.
428  };
429  enum : typename std::underlying_type<EnumT>::type {
430  value_as_int=static_cast<typename std::underlying_type<EnumT>::type>(t)
431  };
432  using const_element_type=const char [size+1]; ///< The type of the const char-array of the extracted string.
433  using element_type=char [size+1]; ///< The type of the char-array of the extracted string.
434  using element_type_no_null=char [size]; ///< The type of the char-array of the extracted string without the terminating NULL.
435  static inline constexpr EnumT tag=t; ///< The enum-tag associated the with the encoded string.
436  /// The array of chars extracted from the enum-tag as a NULL-terminated string.
437  /// The array of chars extracted from the enum-tag as a NULL-terminated string.
438  static inline constexpr const_element_type value={
439  static_cast<char>(static_cast<typename std::underlying_type<EnumT>::type>(t)&0xFF),
440  '\0'
441  };
442 };
443 
444 /**
445  \test Verify the operation of the enum-as-char-arrays.
446 */
447 namespace tests {
448 
450  e1=to_tag<'0', '0'>::value,
451  e2=to_tag<'1', '2'>::value,
452  e3=to_tag<'3'>::value
453 };
454 
455 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.");
456 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs1, enum_tags_as_strs1::e1>::size), ==, 2);
457 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs1, enum_tags_as_strs1::e1>::value[0]), ==, '0');
458 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs1, enum_tags_as_strs1::e1>::value[1]), ==, '0');
459 
460 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.");
461 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs1, enum_tags_as_strs1::e2>::size), ==, 2);
462 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs1, enum_tags_as_strs1::e2>::value[0]), ==, '1');
463 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs1, enum_tags_as_strs1::e2>::value[1]), ==, '2');
464 
465 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.");
466 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs1, enum_tags_as_strs1::e3>::size), ==, 1);
467 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs1, enum_tags_as_strs1::e3>::value[0]), ==, '3');
468 
470  e8=to_tag<'2', '.', '7', '1', '8', '2', '8', '1'>::value,
471  e7=to_tag<'1', '2', '3', '4', '5', '6', '7'>::value,
472  e6=to_tag<'1', '2', '3', '4', '5', '6'>::value,
473  e5=to_tag<'1', '2', '3', '4', '5'>::value,
474  e4=to_tag<'1', '2', '3', '4'>::value,
475  e3=to_tag<'3', '1', '4'>::value,
476  e2=to_tag<'3', '1'>::value,
477  e1=to_tag<'3'>::value
478 };
479 
480 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.");
481 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e8>::size), ==, 8);
482 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e8>::value[0]), ==, '2');
483 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e8>::value[1]), ==, '.');
484 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e8>::value[2]), ==, '7');
485 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e8>::value[3]), ==, '1');
486 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e8>::value[4]), ==, '8');
487 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e8>::value[5]), ==, '2');
488 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e8>::value[6]), ==, '8');
489 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e8>::value[7]), ==, '1');
490 
491 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.");
492 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e7>::size), ==, 7);
493 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e7>::value[0]), ==, '1');
494 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e7>::value[1]), ==, '2');
495 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e7>::value[2]), ==, '3');
496 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e7>::value[3]), ==, '4');
497 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e7>::value[4]), ==, '5');
498 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e7>::value[5]), ==, '6');
499 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e7>::value[6]), ==, '7');
500 
501 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.");
502 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e6>::size), ==, 6);
503 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e6>::value[0]), ==, '1');
504 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e6>::value[1]), ==, '2');
505 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e6>::value[2]), ==, '3');
506 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e6>::value[3]), ==, '4');
507 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e6>::value[4]), ==, '5');
508 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e6>::value[5]), ==, '6');
509 
510 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.");
511 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e5>::size), ==, 5);
512 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e5>::value[0]), ==, '1');
513 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e5>::value[1]), ==, '2');
514 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e5>::value[2]), ==, '3');
515 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e5>::value[3]), ==, '4');
516 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e5>::value[4]), ==, '5');
517 
518 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.");
519 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e4>::size), ==, 4);
520 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e4>::value[0]), ==, '1');
521 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e4>::value[1]), ==, '2');
522 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e4>::value[2]), ==, '3');
523 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e4>::value[3]), ==, '4');
524 
525 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.");
526 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e3>::size), ==, 3);
527 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e3>::value[0]), ==, '3');
528 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e3>::value[1]), ==, '1');
529 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e3>::value[2]), ==, '4');
530 
531 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.");
532 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e2>::size), ==, 2);
533 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e2>::value[0]), ==, '3');
534 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e2>::value[1]), ==, '1');
535 
536 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.");
537 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e1>::size), ==, 1);
538 BOOST_MPL_ASSERT_RELATION((to_array<enum_tags_as_strs2, enum_tags_as_strs2::e2>::value[0]), ==, '3');
539 
540 }
541 
542 }
543 
544 } } }
545 
546 #endif