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