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