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_MATCH_IDENTIFIER_HPP)
8 #define BOOST_VMD_DETAIL_MATCH_IDENTIFIER_HPP
9 
10 #include <boost/preprocessor/arithmetic/inc.hpp>
11 #include <boost/preprocessor/cat.hpp>
12 #include <boost/preprocessor/comparison/equal.hpp>
13 #include <boost/preprocessor/comparison/not_equal.hpp>
14 #include <boost/preprocessor/control/iif.hpp>
15 #include <boost/preprocessor/control/while.hpp>
16 #include <boost/preprocessor/logical/bitand.hpp>
17 #include <boost/preprocessor/tuple/elem.hpp>
18 #include <boost/preprocessor/tuple/replace.hpp>
19 #include <boost/preprocessor/tuple/size.hpp>
20 #include <boost/vmd/is_empty.hpp>
21 #include <boost/vmd/detail/idprefix.hpp>
22 #include <boost/vmd/detail/match_identifier_common.hpp>
23 
24 #define BOOST_VMD_DETAIL_MATCH_IDENTIFIER_STATE_ID(state) \
25     BOOST_PP_TUPLE_ELEM(0,state) \
26 /**/
27 
28 #define BOOST_VMD_DETAIL_MATCH_IDENTIFIER_STATE_KEY_TUPLE(state) \
29     BOOST_PP_TUPLE_ELEM(1,state) \
30 /**/
31 
32 #define BOOST_VMD_DETAIL_MATCH_IDENTIFIER_STATE_KEY_TUPLE_SIZE(state) \
33     BOOST_PP_TUPLE_ELEM(2,state) \
34 /**/
35 
36 #define BOOST_VMD_DETAIL_MATCH_IDENTIFIER_STATE_KEY_CURRENT(state) \
37     BOOST_PP_TUPLE_ELEM \
38         ( \
39         BOOST_VMD_DETAIL_MATCH_IDENTIFIER_STATE_INDEX(state), \
40         BOOST_VMD_DETAIL_MATCH_IDENTIFIER_STATE_KEY_TUPLE(state) \
41         ) \
42 /**/
43 
44 #define BOOST_VMD_DETAIL_MATCH_IDENTIFIER_STATE_INDEX(state) \
45     BOOST_PP_TUPLE_ELEM(3,state) \
46 /**/
47 
48 #define BOOST_VMD_DETAIL_MATCH_IDENTIFIER_STATE_RESULT(state) \
49     BOOST_PP_TUPLE_ELEM(4,state) \
50 /**/
51 
52 #define BOOST_VMD_DETAIL_MATCH_IDENTIFIER_PRED(d,state) \
53     BOOST_PP_BITAND \
54         ( \
55         BOOST_PP_EQUAL_D \
56             ( \
57             d, \
58             BOOST_VMD_DETAIL_MATCH_IDENTIFIER_STATE_RESULT(state), \
59             0 \
60             ), \
61         BOOST_PP_NOT_EQUAL_D \
62             ( \
63             d, \
64             BOOST_VMD_DETAIL_MATCH_IDENTIFIER_STATE_INDEX(state), \
65             BOOST_VMD_DETAIL_MATCH_IDENTIFIER_STATE_KEY_TUPLE_SIZE(state) \
66             ) \
67         ) \
68 /**/
69 
70 #define BOOST_VMD_DETAIL_MATCH_IDENTIFIER_OP_FOUND(d,state) \
71     BOOST_PP_TUPLE_REPLACE_D \
72         ( \
73         d, \
74         state, \
75         4, \
76         BOOST_PP_INC \
77             ( \
78             BOOST_VMD_DETAIL_MATCH_IDENTIFIER_STATE_INDEX(state) \
79             ) \
80         ) \
81 /**/
82 
83 #define BOOST_VMD_DETAIL_MATCH_IDENTIFIER_OP_CONTINUE(d,state) \
84     BOOST_PP_TUPLE_REPLACE_D \
85         ( \
86         d, \
87         state, \
88         3, \
89         BOOST_PP_INC \
90             ( \
91             BOOST_VMD_DETAIL_MATCH_IDENTIFIER_STATE_INDEX(state) \
92             ) \
93         ) \
94 /**/
95 
96 #define BOOST_VMD_DETAIL_MATCH_IDENTIFIER_OP(d,state) \
97     BOOST_PP_IIF \
98         ( \
99         BOOST_VMD_DETAIL_MATCH_IDENTIFIER_OP_CMP_IDS \
100             ( \
101             BOOST_VMD_DETAIL_MATCH_IDENTIFIER_STATE_ID(state), \
102             BOOST_VMD_DETAIL_MATCH_IDENTIFIER_STATE_KEY_CURRENT(state) \
103             ), \
104         BOOST_VMD_DETAIL_MATCH_IDENTIFIER_OP_FOUND, \
105         BOOST_VMD_DETAIL_MATCH_IDENTIFIER_OP_CONTINUE \
106         ) \
107     (d,state) \
108 /**/
109 
110 /*
111 
112   Return index starting with 1 of the tuple id the identifier matches, or 0 if there are no matches.
113 
114 */
115 
116 #define BOOST_VMD_DETAIL_MATCH_IDENTIFIER(id,keytuple) \
117     BOOST_PP_TUPLE_ELEM \
118         ( \
119         4, \
120         BOOST_PP_WHILE \
121             ( \
122             BOOST_VMD_DETAIL_MATCH_IDENTIFIER_PRED, \
123             BOOST_VMD_DETAIL_MATCH_IDENTIFIER_OP, \
124                 ( \
125                 id, \
126                 keytuple, \
127                 BOOST_PP_TUPLE_SIZE(keytuple), \
128                 0, \
129                 0 \
130                 ) \
131             ) \
132         ) \
133 /**/
134 
135 /*
136 
137   Return index starting with 1 of the tuple id the identifier matches, or 0 if there are no matches.
138 
139 */
140 
141 #define BOOST_VMD_DETAIL_MATCH_IDENTIFIER_D(d,id,keytuple) \
142     BOOST_PP_TUPLE_ELEM \
143         ( \
144         4, \
145         BOOST_PP_WHILE_ ## d \
146             ( \
147             BOOST_VMD_DETAIL_MATCH_IDENTIFIER_PRED, \
148             BOOST_VMD_DETAIL_MATCH_IDENTIFIER_OP, \
149                 ( \
150                 id, \
151                 keytuple, \
152                 BOOST_PP_TUPLE_SIZE(keytuple), \
153                 0, \
154                 0 \
155                 ) \
156             ) \
157         ) \
158 /**/
159 
160 #endif /* BOOST_VMD_DETAIL_MATCH_IDENTIFIER_HPP */
161