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
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
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
0057
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
0192
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
0309
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
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 }}
0606
0607 #endif