]> git.lyx.org Git - lyx.git/blob - boost/boost/mpl/string.hpp
How about if we write a script to do some of this and stop doing it
[lyx.git] / boost / boost / mpl / string.hpp
1 \r
2 #ifndef BOOST_MPL_STRING_HPP_INCLUDED\r
3 #define BOOST_MPL_STRING_HPP_INCLUDED\r
4 \r
5 // Copyright Eric Niebler 2009\r
6 //\r
7 // Distributed under the Boost Software License, Version 1.0.\r
8 // (See accompanying file LICENSE_1_0.txt or copy at\r
9 // http://www.boost.org/LICENSE_1_0.txt)\r
10 //\r
11 // See http://www.boost.org/libs/mpl for documentation.\r
12 \r
13 // $Id: string.hpp 49239 2009-04-01 09:10:26Z eric_niebler $\r
14 // $Date: 2009-04-01 02:10:26 -0700 (Wed, 1 Apr 2009) $\r
15 // $Revision: 49239 $\r
16 //\r
17 // Thanks to:\r
18 //   Dmitry Goncharov for porting this to the Sun compiler\r
19 \r
20 #include <boost/config.hpp>\r
21 #include <boost/detail/workaround.hpp>\r
22 #include <boost/detail/endian.hpp>\r
23 #include <boost/mpl/limits/string.hpp>\r
24 #include <boost/mpl/if.hpp>\r
25 #include <boost/mpl/char.hpp>\r
26 #include <boost/mpl/copy.hpp>\r
27 #include <boost/mpl/size.hpp>\r
28 #include <boost/mpl/empty.hpp>\r
29 #include <boost/mpl/assert.hpp>\r
30 #include <boost/mpl/size_t.hpp>\r
31 #include <boost/mpl/begin_end.hpp>\r
32 #include <boost/mpl/joint_view.hpp>\r
33 #include <boost/mpl/insert_range.hpp>\r
34 #include <boost/mpl/back_inserter.hpp>\r
35 #include <boost/mpl/front_inserter.hpp>\r
36 #include <boost/mpl/iterator_range.hpp>\r
37 #include <boost/preprocessor/arithmetic/dec.hpp>\r
38 #include <boost/preprocessor/arithmetic/add.hpp>\r
39 #include <boost/preprocessor/arithmetic/div.hpp>\r
40 #include <boost/preprocessor/punctuation/comma_if.hpp>\r
41 #include <boost/preprocessor/repetition/repeat.hpp>\r
42 #include <boost/preprocessor/repetition/enum_params.hpp>\r
43 #include <boost/preprocessor/repetition/repeat_from_to.hpp>\r
44 #include <boost/preprocessor/repetition/enum_shifted_params.hpp>\r
45 #include <boost/preprocessor/repetition/enum_trailing_params.hpp>\r
46 #include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>\r
47 \r
48 #include <iterator> // for bidirectional_iterator_tag\r
49 #include <climits>\r
50 \r
51 namespace boost { namespace mpl\r
52 {\r
53     #define BOOST_MPL_STRING_MAX_PARAMS                                                             \\r
54       BOOST_PP_DIV(BOOST_PP_ADD(BOOST_MPL_LIMIT_STRING_SIZE, 3), 4)\r
55 \r
56     // Low-level bit-twiddling is done by macros. Any implementation-defined behavior of\r
57     // multi-character literals should be localized to these macros.\r
58 \r
59     #define BOOST_MPL_MULTICHAR_LENGTH(c)                                                           \\r
60       (std::size_t)((c<CHAR_MIN) ? 4 : ((c>0xffffff)+(c>0xffff)+(c>0xff)+1))\r
61 \r
62     #if defined(BOOST_LITTLE_ENDIAN) && defined(__SUNPRO_CC)\r
63 \r
64         #define BOOST_MPL_MULTICHAR_AT(c,i)                                                         \\r
65           (char)(0xff&((unsigned)(c)>>(8*(std::size_t)(i))))\r
66 \r
67         #define BOOST_MPL_MULTICHAR_PUSH_BACK(c,i)                                                  \\r
68           ((((unsigned char)(i))<<(BOOST_MPL_MULTICHAR_LENGTH(c)*8))|(unsigned)(c))\r
69 \r
70         #define BOOST_MPL_MULTICHAR_PUSH_FRONT(c,i)                                                 \\r
71           (((unsigned)(c)<<8)|(unsigned char)(i))\r
72 \r
73         #define BOOST_MPL_MULTICHAR_POP_BACK(c)                                                     \\r
74           (((1<<((BOOST_MPL_MULTICHAR_LENGTH(c)-1)*8))-1)&(unsigned)(c))\r
75 \r
76         #define BOOST_MPL_MULTICHAR_POP_FRONT(c)                                                    \\r
77           ((unsigned)(c)>>8)\r
78 \r
79     #else\r
80 \r
81         #define BOOST_MPL_MULTICHAR_AT(c,i)                                                         \\r
82           (char)(0xff&((unsigned)(c)>>(8*(BOOST_MPL_MULTICHAR_LENGTH(c)-(std::size_t)(i)-1))))\r
83 \r
84         #define BOOST_MPL_MULTICHAR_PUSH_BACK(c,i)                                                  \\r
85           (((unsigned)(c)<<8)|(unsigned char)(i))\r
86 \r
87         #define BOOST_MPL_MULTICHAR_PUSH_FRONT(c,i)                                                 \\r
88           ((((unsigned char)(i))<<(BOOST_MPL_MULTICHAR_LENGTH(c)*8))|(unsigned)(c))\r
89 \r
90         #define BOOST_MPL_MULTICHAR_POP_BACK(c)                                                     \\r
91           ((unsigned)(c)>>8)\r
92 \r
93         #define BOOST_MPL_MULTICHAR_POP_FRONT(c)                                                    \\r
94           (((1<<((BOOST_MPL_MULTICHAR_LENGTH(c)-1)*8))-1)&(unsigned)(c))\r
95 \r
96     #endif\r
97 \r
98     struct string_tag;\r
99     struct string_iterator_tag;\r
100 \r
101     template<BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_MPL_STRING_MAX_PARAMS, int C, 0)>\r
102     struct string;\r
103 \r
104     template<typename Sequence, int I, int J>\r
105     struct string_iterator;\r
106 \r
107     template<typename Sequence>\r
108     struct sequence_tag;\r
109 \r
110     template<typename Tag>\r
111     struct size_impl;\r
112 \r
113     template<>\r
114     struct size_impl<mpl::string_tag>\r
115     {\r
116         template<typename Sequence>\r
117         struct apply;\r
118 \r
119         #define M0(z, n, data)                                                                      \\r
120         + BOOST_MPL_MULTICHAR_LENGTH(BOOST_PP_CAT(C,n))\r
121 \r
122         #define M1(z, n, data)                                                                      \\r
123         template<BOOST_PP_ENUM_PARAMS_Z(z, n, int C)>                                               \\r
124         struct apply<mpl::string<BOOST_PP_ENUM_PARAMS_Z(z, n, C)> >                                 \\r
125           : mpl::size_t<(0 BOOST_PP_REPEAT_ ## z(n, M0, ~))>                                        \\r
126         {};\r
127 \r
128         BOOST_PP_REPEAT_FROM_TO(1, BOOST_PP_INC(BOOST_MPL_STRING_MAX_PARAMS), M1, ~)\r
129         #undef M0\r
130         #undef M1\r
131     };\r
132 \r
133     template<>\r
134     struct size_impl<mpl::string_tag>::apply<mpl::string<> >\r
135       : mpl::size_t<0>\r
136     {};\r
137 \r
138     template<typename Tag>\r
139     struct begin_impl;\r
140 \r
141     template<>\r
142     struct begin_impl<mpl::string_tag>\r
143     {\r
144         template<typename Sequence>\r
145         struct apply\r
146         {\r
147             typedef mpl::string_iterator<Sequence, 0, 0> type;\r
148         };\r
149     };\r
150 \r
151     template<typename Tag>\r
152     struct end_impl;\r
153 \r
154     template<>\r
155     struct end_impl<mpl::string_tag>\r
156     {\r
157         template<typename Sequence>\r
158         struct apply;\r
159 \r
160         #define M0(z,n,data)                                                                        \\r
161         template<BOOST_PP_ENUM_PARAMS_Z(z, n, int C)>                                               \\r
162         struct apply<mpl::string<BOOST_PP_ENUM_PARAMS_Z(z, n, C)> >                                 \\r
163         {                                                                                           \\r
164             typedef mpl::string_iterator<mpl::string<BOOST_PP_ENUM_PARAMS_Z(z, n, C)>, n, 0> type;  \\r
165         };\r
166 \r
167         BOOST_PP_REPEAT_FROM_TO(1, BOOST_PP_INC(BOOST_MPL_STRING_MAX_PARAMS), M0, ~)\r
168         #undef M0\r
169     };\r
170 \r
171     template<>\r
172     struct end_impl<mpl::string_tag>::apply<mpl::string<> >\r
173     {\r
174         typedef mpl::string_iterator<mpl::string<>, 0, 0> type;\r
175     };\r
176 \r
177     template<typename Tag>\r
178     struct push_back_impl;\r
179 \r
180     template<>\r
181     struct push_back_impl<mpl::string_tag>\r
182     {\r
183         template<typename Sequence, typename Value, bool B = (4==BOOST_MPL_MULTICHAR_LENGTH(Sequence::back_))>\r
184         struct apply\r
185         {\r
186             BOOST_MPL_ASSERT_MSG(\r
187                 (BOOST_MPL_LIMIT_STRING_SIZE != mpl::size<Sequence>::type::value)\r
188               , PUSH_BACK_FAILED_MPL_STRING_IS_FULL\r
189               , (Sequence)\r
190             );\r
191             // If the above assertion didn't fire, then the string is sparse.\r
192             // Repack the string and retry the push_back\r
193             typedef\r
194                 typename mpl::push_back<\r
195                     typename mpl::copy<\r
196                         Sequence\r
197                       , mpl::back_inserter<mpl::string<> >\r
198                     >::type\r
199                   , Value\r
200                 >::type\r
201             type;\r
202         };\r
203 \r
204         template<typename Value>\r
205         struct apply<mpl::string<>, Value, false>\r
206         {\r
207             typedef mpl::string<(char)Value::value> type;\r
208         };\r
209 \r
210         #define M0(z,n,data)                                                                        \\r
211         template<BOOST_PP_ENUM_PARAMS_Z(z, n, int C), typename Value>                               \\r
212         struct apply<mpl::string<BOOST_PP_ENUM_PARAMS_Z(z, n, C)>, Value, false>                    \\r
213         {                                                                                           \\r
214             typedef                                                                                 \\r
215                 mpl::string<                                                                        \\r
216                     BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_DEC(n), C)                                   \\r
217                     BOOST_PP_COMMA_IF(BOOST_PP_DEC(n))                                              \\r
218                     ((unsigned)BOOST_PP_CAT(C,BOOST_PP_DEC(n))>0xffffff)                            \\r
219                     ?BOOST_PP_CAT(C,BOOST_PP_DEC(n))                                                \\r
220                     :BOOST_MPL_MULTICHAR_PUSH_BACK(BOOST_PP_CAT(C,BOOST_PP_DEC(n)), Value::value)   \\r
221                   , ((unsigned)BOOST_PP_CAT(C,BOOST_PP_DEC(n))>0xffffff)                            \\r
222                     ?(char)Value::value                                                             \\r
223                     :0                                                                              \\r
224                 >                                                                                   \\r
225             type;                                                                                   \\r
226         };\r
227 \r
228         BOOST_PP_REPEAT_FROM_TO(1, BOOST_MPL_STRING_MAX_PARAMS, M0, ~)\r
229         #undef M0\r
230 \r
231         template<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, int C), typename Value>\r
232         struct apply<mpl::string<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)>, Value, false>\r
233         {\r
234             typedef\r
235                 mpl::string<\r
236                     BOOST_PP_ENUM_PARAMS(BOOST_PP_DEC(BOOST_MPL_STRING_MAX_PARAMS), C)\r
237                   , BOOST_MPL_MULTICHAR_PUSH_BACK(BOOST_PP_CAT(C,BOOST_PP_DEC(BOOST_MPL_STRING_MAX_PARAMS)), Value::value)\r
238                 >\r
239             type;\r
240         };\r
241     };\r
242 \r
243     template<typename Tag>\r
244     struct pop_back_impl;\r
245 \r
246     template<>\r
247     struct pop_back_impl<mpl::string_tag>\r
248     {\r
249         template<typename Sequence>\r
250         struct apply;\r
251 \r
252         #define M0(z,n,data)                                                                        \\r
253         template<BOOST_PP_ENUM_PARAMS_Z(z, n, int C)>                                               \\r
254         struct apply<mpl::string<BOOST_PP_ENUM_PARAMS_Z(z, n, C)> >                                 \\r
255         {                                                                                           \\r
256             BOOST_MPL_ASSERT_MSG((C0 != 0), POP_BACK_FAILED_MPL_STRING_IS_EMPTY, (mpl::string<>));  \\r
257             typedef                                                                                 \\r
258                 mpl::string<                                                                        \\r
259                     BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_DEC(n), C)                                   \\r
260                     BOOST_PP_COMMA_IF(BOOST_PP_DEC(n))                                              \\r
261                     BOOST_MPL_MULTICHAR_POP_BACK(BOOST_PP_CAT(C,BOOST_PP_DEC(n)))                   \\r
262                 >                                                                                   \\r
263             type;                                                                                   \\r
264         };\r
265 \r
266         BOOST_PP_REPEAT_FROM_TO(1, BOOST_PP_INC(BOOST_MPL_STRING_MAX_PARAMS), M0, ~)\r
267         #undef M0\r
268     };\r
269 \r
270     template<typename Tag>\r
271     struct push_front_impl;\r
272 \r
273     template<>\r
274     struct push_front_impl<mpl::string_tag>\r
275     {\r
276         template<typename Sequence, typename Value, bool B = (4==BOOST_MPL_MULTICHAR_LENGTH(Sequence::front_))>\r
277         struct apply\r
278         {\r
279             BOOST_MPL_ASSERT_MSG(\r
280                 (BOOST_MPL_LIMIT_STRING_SIZE != mpl::size<Sequence>::type::value)\r
281               , PUSH_FRONT_FAILED_MPL_STRING_IS_FULL\r
282               , (Sequence)\r
283             );\r
284             // If the above assertion didn't fire, then the string is sparse.\r
285             // Repack the string and retry the push_front.\r
286             typedef\r
287                 typename mpl::push_front<\r
288                     typename mpl::reverse_copy<\r
289                         Sequence\r
290                       , mpl::front_inserter<string<> >\r
291                     >::type\r
292                   , Value\r
293                 >::type\r
294             type;\r
295         };\r
296 \r
297         #if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))\r
298         template<typename Value>\r
299         struct apply<mpl::string<>, Value, false>\r
300         {\r
301             typedef mpl::string<(char)Value::value> type;\r
302         };\r
303         #endif\r
304 \r
305         #define M0(z,n,data)                                                                        \\r
306         template<BOOST_PP_ENUM_PARAMS_Z(z, n, int C), typename Value>                               \\r
307         struct apply<mpl::string<BOOST_PP_ENUM_PARAMS_Z(z, n, C)>, Value, true>                     \\r
308         {                                                                                           \\r
309             typedef                                                                                 \\r
310                 mpl::string<                                                                        \\r
311                     (char)Value::value                                                              \\r
312                     BOOST_PP_ENUM_TRAILING_PARAMS_Z(z, n, C)                                        \\r
313                 >                                                                                   \\r
314             type;                                                                                   \\r
315         };\r
316 \r
317         BOOST_PP_REPEAT_FROM_TO(1, BOOST_MPL_STRING_MAX_PARAMS, M0, ~)\r
318         #undef M0\r
319 \r
320         template<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, int C), typename Value>\r
321         struct apply<mpl::string<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)>, Value, false>\r
322         {\r
323             typedef\r
324                 mpl::string<\r
325                     BOOST_MPL_MULTICHAR_PUSH_FRONT(C0, Value::value)\r
326                   , BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)\r
327                 >\r
328             type0;\r
329 \r
330             #if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))\r
331             typedef\r
332                 typename mpl::if_<\r
333                     mpl::empty<mpl::string<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)> >\r
334                   , mpl::string<(char)Value::value>\r
335                   , type0\r
336                 >::type\r
337             type;\r
338             #else\r
339             typedef type0 type;\r
340             #endif\r
341         };\r
342     };\r
343 \r
344     template<typename Tag>\r
345     struct pop_front_impl;\r
346 \r
347     template<>\r
348     struct pop_front_impl<mpl::string_tag>\r
349     {\r
350         template<typename Sequence, bool B = (1==BOOST_MPL_MULTICHAR_LENGTH(Sequence::front_))>\r
351         struct apply;\r
352 \r
353         #define M0(z,n,data)                                                                        \\r
354         template<BOOST_PP_ENUM_PARAMS_Z(z, n, int C)>                                               \\r
355         struct apply<mpl::string<BOOST_PP_ENUM_PARAMS_Z(z, n, C)>, true>                            \\r
356         {                                                                                           \\r
357             BOOST_MPL_ASSERT_MSG((C0 != 0), POP_FRONT_FAILED_MPL_STRING_IS_EMPTY, (mpl::string<>)); \\r
358             typedef                                                                                 \\r
359                 mpl::string<BOOST_PP_ENUM_SHIFTED_PARAMS_Z(z, n, C)>                                \\r
360             type;                                                                                   \\r
361         };\r
362 \r
363         BOOST_PP_REPEAT_FROM_TO(1, BOOST_MPL_STRING_MAX_PARAMS, M0, ~)\r
364         #undef M0\r
365 \r
366         template<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, int C)>\r
367         struct apply<mpl::string<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)>, false>\r
368         {\r
369             typedef\r
370                 mpl::string<\r
371                     BOOST_MPL_MULTICHAR_POP_FRONT(C0)\r
372                   , BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)\r
373                 >\r
374             type;\r
375         };\r
376     };\r
377 \r
378     template<typename Tag>\r
379     struct insert_range_impl;\r
380 \r
381     template<>\r
382     struct insert_range_impl<mpl::string_tag>\r
383     {\r
384         template<typename Sequence, typename Pos, typename Range>\r
385         struct apply\r
386           : mpl::copy<\r
387                 mpl::joint_view<\r
388                     mpl::iterator_range<\r
389                         mpl::string_iterator<Sequence, 0, 0>\r
390                       , Pos\r
391                     >\r
392                   , mpl::joint_view<\r
393                         Range\r
394                       , mpl::iterator_range<\r
395                             Pos\r
396                           , typename mpl::end<Sequence>::type\r
397                         >\r
398                     >\r
399                 >\r
400               , mpl::back_inserter<mpl::string<> >\r
401             >\r
402         {};\r
403     };\r
404 \r
405     template<typename Tag>\r
406     struct insert_impl;\r
407 \r
408     template<>\r
409     struct insert_impl<mpl::string_tag>\r
410     {\r
411         template<typename Sequence, typename Pos, typename Value>\r
412         struct apply\r
413           : mpl::insert_range<Sequence, Pos, mpl::string<(char)Value::value> >\r
414         {};\r
415     };\r
416 \r
417     template<typename Tag>\r
418     struct erase_impl;\r
419 \r
420     template<>\r
421     struct erase_impl<mpl::string_tag>\r
422     {\r
423         template<typename Sequence, typename First, typename Last>\r
424         struct apply\r
425           : mpl::copy<\r
426                 mpl::joint_view<\r
427                     mpl::iterator_range<\r
428                         mpl::string_iterator<Sequence, 0, 0>\r
429                       , First\r
430                     >\r
431                   , mpl::iterator_range<\r
432                         typename mpl::if_na<Last, typename mpl::next<First>::type>::type\r
433                       , typename mpl::end<Sequence>::type\r
434                     >\r
435                 >\r
436               , mpl::back_inserter<mpl::string<> >\r
437             >\r
438         {};\r
439     };\r
440 \r
441     template<typename Tag>\r
442     struct clear_impl;\r
443 \r
444     template<>\r
445     struct clear_impl<mpl::string_tag>\r
446     {\r
447         template<typename>\r
448         struct apply\r
449         {\r
450             typedef mpl::string<> type;\r
451         };\r
452     };\r
453 \r
454     #define M0(z, n, data)                                                                            \\r
455     template<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, int C), int J>                         \\r
456     struct string_iterator<mpl::string<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)>, n, J>   \\r
457     {                                                                                                 \\r
458         enum { eomc_ = (BOOST_MPL_MULTICHAR_LENGTH(BOOST_PP_CAT(C, n)) == J + 1) };                   \\r
459         typedef mpl::string<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)> string;             \\r
460         typedef std::bidirectional_iterator_tag category;                                             \\r
461         typedef                                                                                       \\r
462             mpl::string_iterator<string, n + eomc_, eomc_ ? 0 : J + 1>                                \\r
463         next;                                                                                         \\r
464         typedef                                                                                       \\r
465             mpl::string_iterator<string, n, J - 1>                                                    \\r
466         prior;                                                                                        \\r
467         typedef mpl::char_<BOOST_MPL_MULTICHAR_AT(BOOST_PP_CAT(C, n), J)> type;                       \\r
468     };                                                                                                \\r
469     template<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, int C)>                                \\r
470     struct string_iterator<mpl::string<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)>, n, 0>   \\r
471     {                                                                                                 \\r
472         enum { eomc_ = (BOOST_MPL_MULTICHAR_LENGTH(BOOST_PP_CAT(C, n)) == 1) };                       \\r
473         typedef mpl::string<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)> string;             \\r
474         typedef std::bidirectional_iterator_tag category;                                             \\r
475         typedef                                                                                       \\r
476             mpl::string_iterator<string, n + eomc_, !eomc_>                                           \\r
477         next;                                                                                         \\r
478         typedef                                                                                       \\r
479             mpl::string_iterator<                                                                     \\r
480                 string                                                                                \\r
481               , n - 1                                                                                 \\r
482               , BOOST_MPL_MULTICHAR_LENGTH(BOOST_PP_CAT(C, BOOST_PP_DEC(n))) - 1                      \\r
483             >                                                                                         \\r
484         prior;                                                                                        \\r
485         typedef mpl::char_<BOOST_MPL_MULTICHAR_AT(BOOST_PP_CAT(C, n), 0)> type;                       \\r
486     };\r
487 \r
488     BOOST_PP_REPEAT(BOOST_MPL_STRING_MAX_PARAMS, M0, ~)\r
489     #undef M0\r
490 \r
491     template<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, int C)>\r
492     struct string\r
493     {\r
494         /// INTERNAL ONLY\r
495         enum\r
496         {\r
497             front_  = C0\r
498           , back_   = BOOST_PP_CAT(C, BOOST_PP_DEC(BOOST_MPL_STRING_MAX_PARAMS))\r
499         };\r
500 \r
501         typedef char        value_type;\r
502         typedef string      type;\r
503         typedef string_tag  tag;\r
504     };\r
505 \r
506     namespace aux_\r
507     {\r
508         template<typename It, typename End>\r
509         struct next_unless\r
510           : mpl::next<It>\r
511         {};\r
512 \r
513         template<typename End>\r
514         struct next_unless<End, End>\r
515         {\r
516             typedef End type;\r
517         };\r
518 \r
519         template<typename It, typename End>\r
520         struct deref_unless\r
521           : mpl::deref<It>\r
522         {};\r
523 \r
524         template<typename End>\r
525         struct deref_unless<End, End>\r
526         {\r
527             typedef mpl::char_<'\0'> type;\r
528         };\r
529     }\r
530 \r
531     template<typename Sequence>\r
532     struct c_str\r
533     {\r
534         typedef typename mpl::end<Sequence>::type iend;\r
535         typedef typename mpl::begin<Sequence>::type i0;\r
536         #define M0(z, n, data)                                                                      \\r
537         typedef                                                                                     \\r
538             typename mpl::aux_::next_unless<BOOST_PP_CAT(i, n), iend>::type                         \\r
539         BOOST_PP_CAT(i, BOOST_PP_INC(n));\r
540         BOOST_PP_REPEAT(BOOST_MPL_LIMIT_STRING_SIZE, M0, ~)\r
541         #undef M0\r
542 \r
543         typedef c_str type;\r
544         static typename Sequence::value_type const value[BOOST_MPL_LIMIT_STRING_SIZE+1];\r
545     };\r
546 \r
547     template<typename Sequence>\r
548     typename Sequence::value_type const c_str<Sequence>::value[BOOST_MPL_LIMIT_STRING_SIZE+1] =\r
549     {\r
550         #define M0(z, n, data)                                                                      \\r
551         mpl::aux_::deref_unless<BOOST_PP_CAT(i, n), iend>::type::value,\r
552         BOOST_PP_REPEAT(BOOST_MPL_LIMIT_STRING_SIZE, M0, ~)\r
553         #undef M0\r
554         '\0'\r
555     };\r
556 \r
557 }} // namespace boost\r
558 \r
559 #endif // BOOST_MPL_STRING_HPP_INCLUDED\r