1 
2 //  (C) Copyright Edward Diener 2011-2015
3 //  Use, modification and distribution are subject to the Boost Software License,
4 //  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
5 //  http://www.boost.org/LICENSE_1_0.txt).
6 
7 #if !defined(BOOST_VMD_DETAIL_SEQUENCE_COMMON_HPP)
8 #define BOOST_VMD_DETAIL_SEQUENCE_COMMON_HPP
9 
10 #include <boost/preprocessor/arithmetic/inc.hpp>
11 #include <boost/preprocessor/array/push_back.hpp>
12 #include <boost/preprocessor/cat.hpp>
13 #include <boost/preprocessor/comparison/equal.hpp>
14 #include <boost/preprocessor/comparison/less_equal.hpp>
15 #include <boost/preprocessor/comparison/not_equal.hpp>
16 #include <boost/preprocessor/control/iif.hpp>
17 #include <boost/preprocessor/control/while.hpp>
18 #include <boost/preprocessor/list/append.hpp>
19 #include <boost/preprocessor/logical/bitor.hpp>
20 #include <boost/preprocessor/punctuation/is_begin_parens.hpp>
21 #include <boost/preprocessor/seq/push_back.hpp>
22 #include <boost/preprocessor/seq/size.hpp>
23 #include <boost/preprocessor/tuple/elem.hpp>
24 #include <boost/preprocessor/tuple/push_back.hpp>
25 #include <boost/preprocessor/tuple/replace.hpp>
26 #include <boost/preprocessor/tuple/size.hpp>
27 #include <boost/vmd/empty.hpp>
28 #include <boost/vmd/identity.hpp>
29 #include <boost/vmd/is_empty.hpp>
30 #include <boost/vmd/is_empty_list.hpp>
31 #include <boost/vmd/detail/array.hpp>
32 #include <boost/vmd/detail/equal_type.hpp>
33 #include <boost/vmd/detail/identifier.hpp>
34 #include <boost/vmd/detail/identifier_type.hpp>
35 #include <boost/vmd/detail/list.hpp>
36 #include <boost/vmd/detail/modifiers.hpp>
37 #include <boost/vmd/detail/mods.hpp>
38 #include <boost/vmd/detail/seq.hpp>
39 #include <boost/vmd/detail/tuple.hpp>
40 
41 #define BOOST_VMD_DETAIL_SEQUENCE_STATE_INPUT_ELEM 0
42 #define BOOST_VMD_DETAIL_SEQUENCE_STATE_RESULT_ELEM 1
43 #define BOOST_VMD_DETAIL_SEQUENCE_STATE_ELEM_ELEM 2
44 #define BOOST_VMD_DETAIL_SEQUENCE_STATE_OUTTYPE_ELEM 3
45 #define BOOST_VMD_DETAIL_SEQUENCE_STATE_FROM_ELEM 4
46 #define BOOST_VMD_DETAIL_SEQUENCE_STATE_TYPES_ELEM 5
47 #define BOOST_VMD_DETAIL_SEQUENCE_STATE_INDEX_ELEM 6
48 
49 #define BOOST_VMD_DETAIL_SEQUENCE_STATE_INPUT(state) \
50     BOOST_PP_TUPLE_ELEM(BOOST_VMD_DETAIL_SEQUENCE_STATE_INPUT_ELEM,state) \
51 /**/
52 
53 #define BOOST_VMD_DETAIL_SEQUENCE_STATE_RESULT(state) \
54     BOOST_PP_TUPLE_ELEM(BOOST_VMD_DETAIL_SEQUENCE_STATE_RESULT_ELEM,state) \
55 /**/
56 
57 #define BOOST_VMD_DETAIL_SEQUENCE_STATE_ELEM(state) \
58         BOOST_PP_TUPLE_ELEM(BOOST_VMD_DETAIL_SEQUENCE_STATE_ELEM_ELEM,state) \
59 /**/
60 
61 #define BOOST_VMD_DETAIL_SEQUENCE_STATE_OUTTYPE(state) \
62         BOOST_PP_TUPLE_ELEM(BOOST_VMD_DETAIL_SEQUENCE_STATE_OUTTYPE_ELEM,state) \
63 /**/
64 
65 #define BOOST_VMD_DETAIL_SEQUENCE_STATE_FROM(state) \
66         BOOST_PP_TUPLE_ELEM(BOOST_VMD_DETAIL_SEQUENCE_STATE_FROM_ELEM,state) \
67 /**/
68 
69 #define BOOST_VMD_DETAIL_SEQUENCE_STATE_IS_RETURN(d,from,number) \
70     BOOST_PP_EQUAL_D \
71         ( \
72         d, \
73         BOOST_PP_TUPLE_ELEM(0,from), \
74         number \
75         ) \
76 /**/
77 
78 #define BOOST_VMD_DETAIL_SEQUENCE_STATE_IS_NO_RETURN(d,from) \
79     BOOST_VMD_DETAIL_SEQUENCE_STATE_IS_RETURN(d,from,BOOST_VMD_DETAIL_MODS_NO_RETURN) \
80 /**/
81 
82 #define BOOST_VMD_DETAIL_SEQUENCE_STATE_IS_EXACT_RETURN(d,from) \
83     BOOST_VMD_DETAIL_SEQUENCE_STATE_IS_RETURN(d,from,BOOST_VMD_DETAIL_MODS_RETURN) \
84 /**/
85 
86 #define BOOST_VMD_DETAIL_SEQUENCE_STATE_IS_GENERAL_RETURN(d,from) \
87     BOOST_VMD_DETAIL_SEQUENCE_STATE_IS_RETURN(d,from,BOOST_VMD_DETAIL_MODS_RETURN_TUPLE) \
88 /**/
89 
90 #define BOOST_VMD_DETAIL_SEQUENCE_STATE_IS_ARRAY_RETURN(d,from) \
91     BOOST_VMD_DETAIL_SEQUENCE_STATE_IS_RETURN(d,from,BOOST_VMD_DETAIL_MODS_RETURN_ARRAY) \
92 /**/
93 
94 #define BOOST_VMD_DETAIL_SEQUENCE_STATE_IS_LIST_RETURN(d,from) \
95     BOOST_VMD_DETAIL_SEQUENCE_STATE_IS_RETURN(d,from,BOOST_VMD_DETAIL_MODS_RETURN_LIST) \
96 /**/
97 
98 #define BOOST_VMD_DETAIL_SEQUENCE_STATE_IS_AFTER(from) \
99     BOOST_PP_EQUAL \
100         ( \
101         BOOST_PP_TUPLE_ELEM(1,from), \
102         BOOST_VMD_DETAIL_MODS_RETURN_AFTER \
103         ) \
104 /**/
105 
106 #define BOOST_VMD_DETAIL_SEQUENCE_STATE_IS_AFTER_D(d,from) \
107     BOOST_PP_EQUAL_D \
108         ( \
109         d, \
110         BOOST_PP_TUPLE_ELEM(1,from), \
111         BOOST_VMD_DETAIL_MODS_RETURN_AFTER \
112         ) \
113 /**/
114 
115 #define BOOST_VMD_DETAIL_SEQUENCE_STATE_TYPES(state) \
116         BOOST_PP_TUPLE_ELEM(BOOST_VMD_DETAIL_SEQUENCE_STATE_TYPES_ELEM,state) \
117 /**/
118 
119 #define BOOST_VMD_DETAIL_SEQUENCE_STATE_INDEX(state) \
120         BOOST_PP_TUPLE_ELEM(BOOST_VMD_DETAIL_SEQUENCE_STATE_INDEX_ELEM,state) \
121 /**/
122 
123 #define BOOST_VMD_DETAIL_SEQUENCE_STATE_RESULT_IS_EMPTY(state) \
124     BOOST_VMD_IS_EMPTY \
125         ( \
126         BOOST_VMD_DETAIL_SEQUENCE_STATE_RESULT(state) \
127         ) \
128 /**/
129 
130 #define BOOST_VMD_DETAIL_SEQUENCE_STATE_RESULT_ADD_FROM_EMPTY(state,data) \
131     (data) \
132 /**/
133 
134 #define BOOST_VMD_DETAIL_SEQUENCE_STATE_RESULT_ADD_TO_SEQ(state,data) \
135     BOOST_PP_SEQ_PUSH_BACK(BOOST_VMD_DETAIL_SEQUENCE_STATE_RESULT(state),data) \
136 /**/
137 
138 #define BOOST_VMD_DETAIL_SEQUENCE_STATE_RESULT_ADD_TO_TUPLE(state,data) \
139     BOOST_PP_TUPLE_PUSH_BACK(BOOST_VMD_DETAIL_SEQUENCE_STATE_RESULT(state),data) \
140 /**/
141 
142 // Array
143 
144 #define BOOST_VMD_DETAIL_SEQUENCE_STATE_RESULT_ADD_BOOST_VMD_TYPE_ARRAY(d,state,data) \
145     BOOST_PP_ARRAY_PUSH_BACK(BOOST_VMD_DETAIL_SEQUENCE_STATE_RESULT(state),data) \
146 /**/
147 
148 // List
149 
150 #define BOOST_VMD_DETAIL_SEQUENCE_STATE_RESULT_ADD_BOOST_VMD_TYPE_LIST(d,state,data) \
151     BOOST_PP_LIST_APPEND_D(d,BOOST_VMD_DETAIL_SEQUENCE_STATE_RESULT(state),(data,BOOST_PP_NIL)) \
152 /**/
153 
154 // Seq
155 
156 #define BOOST_VMD_DETAIL_SEQUENCE_STATE_RESULT_ADD_BOOST_VMD_TYPE_SEQ(d,state,data) \
157     BOOST_PP_IIF \
158          ( \
159          BOOST_VMD_DETAIL_SEQUENCE_STATE_RESULT_IS_EMPTY(state), \
160          BOOST_VMD_DETAIL_SEQUENCE_STATE_RESULT_ADD_FROM_EMPTY, \
161          BOOST_VMD_DETAIL_SEQUENCE_STATE_RESULT_ADD_TO_SEQ \
162          ) \
163      (state,data) \
164 /**/
165 
166 // Tuple
167 
168 #define BOOST_VMD_DETAIL_SEQUENCE_STATE_RESULT_ADD_BOOST_VMD_TYPE_TUPLE(d,state,data) \
169     BOOST_PP_IIF \
170          ( \
171          BOOST_VMD_DETAIL_SEQUENCE_STATE_RESULT_IS_EMPTY(state), \
172          BOOST_VMD_DETAIL_SEQUENCE_STATE_RESULT_ADD_FROM_EMPTY, \
173          BOOST_VMD_DETAIL_SEQUENCE_STATE_RESULT_ADD_TO_TUPLE \
174          ) \
175      (state,data) \
176 /**/
177 
178 #define BOOST_VMD_DETAIL_SEQUENCE_STATE_RESULT_ADD_GET_NAME(state) \
179     BOOST_PP_CAT \
180         ( \
181         BOOST_VMD_DETAIL_SEQUENCE_STATE_RESULT_ADD_, \
182         BOOST_VMD_DETAIL_SEQUENCE_STATE_OUTTYPE(state) \
183         ) \
184 /**/
185 
186 #define BOOST_VMD_DETAIL_SEQUENCE_STATE_RESULT_ADD_PROCESS(d,name,state,data) \
187     name(d,state,data) \
188 /**/
189 
190 #define BOOST_VMD_DETAIL_SEQUENCE_STATE_RESULT_ADD_GET_DATA(d,state,tuple) \
191     BOOST_VMD_IDENTITY_RESULT \
192         ( \
193         BOOST_PP_IIF \
194             ( \
195             BOOST_VMD_DETAIL_SEQUENCE_STATE_IS_NO_RETURN \
196                 ( \
197                 d, \
198                 BOOST_VMD_DETAIL_SEQUENCE_STATE_FROM(state) \
199                 ), \
200             BOOST_PP_TUPLE_ELEM, \
201             BOOST_VMD_IDENTITY(tuple) \
202             ) \
203         (1,tuple) \
204         ) \
205 /**/
206 
207 #define BOOST_VMD_DETAIL_SEQUENCE_STATE_RESULT_ADD(d,state,ttuple) \
208     BOOST_VMD_DETAIL_SEQUENCE_STATE_RESULT_ADD_PROCESS \
209         ( \
210         d, \
211         BOOST_VMD_DETAIL_SEQUENCE_STATE_RESULT_ADD_GET_NAME(state), \
212         state, \
213         BOOST_VMD_DETAIL_SEQUENCE_STATE_RESULT_ADD_GET_DATA(d,state,ttuple) \
214         ) \
215 /**/
216 
217 #define BOOST_VMD_DETAIL_SEQUENCE_PROCESSING_ELEM_CHECK(d,state) \
218     BOOST_PP_EQUAL_D \
219         ( \
220         d, \
221         BOOST_PP_SEQ_SIZE(BOOST_VMD_DETAIL_SEQUENCE_STATE_RESULT(state)), \
222         BOOST_VMD_DETAIL_SEQUENCE_STATE_ELEM(state) \
223         ) \
224 /**/
225 
226 #define BOOST_VMD_DETAIL_SEQUENCE_PROCESSING_ELEM(d,state) \
227     BOOST_VMD_IDENTITY_RESULT \
228         ( \
229         BOOST_PP_IIF \
230             ( \
231             BOOST_VMD_IS_EMPTY(BOOST_VMD_DETAIL_SEQUENCE_STATE_ELEM(state)), \
232             BOOST_VMD_IDENTITY(0), \
233             BOOST_VMD_DETAIL_SEQUENCE_PROCESSING_ELEM_CHECK \
234             ) \
235         (d,state) \
236         ) \
237 /**/
238 
239 #define BOOST_VMD_DETAIL_SEQUENCE_STATE_GET_TYPE(state) \
240         BOOST_PP_TUPLE_ELEM \
241             ( \
242             0, \
243             BOOST_PP_TUPLE_ELEM(BOOST_VMD_DETAIL_SEQUENCE_STATE_INDEX(state),BOOST_VMD_DETAIL_SEQUENCE_STATE_TYPES(state)) \
244             ) \
245 /**/
246 
247 #define BOOST_VMD_DETAIL_SEQUENCE_STATE_GET_TYPE_REENTRANT(state) \
248         BOOST_PP_TUPLE_ELEM \
249             ( \
250             1, \
251             BOOST_PP_TUPLE_ELEM(BOOST_VMD_DETAIL_SEQUENCE_STATE_INDEX(state),BOOST_VMD_DETAIL_SEQUENCE_STATE_TYPES(state)) \
252             ) \
253 /**/
254 
255 #define BOOST_VMD_DETAIL_SEQUENCE_INNER_OP_UNKNOWN(d,state) \
256     ( \
257     , \
258     BOOST_VMD_DETAIL_SEQUENCE_STATE_RESULT_ADD(d,state,(BOOST_VMD_TYPE_UNKNOWN,BOOST_VMD_DETAIL_SEQUENCE_STATE_INPUT(state))), \
259     BOOST_VMD_DETAIL_SEQUENCE_STATE_ELEM(state), \
260     BOOST_VMD_DETAIL_SEQUENCE_STATE_OUTTYPE(state), \
261     BOOST_VMD_DETAIL_SEQUENCE_STATE_FROM(state), \
262     BOOST_VMD_DETAIL_SEQUENCE_STATE_TYPES(state), \
263     BOOST_PP_INC(BOOST_VMD_DETAIL_SEQUENCE_STATE_INDEX(state)) \
264     ) \
265 /**/
266 
267 #define    BOOST_VMD_DETAIL_SEQUENCE_GET_FULL_TYPE_CHECK_ID(d,type,id) \
268     BOOST_VMD_IDENTITY_RESULT \
269         ( \
270         BOOST_PP_IIF \
271             ( \
272             BOOST_VMD_DETAIL_EQUAL_TYPE_D(d,type,BOOST_VMD_TYPE_IDENTIFIER), \
273             BOOST_VMD_DETAIL_IDENTIFIER_TYPE_D, \
274             BOOST_VMD_IDENTITY(type) \
275             ) \
276         (d,id) \
277         ) \
278 /**/
279 
280 #define    BOOST_VMD_DETAIL_SEQUENCE_GET_FULL_TYPE(d,state,tuple) \
281     BOOST_VMD_DETAIL_SEQUENCE_GET_FULL_TYPE_CHECK_ID \
282         ( \
283         d, \
284         BOOST_PP_CAT \
285             ( \
286             BOOST_VMD_TYPE_, \
287             BOOST_VMD_DETAIL_SEQUENCE_STATE_GET_TYPE(state) \
288             ), \
289         BOOST_PP_TUPLE_ELEM(0,tuple) \
290         ) \
291 /**/
292 
293 #define    BOOST_VMD_DETAIL_SEQUENCE_TYPE_FOUND_PROCESS(d,state,tuple) \
294     ( \
295     BOOST_PP_TUPLE_ELEM(1,tuple), \
296     BOOST_VMD_DETAIL_SEQUENCE_STATE_RESULT_ADD \
297         ( \
298         d, \
299         state, \
300             ( \
301             BOOST_VMD_DETAIL_SEQUENCE_GET_FULL_TYPE(d,state,tuple), \
302             BOOST_PP_TUPLE_ELEM(0,tuple) \
303             ) \
304         ), \
305     BOOST_VMD_DETAIL_SEQUENCE_STATE_ELEM(state), \
306     BOOST_VMD_DETAIL_SEQUENCE_STATE_OUTTYPE(state), \
307     BOOST_VMD_DETAIL_SEQUENCE_STATE_FROM(state), \
308     BOOST_VMD_DETAIL_SEQUENCE_STATE_TYPES(state), \
309     BOOST_PP_INC(BOOST_PP_TUPLE_SIZE(BOOST_VMD_DETAIL_SEQUENCE_STATE_TYPES(state))) \
310     ) \
311 /**/
312 
313 #define    BOOST_VMD_DETAIL_SEQUENCE_TYPE_FOUND_SEQ_SINGLE(d,tuple) \
314     BOOST_PP_EQUAL_D(d,BOOST_PP_SEQ_SIZE(BOOST_PP_TUPLE_ELEM(0,tuple)),1) \
315 /**/
316 
317 #define    BOOST_VMD_DETAIL_SEQUENCE_TYPE_FOUND_SEQ(d,state,tuple) \
318     BOOST_VMD_IDENTITY_RESULT \
319         ( \
320         BOOST_PP_IIF \
321             ( \
322             BOOST_VMD_DETAIL_EQUAL_TYPE_D \
323                 ( \
324                 d, \
325                 BOOST_VMD_DETAIL_SEQUENCE_GET_FULL_TYPE(d,state,tuple), \
326                 BOOST_VMD_TYPE_SEQ \
327                 ), \
328             BOOST_VMD_DETAIL_SEQUENCE_TYPE_FOUND_SEQ_SINGLE, \
329             BOOST_VMD_IDENTITY(0) \
330             ) \
331         (d,tuple) \
332         ) \
333 /**/
334 
335 #define    BOOST_VMD_DETAIL_SEQUENCE_TYPE_FOUND(d,state,tuple) \
336     BOOST_PP_IIF \
337         ( \
338         BOOST_VMD_DETAIL_SEQUENCE_TYPE_FOUND_SEQ(d,state,tuple), \
339         BOOST_VMD_DETAIL_SEQUENCE_INCREMENT_INDEX, \
340         BOOST_VMD_DETAIL_SEQUENCE_TYPE_FOUND_PROCESS \
341         ) \
342     (d,state,tuple) \
343 /**/
344 
345 #define    BOOST_VMD_DETAIL_SEQUENCE_INCREMENT_INDEX(d,state,tuple) \
346     BOOST_PP_TUPLE_REPLACE_D(d,state,BOOST_VMD_DETAIL_SEQUENCE_STATE_INDEX_ELEM,BOOST_PP_INC(BOOST_VMD_DETAIL_SEQUENCE_STATE_INDEX(state))) \
347 /**/
348 
349 #define    BOOST_VMD_DETAIL_SEQUENCE_TEST_TYPE_TUPLE(d,state,tuple) \
350     BOOST_PP_IIF \
351         ( \
352         BOOST_VMD_IS_EMPTY \
353             ( \
354             BOOST_PP_TUPLE_ELEM(0,tuple) \
355             ), \
356         BOOST_VMD_DETAIL_SEQUENCE_INCREMENT_INDEX, \
357         BOOST_VMD_DETAIL_SEQUENCE_TYPE_FOUND \
358         ) \
359     (d,state,tuple) \
360 /**/
361 
362 #define    BOOST_VMD_DETAIL_SEQUENCE_TEST_TYPE(d,call,state) \
363     BOOST_VMD_DETAIL_SEQUENCE_TEST_TYPE_TUPLE \
364         ( \
365         d, \
366         state, \
367         call(BOOST_VMD_DETAIL_SEQUENCE_STATE_INPUT(state),BOOST_VMD_RETURN_AFTER) \
368         ) \
369 /**/
370 
371 #define    BOOST_VMD_DETAIL_SEQUENCE_TEST_TYPE_D(d,call,state) \
372     BOOST_VMD_DETAIL_SEQUENCE_TEST_TYPE_TUPLE \
373         ( \
374         d, \
375         state, \
376         call(d,BOOST_VMD_DETAIL_SEQUENCE_STATE_INPUT(state),BOOST_VMD_RETURN_AFTER) \
377         ) \
378 /**/
379 
380 #define BOOST_VMD_DETAIL_SEQUENCE_GCLRT(state) \
381     BOOST_PP_CAT \
382         ( \
383         BOOST_VMD_DETAIL_, \
384         BOOST_PP_CAT(BOOST_VMD_DETAIL_SEQUENCE_STATE_GET_TYPE(state),_D) \
385         ) \
386 /**/
387 
388 #define BOOST_VMD_DETAIL_SEQUENCE_GCLPL(state) \
389     BOOST_PP_CAT \
390         ( \
391         BOOST_VMD_DETAIL_, \
392         BOOST_VMD_DETAIL_SEQUENCE_STATE_GET_TYPE(state) \
393         ) \
394 /**/
395 
396 #define BOOST_VMD_DETAIL_SEQUENCE_INNER_OP_TEST_GCL(state,rflag) \
397     BOOST_PP_IIF \
398         ( \
399         rflag, \
400         BOOST_VMD_DETAIL_SEQUENCE_GCLRT, \
401         BOOST_VMD_DETAIL_SEQUENCE_GCLPL \
402         ) \
403     (state) \
404 /**/
405 
406 #define BOOST_VMD_DETAIL_SEQUENCE_INNER_OP_TEST_RT_CALL(d,call,state,rflag) \
407     BOOST_PP_IIF \
408         ( \
409         rflag, \
410         BOOST_VMD_DETAIL_SEQUENCE_TEST_TYPE_D, \
411         BOOST_VMD_DETAIL_SEQUENCE_TEST_TYPE \
412         ) \
413     (d,call,state) \
414 /**/
415 
416 #define BOOST_VMD_DETAIL_SEQUENCE_INNER_OP_TEST_RT(d,state,rflag) \
417     BOOST_VMD_DETAIL_SEQUENCE_INNER_OP_TEST_RT_CALL \
418         ( \
419         d, \
420         BOOST_VMD_DETAIL_SEQUENCE_INNER_OP_TEST_GCL(state,rflag), \
421         state, \
422         rflag \
423         ) \
424 /**/
425 
426 #define BOOST_VMD_DETAIL_SEQUENCE_INNER_OP_TEST(d,state) \
427     BOOST_VMD_DETAIL_SEQUENCE_INNER_OP_TEST_RT \
428         ( \
429         d, \
430         state, \
431         BOOST_VMD_DETAIL_SEQUENCE_STATE_GET_TYPE_REENTRANT(state) \
432         ) \
433 /**/
434 
435 #define BOOST_VMD_DETAIL_SEQUENCE_INNER_OP(d,state) \
436     BOOST_PP_IIF \
437         ( \
438         BOOST_PP_EQUAL_D \
439             ( \
440             d, \
441             BOOST_VMD_DETAIL_SEQUENCE_STATE_INDEX(state), \
442             BOOST_PP_TUPLE_SIZE(BOOST_VMD_DETAIL_SEQUENCE_STATE_TYPES(state)) \
443             ), \
444         BOOST_VMD_DETAIL_SEQUENCE_INNER_OP_UNKNOWN, \
445         BOOST_VMD_DETAIL_SEQUENCE_INNER_OP_TEST \
446         ) \
447     (d,state) \
448 /**/
449 
450 #define BOOST_VMD_DETAIL_SEQUENCE_INNER_PRED(d,state) \
451     BOOST_PP_NOT_EQUAL_D \
452         ( \
453         d, \
454         BOOST_VMD_DETAIL_SEQUENCE_STATE_INDEX(state), \
455         BOOST_PP_INC(BOOST_PP_TUPLE_SIZE(BOOST_VMD_DETAIL_SEQUENCE_STATE_TYPES(state))) \
456         ) \
457 /**/
458 
459 #define BOOST_VMD_DETAIL_SEQUENCE_OP_PAREN_TUPLE_TYPES_ELEM_FROM(d,from) \
460     BOOST_PP_IIF \
461         ( \
462         BOOST_VMD_DETAIL_SEQUENCE_STATE_IS_GENERAL_RETURN(d,from), \
463         ((SEQ,1),(TUPLE,1)), \
464         BOOST_PP_IIF \
465             ( \
466             BOOST_VMD_DETAIL_SEQUENCE_STATE_IS_EXACT_RETURN(d,from), \
467             ((SEQ,1),(LIST,1),(ARRAY,1),(TUPLE,1)), \
468             BOOST_PP_IIF \
469                 ( \
470                 BOOST_VMD_DETAIL_SEQUENCE_STATE_IS_ARRAY_RETURN(d,from), \
471                 ((SEQ,1),(ARRAY,1),(TUPLE,1)), \
472                 BOOST_PP_IIF \
473                     ( \
474                     BOOST_VMD_DETAIL_SEQUENCE_STATE_IS_LIST_RETURN(d,from), \
475                     ((SEQ,1),(LIST,1),(TUPLE,1)), \
476                     ((SEQ,1),(TUPLE,1)) \
477                     ) \
478                 ) \
479             ) \
480         ) \
481 /**/
482 
483 #define BOOST_VMD_DETAIL_SEQUENCE_OP_PAREN_TUPLE_TYPES_ELEM(d,state) \
484     BOOST_VMD_DETAIL_SEQUENCE_OP_PAREN_TUPLE_TYPES_ELEM_FROM \
485         ( \
486         d, \
487         BOOST_VMD_DETAIL_SEQUENCE_STATE_FROM(state) \
488         ) \
489 /**/
490 
491 #define BOOST_VMD_DETAIL_SEQUENCE_OP_PAREN_TUPLE_TYPES_ANY(d,state) \
492     BOOST_VMD_IDENTITY_RESULT \
493         ( \
494         BOOST_PP_IIF \
495             ( \
496             BOOST_VMD_IS_EMPTY \
497                 ( \
498                 BOOST_VMD_DETAIL_SEQUENCE_STATE_ELEM(state) \
499                 ), \
500             BOOST_VMD_DETAIL_SEQUENCE_OP_PAREN_TUPLE_TYPES_ELEM, \
501             BOOST_VMD_IDENTITY(((SEQ,1),(TUPLE,1))) \
502             ) \
503         (d,state) \
504         ) \
505 /**/
506 
507 #define BOOST_VMD_DETAIL_SEQUENCE_OP_PAREN_TUPLE_TYPES(d,state) \
508     BOOST_PP_IIF \
509         ( \
510         BOOST_VMD_DETAIL_SEQUENCE_PROCESSING_ELEM(d,state), \
511         BOOST_VMD_DETAIL_SEQUENCE_OP_PAREN_TUPLE_TYPES_ELEM, \
512         BOOST_VMD_DETAIL_SEQUENCE_OP_PAREN_TUPLE_TYPES_ANY \
513         ) \
514     (d,state) \
515 /**/
516 
517 #define BOOST_VMD_DETAIL_SEQUENCE_OP_PAREN(d,state) \
518     BOOST_PP_WHILE_ ## d \
519         ( \
520         BOOST_VMD_DETAIL_SEQUENCE_INNER_PRED, \
521         BOOST_VMD_DETAIL_SEQUENCE_INNER_OP, \
522         BOOST_PP_TUPLE_PUSH_BACK \
523             ( \
524             BOOST_PP_TUPLE_PUSH_BACK \
525                 ( \
526                 state, \
527                 BOOST_VMD_DETAIL_SEQUENCE_OP_PAREN_TUPLE_TYPES(d,state) \
528                 ), \
529             0 \
530             ) \
531         ) \
532 /**/
533 
534 #define BOOST_VMD_DETAIL_SEQUENCE_OP_ID_LOOP(d,state) \
535     BOOST_PP_WHILE_ ## d \
536         ( \
537         BOOST_VMD_DETAIL_SEQUENCE_INNER_PRED, \
538         BOOST_VMD_DETAIL_SEQUENCE_INNER_OP, \
539         BOOST_PP_TUPLE_PUSH_BACK(BOOST_PP_TUPLE_PUSH_BACK(state,((IDENTIFIER,1))),0) \
540         ) \
541 /**/
542 
543 #define BOOST_VMD_DETAIL_SEQUENCE_OP_ID_EL(d,state) \
544     ( \
545     BOOST_PP_TUPLE_ELEM(1,BOOST_VMD_DETAIL_LIST_D(d,BOOST_VMD_DETAIL_SEQUENCE_STATE_INPUT(state),BOOST_VMD_RETURN_AFTER)), \
546     BOOST_VMD_DETAIL_SEQUENCE_STATE_RESULT_ADD(d,state,(BOOST_VMD_TYPE_LIST,BOOST_PP_NIL)), \
547     BOOST_VMD_DETAIL_SEQUENCE_STATE_ELEM(state), \
548     BOOST_VMD_DETAIL_SEQUENCE_STATE_OUTTYPE(state), \
549     BOOST_VMD_DETAIL_SEQUENCE_STATE_FROM(state) \
550     ) \
551 /**/
552 
553 #define BOOST_VMD_DETAIL_SEQUENCE_OP_ID(d,state) \
554     BOOST_PP_IIF \
555         ( \
556         BOOST_VMD_IS_EMPTY_LIST_D \
557             ( \
558             d, \
559             BOOST_VMD_DETAIL_IDENTIFIER_D \
560                 ( \
561                 d, \
562                 BOOST_VMD_DETAIL_SEQUENCE_STATE_INPUT(state) \
563                 ) \
564             ), \
565         BOOST_VMD_DETAIL_SEQUENCE_OP_ID_EL, \
566         BOOST_VMD_DETAIL_SEQUENCE_OP_ID_LOOP \
567         ) \
568     (d,state) \
569 /**/
570 
571 #define BOOST_VMD_DETAIL_SEQUENCE_OP_REDUCE_STATE(state) \
572     ( \
573     BOOST_VMD_DETAIL_SEQUENCE_STATE_INPUT(state), \
574     BOOST_VMD_DETAIL_SEQUENCE_STATE_RESULT(state), \
575     BOOST_VMD_DETAIL_SEQUENCE_STATE_ELEM(state), \
576     BOOST_VMD_DETAIL_SEQUENCE_STATE_OUTTYPE(state), \
577     BOOST_VMD_DETAIL_SEQUENCE_STATE_FROM(state) \
578     ) \
579 /**/
580 
581 #define BOOST_VMD_DETAIL_SEQUENCE_OP(d,state) \
582     BOOST_VMD_DETAIL_SEQUENCE_OP_REDUCE_STATE \
583         ( \
584         BOOST_PP_IIF \
585             ( \
586             BOOST_PP_IS_BEGIN_PARENS \
587                 ( \
588                 BOOST_VMD_DETAIL_SEQUENCE_STATE_INPUT(state) \
589                 ), \
590             BOOST_VMD_DETAIL_SEQUENCE_OP_PAREN, \
591             BOOST_VMD_DETAIL_SEQUENCE_OP_ID \
592             ) \
593         (d,state) \
594         ) \
595 /**/
596 
597 #define BOOST_VMD_DETAIL_SEQUENCE_PRED_CELEM_SZ(d,state) \
598     BOOST_PP_LESS_EQUAL_D \
599         ( \
600         d, \
601         BOOST_PP_SEQ_SIZE(BOOST_VMD_DETAIL_SEQUENCE_STATE_RESULT(state)), \
602         BOOST_VMD_DETAIL_SEQUENCE_STATE_ELEM(state) \
603         ) \
604 /**/
605 
606 #define BOOST_VMD_DETAIL_SEQUENCE_PRED_CELEM(d,state) \
607     BOOST_VMD_IDENTITY_RESULT \
608         ( \
609         BOOST_PP_IIF \
610             ( \
611             BOOST_PP_BITOR \
612                 ( \
613                 BOOST_VMD_IS_EMPTY \
614                     ( \
615                     BOOST_VMD_DETAIL_SEQUENCE_STATE_ELEM(state) \
616                     ), \
617                 BOOST_VMD_IS_EMPTY \
618                     ( \
619                     BOOST_VMD_DETAIL_SEQUENCE_STATE_RESULT(state) \
620                     ) \
621                 ), \
622             BOOST_VMD_IDENTITY(1), \
623             BOOST_VMD_DETAIL_SEQUENCE_PRED_CELEM_SZ \
624             ) \
625         (d,state) \
626         ) \
627 /**/
628 
629 #define BOOST_VMD_DETAIL_SEQUENCE_PRED(d,state) \
630     BOOST_VMD_IDENTITY_RESULT \
631         ( \
632         BOOST_PP_IIF \
633             ( \
634             BOOST_VMD_IS_EMPTY \
635                 ( \
636                 BOOST_VMD_DETAIL_SEQUENCE_STATE_INPUT(state) \
637                 ), \
638             BOOST_VMD_IDENTITY(0), \
639             BOOST_VMD_DETAIL_SEQUENCE_PRED_CELEM \
640             ) \
641         (d,state) \
642         ) \
643 /**/
644 
645 #define BOOST_VMD_DETAIL_SEQUENCE_EMPTY_TYPE_CHECK(output) \
646     BOOST_PP_IIF \
647         ( \
648         BOOST_VMD_DETAIL_EQUAL_TYPE(output,BOOST_VMD_TYPE_ARRAY), \
649         (0,()), \
650         BOOST_PP_NIL \
651         ) \
652 /**/
653 
654 #define BOOST_VMD_DETAIL_SEQUENCE_EMPTY_TYPE_CHECK_D(d,output) \
655     BOOST_PP_IIF \
656         ( \
657         BOOST_VMD_DETAIL_EQUAL_TYPE_D(d,output,BOOST_VMD_TYPE_ARRAY), \
658         (0,()), \
659         BOOST_PP_NIL \
660         ) \
661 /**/
662 
663 #define BOOST_VMD_DETAIL_SEQUENCE_EMPTY_TYPE(output) \
664     BOOST_PP_IIF \
665         ( \
666         BOOST_PP_BITOR \
667             ( \
668             BOOST_VMD_DETAIL_EQUAL_TYPE(output,BOOST_VMD_TYPE_SEQ), \
669             BOOST_VMD_DETAIL_EQUAL_TYPE(output,BOOST_VMD_TYPE_TUPLE) \
670             ), \
671         BOOST_VMD_EMPTY, \
672         BOOST_VMD_DETAIL_SEQUENCE_EMPTY_TYPE_CHECK \
673         ) \
674     (output) \
675 /**/
676 
677 #define BOOST_VMD_DETAIL_SEQUENCE_EMPTY_TYPE_D(d,output) \
678     BOOST_PP_IIF \
679         ( \
680         BOOST_PP_BITOR \
681             ( \
682             BOOST_VMD_DETAIL_EQUAL_TYPE_D(d,output,BOOST_VMD_TYPE_SEQ), \
683             BOOST_VMD_DETAIL_EQUAL_TYPE_D(d,output,BOOST_VMD_TYPE_TUPLE) \
684             ), \
685         BOOST_VMD_EMPTY, \
686         BOOST_VMD_DETAIL_SEQUENCE_EMPTY_TYPE_CHECK_D \
687         ) \
688     (d,output) \
689 /**/
690 
691 #define BOOST_VMD_DETAIL_SEQUENCE_ELEM_PROCESS_TUPLE_GET(state) \
692     BOOST_PP_IIF \
693         ( \
694         BOOST_VMD_DETAIL_SEQUENCE_STATE_IS_AFTER \
695             ( \
696             BOOST_VMD_DETAIL_SEQUENCE_STATE_FROM(state) \
697             ), \
698             ( \
699             BOOST_VMD_DETAIL_SEQUENCE_STATE_RESULT(state), \
700             BOOST_VMD_DETAIL_SEQUENCE_STATE_INPUT(state) \
701             ), \
702             BOOST_VMD_DETAIL_SEQUENCE_STATE_RESULT(state) \
703         )
704 /**/
705 
706 #define BOOST_VMD_DETAIL_SEQUENCE_ELEM_PROCESS_TUPLE_GET_D(d,state) \
707     BOOST_PP_IIF \
708         ( \
709         BOOST_VMD_DETAIL_SEQUENCE_STATE_IS_AFTER_D \
710             ( \
711             d, \
712             BOOST_VMD_DETAIL_SEQUENCE_STATE_FROM(state) \
713             ), \
714             ( \
715             BOOST_VMD_DETAIL_SEQUENCE_STATE_RESULT(state), \
716             BOOST_VMD_DETAIL_SEQUENCE_STATE_INPUT(state) \
717             ), \
718             BOOST_VMD_DETAIL_SEQUENCE_STATE_RESULT(state) \
719         )
720 /**/
721 
722 #define BOOST_VMD_DETAIL_SEQUENCE_ELEM_PROCESS_TUPLE(vseq,elem,output,from) \
723     BOOST_VMD_DETAIL_SEQUENCE_ELEM_PROCESS_TUPLE_GET \
724         ( \
725         BOOST_PP_WHILE \
726             ( \
727             BOOST_VMD_DETAIL_SEQUENCE_PRED, \
728             BOOST_VMD_DETAIL_SEQUENCE_OP, \
729                 ( \
730                 vseq, \
731                 BOOST_VMD_DETAIL_SEQUENCE_EMPTY_TYPE \
732                     ( \
733                     output \
734                     ), \
735                 elem, \
736                 output, \
737                 from \
738                 ) \
739             ) \
740         ) \
741 /**/
742 
743 #define BOOST_VMD_DETAIL_SEQUENCE_ELEM_PROCESS_TUPLE_D(d,vseq,elem,output,from) \
744     BOOST_VMD_DETAIL_SEQUENCE_ELEM_PROCESS_TUPLE_GET_D \
745         ( \
746         d, \
747         BOOST_PP_WHILE_ ## d \
748             ( \
749             BOOST_VMD_DETAIL_SEQUENCE_PRED, \
750             BOOST_VMD_DETAIL_SEQUENCE_OP, \
751                 ( \
752                 vseq, \
753                 BOOST_VMD_DETAIL_SEQUENCE_EMPTY_TYPE_D \
754                     ( \
755                     d, \
756                     output \
757                     ), \
758                 elem, \
759                 output, \
760                 from \
761                 ) \
762             ) \
763         ) \
764 /**/
765 
766 #endif /* BOOST_VMD_DETAIL_SEQUENCE_COMMON_HPP */
767