string.hpp 24 KB

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