Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:41:57

0001 
0002 #ifndef BOOST_MPL_STRING_HPP_INCLUDED
0003 #define BOOST_MPL_STRING_HPP_INCLUDED
0004 
0005 // Copyright Eric Niebler 2009
0006 //
0007 // Distributed under the Boost Software License, Version 1.0.
0008 // (See accompanying file LICENSE_1_0.txt or copy at
0009 // http://www.boost.org/LICENSE_1_0.txt)
0010 //
0011 // See http://www.boost.org/libs/mpl for documentation.
0012 
0013 // $Id: string.hpp 49239 2009-04-01 09:10:26Z eric_niebler $
0014 // $Date: 2009-04-01 02:10:26 -0700 (Wed, 1 Apr 2009) $
0015 // $Revision: 49239 $
0016 //
0017 // Thanks to:
0018 //   Dmitry Goncharov for porting this to the Sun compiler
0019 
0020 #include <boost/config.hpp>
0021 #include <boost/detail/workaround.hpp>
0022 #include <boost/predef/other/endian.h>
0023 #include <boost/mpl/limits/string.hpp>
0024 #include <boost/mpl/if.hpp>
0025 #include <boost/mpl/char.hpp>
0026 #include <boost/mpl/copy.hpp>
0027 #include <boost/mpl/size.hpp>
0028 #include <boost/mpl/empty.hpp>
0029 #include <boost/mpl/assert.hpp>
0030 #include <boost/mpl/size_t.hpp>
0031 #include <boost/mpl/begin_end.hpp>
0032 #include <boost/mpl/joint_view.hpp>
0033 #include <boost/mpl/insert_range.hpp>
0034 #include <boost/mpl/back_inserter.hpp>
0035 #include <boost/mpl/front_inserter.hpp>
0036 #include <boost/mpl/iterator_range.hpp>
0037 #include <boost/preprocessor/arithmetic/dec.hpp>
0038 #include <boost/preprocessor/arithmetic/add.hpp>
0039 #include <boost/preprocessor/arithmetic/div.hpp>
0040 #include <boost/preprocessor/punctuation/comma_if.hpp>
0041 #include <boost/preprocessor/repetition/repeat.hpp>
0042 #include <boost/preprocessor/repetition/enum_params.hpp>
0043 #include <boost/preprocessor/repetition/repeat_from_to.hpp>
0044 #include <boost/preprocessor/repetition/enum_shifted_params.hpp>
0045 #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
0046 #include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
0047 
0048 #include <iterator> // for bidirectional_iterator_tag
0049 #include <climits>
0050 
0051 namespace boost { namespace mpl
0052 {
0053     #define BOOST_MPL_STRING_MAX_PARAMS                                                             \
0054       BOOST_PP_DIV(BOOST_PP_ADD(BOOST_MPL_LIMIT_STRING_SIZE, 3), 4)
0055 
0056     // Low-level bit-twiddling is done by macros. Any implementation-defined behavior of
0057     // multi-character literals should be localized to these macros.
0058 
0059     #define BOOST_MPL_MULTICHAR_LENGTH(c)                                                           \
0060       (std::size_t)((c<CHAR_MIN) ? 4 : ((c>0xffffff)+(c>0xffff)+(c>0xff)+1))
0061 
0062     #if BOOST_ENDIAN_LITTLE_BYTE && defined(__SUNPRO_CC)
0063 
0064         #define BOOST_MPL_MULTICHAR_AT(c,i)                                                         \
0065           (char)(0xff&((unsigned)(c)>>(8*(std::size_t)(i))))
0066 
0067         #define BOOST_MPL_MULTICHAR_PUSH_BACK(c,i)                                                  \
0068           ((((unsigned char)(i))<<(BOOST_MPL_MULTICHAR_LENGTH(c)*8))|(unsigned)(c))
0069 
0070         #define BOOST_MPL_MULTICHAR_PUSH_FRONT(c,i)                                                 \
0071           (((unsigned)(c)<<8)|(unsigned char)(i))
0072 
0073         #define BOOST_MPL_MULTICHAR_POP_BACK(c)                                                     \
0074           (((1<<((BOOST_MPL_MULTICHAR_LENGTH(c)-1)*8))-1)&(unsigned)(c))
0075 
0076         #define BOOST_MPL_MULTICHAR_POP_FRONT(c)                                                    \
0077           ((unsigned)(c)>>8)
0078 
0079     #else
0080 
0081         #define BOOST_MPL_MULTICHAR_AT(c,i)                                                         \
0082           (char)(0xff&((unsigned)(c)>>(8*(BOOST_MPL_MULTICHAR_LENGTH(c)-(std::size_t)(i)-1))))
0083 
0084         #define BOOST_MPL_MULTICHAR_PUSH_BACK(c,i)                                                  \
0085           (((unsigned)(c)<<8)|(unsigned char)(i))
0086 
0087         #define BOOST_MPL_MULTICHAR_PUSH_FRONT(c,i)                                                 \
0088           ((((unsigned char)(i))<<(BOOST_MPL_MULTICHAR_LENGTH(c)*8))|(unsigned)(c))
0089 
0090         #define BOOST_MPL_MULTICHAR_POP_BACK(c)                                                     \
0091           ((unsigned)(c)>>8)
0092 
0093         #define BOOST_MPL_MULTICHAR_POP_FRONT(c)                                                    \
0094           (((1<<((BOOST_MPL_MULTICHAR_LENGTH(c)-1)*8))-1)&(unsigned)(c))
0095 
0096     #endif
0097 
0098     struct string_tag;
0099     struct string_iterator_tag;
0100 
0101     template<BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_MPL_STRING_MAX_PARAMS, int C, 0)>
0102     struct string;
0103 
0104     template<typename Sequence, int I, int J>
0105     struct string_iterator;
0106 
0107     template<typename Sequence>
0108     struct sequence_tag;
0109 
0110     template<typename Tag>
0111     struct size_impl;
0112 
0113     template<>
0114     struct size_impl<mpl::string_tag>
0115     {
0116         template<typename Sequence>
0117         struct apply;
0118 
0119         #define M0(z, n, data)                                                                      \
0120         + BOOST_MPL_MULTICHAR_LENGTH(BOOST_PP_CAT(C,n))
0121 
0122         #define M1(z, n, data)                                                                      \
0123         template<BOOST_PP_ENUM_PARAMS_Z(z, n, int C)>                                               \
0124         struct apply<mpl::string<BOOST_PP_ENUM_PARAMS_Z(z, n, C)> >                                 \
0125           : mpl::size_t<(0 BOOST_PP_REPEAT_ ## z(n, M0, ~))>                                        \
0126         {};
0127 
0128         BOOST_PP_REPEAT_FROM_TO(1, BOOST_PP_INC(BOOST_MPL_STRING_MAX_PARAMS), M1, ~)
0129         #undef M0
0130         #undef M1
0131     };
0132 
0133     template<>
0134     struct size_impl<mpl::string_tag>::apply<mpl::string<> >
0135       : mpl::size_t<0>
0136     {};
0137 
0138     template<typename Tag>
0139     struct begin_impl;
0140 
0141     template<>
0142     struct begin_impl<mpl::string_tag>
0143     {
0144         template<typename Sequence>
0145         struct apply
0146         {
0147             typedef mpl::string_iterator<Sequence, 0, 0> type;
0148         };
0149     };
0150 
0151     template<typename Tag>
0152     struct end_impl;
0153 
0154     template<>
0155     struct end_impl<mpl::string_tag>
0156     {
0157         template<typename Sequence>
0158         struct apply;
0159 
0160         #define M0(z,n,data)                                                                        \
0161         template<BOOST_PP_ENUM_PARAMS_Z(z, n, int C)>                                               \
0162         struct apply<mpl::string<BOOST_PP_ENUM_PARAMS_Z(z, n, C)> >                                 \
0163         {                                                                                           \
0164             typedef mpl::string_iterator<mpl::string<BOOST_PP_ENUM_PARAMS_Z(z, n, C)>, n, 0> type;  \
0165         };
0166 
0167         BOOST_PP_REPEAT_FROM_TO(1, BOOST_PP_INC(BOOST_MPL_STRING_MAX_PARAMS), M0, ~)
0168         #undef M0
0169     };
0170 
0171     template<>
0172     struct end_impl<mpl::string_tag>::apply<mpl::string<> >
0173     {
0174         typedef mpl::string_iterator<mpl::string<>, 0, 0> type;
0175     };
0176 
0177     template<typename Tag>
0178     struct push_back_impl;
0179 
0180     template<>
0181     struct push_back_impl<mpl::string_tag>
0182     {
0183         template<typename Sequence, typename Value, bool B = (4==BOOST_MPL_MULTICHAR_LENGTH(Sequence::back_))>
0184         struct apply
0185         {
0186             BOOST_MPL_ASSERT_MSG(
0187                 (BOOST_MPL_LIMIT_STRING_SIZE != mpl::size<Sequence>::type::value)
0188               , PUSH_BACK_FAILED_MPL_STRING_IS_FULL
0189               , (Sequence)
0190             );
0191             // If the above assertion didn't fire, then the string is sparse.
0192             // Repack the string and retry the push_back
0193             typedef
0194                 typename mpl::push_back<
0195                     typename mpl::copy<
0196                         Sequence
0197                       , mpl::back_inserter<mpl::string<> >
0198                     >::type
0199                   , Value
0200                 >::type
0201             type;
0202         };
0203 
0204         template<typename Value>
0205         struct apply<mpl::string<>, Value, false>
0206         {
0207             typedef mpl::string<(char)Value::value> type;
0208         };
0209 
0210         #define M0(z,n,data)                                                                        \
0211         template<BOOST_PP_ENUM_PARAMS_Z(z, n, int C), typename Value>                               \
0212         struct apply<mpl::string<BOOST_PP_ENUM_PARAMS_Z(z, n, C)>, Value, false>                    \
0213         {                                                                                           \
0214             typedef                                                                                 \
0215                 mpl::string<                                                                        \
0216                     BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_DEC(n), C)                                   \
0217                     BOOST_PP_COMMA_IF(BOOST_PP_DEC(n))                                              \
0218                     ((unsigned)BOOST_PP_CAT(C,BOOST_PP_DEC(n))>0xffffff)                            \
0219                     ?BOOST_PP_CAT(C,BOOST_PP_DEC(n))                                                \
0220                     :BOOST_MPL_MULTICHAR_PUSH_BACK(BOOST_PP_CAT(C,BOOST_PP_DEC(n)), Value::value)   \
0221                   , ((unsigned)BOOST_PP_CAT(C,BOOST_PP_DEC(n))>0xffffff)                            \
0222                     ?(char)Value::value                                                             \
0223                     :0                                                                              \
0224                 >                                                                                   \
0225             type;                                                                                   \
0226         };
0227 
0228         BOOST_PP_REPEAT_FROM_TO(1, BOOST_MPL_STRING_MAX_PARAMS, M0, ~)
0229         #undef M0
0230 
0231         template<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, int C), typename Value>
0232         struct apply<mpl::string<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)>, Value, false>
0233         {
0234             typedef
0235                 mpl::string<
0236                     BOOST_PP_ENUM_PARAMS(BOOST_PP_DEC(BOOST_MPL_STRING_MAX_PARAMS), C)
0237                   , BOOST_MPL_MULTICHAR_PUSH_BACK(BOOST_PP_CAT(C,BOOST_PP_DEC(BOOST_MPL_STRING_MAX_PARAMS)), Value::value)
0238                 >
0239             type;
0240         };
0241     };
0242 
0243     template<typename Tag>
0244     struct has_push_back_impl;
0245 
0246     template<>
0247     struct has_push_back_impl<mpl::string_tag>
0248     {
0249         template<typename Sequence>
0250         struct apply
0251           : mpl::true_
0252         {};
0253     };
0254 
0255     template<typename Tag>
0256     struct pop_back_impl;
0257 
0258     template<>
0259     struct pop_back_impl<mpl::string_tag>
0260     {
0261         template<typename Sequence>
0262         struct apply;
0263 
0264         #define M0(z,n,data)                                                                        \
0265         template<BOOST_PP_ENUM_PARAMS_Z(z, n, int C)>                                               \
0266         struct apply<mpl::string<BOOST_PP_ENUM_PARAMS_Z(z, n, C)> >                                 \
0267         {                                                                                           \
0268             BOOST_MPL_ASSERT_MSG((C0 != 0), POP_BACK_FAILED_MPL_STRING_IS_EMPTY, (mpl::string<>));  \
0269             typedef                                                                                 \
0270                 mpl::string<                                                                        \
0271                     BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_DEC(n), C)                                   \
0272                     BOOST_PP_COMMA_IF(BOOST_PP_DEC(n))                                              \
0273                     BOOST_MPL_MULTICHAR_POP_BACK(BOOST_PP_CAT(C,BOOST_PP_DEC(n)))                   \
0274                 >                                                                                   \
0275             type;                                                                                   \
0276         };
0277 
0278         BOOST_PP_REPEAT_FROM_TO(1, BOOST_PP_INC(BOOST_MPL_STRING_MAX_PARAMS), M0, ~)
0279         #undef M0
0280     };
0281 
0282     template<typename Tag>
0283     struct has_pop_back_impl;
0284 
0285     template<>
0286     struct has_pop_back_impl<mpl::string_tag>
0287     {
0288         template<typename Sequence>
0289         struct apply
0290           : mpl::true_
0291         {};
0292     };
0293 
0294     template<typename Tag>
0295     struct push_front_impl;
0296 
0297     template<>
0298     struct push_front_impl<mpl::string_tag>
0299     {
0300         template<typename Sequence, typename Value, bool B = (4==BOOST_MPL_MULTICHAR_LENGTH(Sequence::front_))>
0301         struct apply
0302         {
0303             BOOST_MPL_ASSERT_MSG(
0304                 (BOOST_MPL_LIMIT_STRING_SIZE != mpl::size<Sequence>::type::value)
0305               , PUSH_FRONT_FAILED_MPL_STRING_IS_FULL
0306               , (Sequence)
0307             );
0308             // If the above assertion didn't fire, then the string is sparse.
0309             // Repack the string and retry the push_front.
0310             typedef
0311                 typename mpl::push_front<
0312                     typename mpl::reverse_copy<
0313                         Sequence
0314                       , mpl::front_inserter<string<> >
0315                     >::type
0316                   , Value
0317                 >::type
0318             type;
0319         };
0320 
0321         #if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
0322         template<typename Value>
0323         struct apply<mpl::string<>, Value, false>
0324         {
0325             typedef mpl::string<(char)Value::value> type;
0326         };
0327         #endif
0328 
0329         #define M0(z,n,data)                                                                        \
0330         template<BOOST_PP_ENUM_PARAMS_Z(z, n, int C), typename Value>                               \
0331         struct apply<mpl::string<BOOST_PP_ENUM_PARAMS_Z(z, n, C)>, Value, true>                     \
0332         {                                                                                           \
0333             typedef                                                                                 \
0334                 mpl::string<                                                                        \
0335                     (char)Value::value                                                              \
0336                     BOOST_PP_ENUM_TRAILING_PARAMS_Z(z, n, C)                                        \
0337                 >                                                                                   \
0338             type;                                                                                   \
0339         };
0340 
0341         BOOST_PP_REPEAT_FROM_TO(1, BOOST_MPL_STRING_MAX_PARAMS, M0, ~)
0342         #undef M0
0343 
0344         template<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, int C), typename Value>
0345         struct apply<mpl::string<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)>, Value, false>
0346         {
0347             typedef
0348                 mpl::string<
0349                     BOOST_MPL_MULTICHAR_PUSH_FRONT(C0, Value::value)
0350                   , BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)
0351                 >
0352             type0;
0353 
0354             #if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
0355             typedef
0356                 typename mpl::if_<
0357                     mpl::empty<mpl::string<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)> >
0358                   , mpl::string<(char)Value::value>
0359                   , type0
0360                 >::type
0361             type;
0362             #else
0363             typedef type0 type;
0364             #endif
0365         };
0366     };
0367 
0368     template<typename Tag>
0369     struct has_push_front_impl;
0370 
0371     template<>
0372     struct has_push_front_impl<mpl::string_tag>
0373     {
0374         template<typename Sequence>
0375         struct apply
0376           : mpl::true_
0377         {};
0378     };
0379 
0380     template<typename Tag>
0381     struct pop_front_impl;
0382 
0383     template<>
0384     struct pop_front_impl<mpl::string_tag>
0385     {
0386         template<typename Sequence, bool B = (1==BOOST_MPL_MULTICHAR_LENGTH(Sequence::front_))>
0387         struct apply;
0388 
0389         #define M0(z,n,data)                                                                        \
0390         template<BOOST_PP_ENUM_PARAMS_Z(z, n, int C)>                                               \
0391         struct apply<mpl::string<BOOST_PP_ENUM_PARAMS_Z(z, n, C)>, true>                            \
0392         {                                                                                           \
0393             BOOST_MPL_ASSERT_MSG((C0 != 0), POP_FRONT_FAILED_MPL_STRING_IS_EMPTY, (mpl::string<>)); \
0394             typedef                                                                                 \
0395                 mpl::string<BOOST_PP_ENUM_SHIFTED_PARAMS_Z(z, n, C)>                                \
0396             type;                                                                                   \
0397         };
0398 
0399         BOOST_PP_REPEAT_FROM_TO(1, BOOST_MPL_STRING_MAX_PARAMS, M0, ~)
0400         #undef M0
0401 
0402         template<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, int C)>
0403         struct apply<mpl::string<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)>, false>
0404         {
0405             typedef
0406                 mpl::string<
0407                     BOOST_MPL_MULTICHAR_POP_FRONT(C0)
0408                   , BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)
0409                 >
0410             type;
0411         };
0412     };
0413 
0414     template<typename Tag>
0415     struct has_pop_front_impl;
0416 
0417     template<>
0418     struct has_pop_front_impl<mpl::string_tag>
0419     {
0420         template<typename Sequence>
0421         struct apply
0422           : mpl::true_
0423         {};
0424     };
0425 
0426     template<typename Tag>
0427     struct insert_range_impl;
0428 
0429     template<>
0430     struct insert_range_impl<mpl::string_tag>
0431     {
0432         template<typename Sequence, typename Pos, typename Range>
0433         struct apply
0434           : mpl::copy<
0435                 mpl::joint_view<
0436                     mpl::iterator_range<
0437                         mpl::string_iterator<Sequence, 0, 0>
0438                       , Pos
0439                     >
0440                   , mpl::joint_view<
0441                         Range
0442                       , mpl::iterator_range<
0443                             Pos
0444                           , typename mpl::end<Sequence>::type
0445                         >
0446                     >
0447                 >
0448               , mpl::back_inserter<mpl::string<> >
0449             >
0450         {};
0451     };
0452 
0453     template<typename Tag>
0454     struct insert_impl;
0455 
0456     template<>
0457     struct insert_impl<mpl::string_tag>
0458     {
0459         template<typename Sequence, typename Pos, typename Value>
0460         struct apply
0461           : mpl::insert_range<Sequence, Pos, mpl::string<(char)Value::value> >
0462         {};
0463     };
0464 
0465     template<typename Tag>
0466     struct erase_impl;
0467 
0468     template<>
0469     struct erase_impl<mpl::string_tag>
0470     {
0471         template<typename Sequence, typename First, typename Last>
0472         struct apply
0473           : mpl::copy<
0474                 mpl::joint_view<
0475                     mpl::iterator_range<
0476                         mpl::string_iterator<Sequence, 0, 0>
0477                       , First
0478                     >
0479                   , mpl::iterator_range<
0480                         typename mpl::if_na<Last, typename mpl::next<First>::type>::type
0481                       , typename mpl::end<Sequence>::type
0482                     >
0483                 >
0484               , mpl::back_inserter<mpl::string<> >
0485             >
0486         {};
0487     };
0488 
0489     template<typename Tag>
0490     struct clear_impl;
0491 
0492     template<>
0493     struct clear_impl<mpl::string_tag>
0494     {
0495         template<typename>
0496         struct apply
0497         {
0498             typedef mpl::string<> type;
0499         };
0500     };
0501 
0502     #define M0(z, n, data)                                                                            \
0503     template<BOOST_PP_ENUM_PARAMS_Z(z, BOOST_MPL_STRING_MAX_PARAMS, int C), int J>                    \
0504     struct string_iterator<mpl::string<BOOST_PP_ENUM_PARAMS_Z(z, BOOST_MPL_STRING_MAX_PARAMS, C)>, n, J> \
0505     {                                                                                                 \
0506         enum { eomc_ = (BOOST_MPL_MULTICHAR_LENGTH(BOOST_PP_CAT(C, n)) == J + 1) };                   \
0507         typedef mpl::string<BOOST_PP_ENUM_PARAMS_Z(z, BOOST_MPL_STRING_MAX_PARAMS, C)> string;        \
0508         typedef std::bidirectional_iterator_tag category;                                             \
0509         typedef                                                                                       \
0510             mpl::string_iterator<string, n + eomc_, eomc_ ? 0 : J + 1>                                \
0511         next;                                                                                         \
0512         typedef                                                                                       \
0513             mpl::string_iterator<string, n, J - 1>                                                    \
0514         prior;                                                                                        \
0515         typedef mpl::char_<BOOST_MPL_MULTICHAR_AT(BOOST_PP_CAT(C, n), J)> type;                       \
0516     };                                                                                                \
0517     template<BOOST_PP_ENUM_PARAMS_Z(z, BOOST_MPL_STRING_MAX_PARAMS, int C)>                           \
0518     struct string_iterator<mpl::string<BOOST_PP_ENUM_PARAMS_Z(z, BOOST_MPL_STRING_MAX_PARAMS, C)>, n, 0> \
0519     {                                                                                                 \
0520         enum { eomc_ = (BOOST_MPL_MULTICHAR_LENGTH(BOOST_PP_CAT(C, n)) == 1) };                       \
0521         typedef mpl::string<BOOST_PP_ENUM_PARAMS_Z(z, BOOST_MPL_STRING_MAX_PARAMS, C)> string;        \
0522         typedef std::bidirectional_iterator_tag category;                                             \
0523         typedef                                                                                       \
0524             mpl::string_iterator<string, n + eomc_, !eomc_>                                           \
0525         next;                                                                                         \
0526         typedef                                                                                       \
0527             mpl::string_iterator<                                                                     \
0528                 string                                                                                \
0529               , n - 1                                                                                 \
0530               , BOOST_MPL_MULTICHAR_LENGTH(BOOST_PP_CAT(C, BOOST_PP_DEC(n))) - 1                      \
0531             >                                                                                         \
0532         prior;                                                                                        \
0533         typedef mpl::char_<BOOST_MPL_MULTICHAR_AT(BOOST_PP_CAT(C, n), 0)> type;                       \
0534     };
0535 
0536     BOOST_PP_REPEAT(BOOST_MPL_STRING_MAX_PARAMS, M0, ~)
0537     #undef M0
0538 
0539     template<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, int C)>
0540     struct string
0541     {
0542         /// INTERNAL ONLY
0543         enum
0544         {
0545             front_  = C0
0546           , back_   = BOOST_PP_CAT(C, BOOST_PP_DEC(BOOST_MPL_STRING_MAX_PARAMS))
0547         };
0548 
0549         typedef char        value_type;
0550         typedef string      type;
0551         typedef string_tag  tag;
0552     };
0553 
0554     namespace aux_
0555     {
0556         template<typename It, typename End>
0557         struct next_unless
0558           : mpl::next<It>
0559         {};
0560 
0561         template<typename End>
0562         struct next_unless<End, End>
0563         {
0564             typedef End type;
0565         };
0566 
0567         template<typename It, typename End>
0568         struct deref_unless
0569           : mpl::deref<It>
0570         {};
0571 
0572         template<typename End>
0573         struct deref_unless<End, End>
0574         {
0575             typedef mpl::char_<'\0'> type;
0576         };
0577     }
0578 
0579     template<typename Sequence>
0580     struct c_str
0581     {
0582         typedef typename mpl::end<Sequence>::type iend;
0583         typedef typename mpl::begin<Sequence>::type i0;
0584         #define M0(z, n, data)                                                                      \
0585         typedef                                                                                     \
0586             typename mpl::aux_::next_unless<BOOST_PP_CAT(i, n), iend>::type                         \
0587         BOOST_PP_CAT(i, BOOST_PP_INC(n));
0588         BOOST_PP_REPEAT(BOOST_MPL_LIMIT_STRING_SIZE, M0, ~)
0589         #undef M0
0590 
0591         typedef c_str type;
0592         static typename Sequence::value_type const value[BOOST_MPL_LIMIT_STRING_SIZE+1];
0593     };
0594 
0595     template<typename Sequence>
0596     typename Sequence::value_type const c_str<Sequence>::value[BOOST_MPL_LIMIT_STRING_SIZE+1] =
0597     {
0598         #define M0(z, n, data)                                                                      \
0599         mpl::aux_::deref_unless<BOOST_PP_CAT(i, n), iend>::type::value,
0600         BOOST_PP_REPEAT(BOOST_MPL_LIMIT_STRING_SIZE, M0, ~)
0601         #undef M0
0602         '\0'
0603     };
0604 
0605 }} // namespace boost
0606 
0607 #endif // BOOST_MPL_STRING_HPP_INCLUDED