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_DATA_EQUAL_COMMON_HPP)
8 #define BOOST_VMD_DETAIL_DATA_EQUAL_COMMON_HPP
9 
10 #include <boost/preprocessor/arithmetic/inc.hpp>
11 #include <boost/preprocessor/array/elem.hpp>
12 #include <boost/preprocessor/array/size.hpp>
13 #include <boost/preprocessor/comparison/equal.hpp>
14 #include <boost/preprocessor/control/iif.hpp>
15 #include <boost/preprocessor/list/at.hpp>
16 #include <boost/preprocessor/list/size.hpp>
17 #include <boost/preprocessor/logical/bitand.hpp>
18 #include <boost/preprocessor/logical/bitor.hpp>
19 #include <boost/preprocessor/logical/compl.hpp>
20 #include <boost/preprocessor/punctuation/is_begin_parens.hpp>
21 #include <boost/preprocessor/seq/elem.hpp>
22 #include <boost/preprocessor/seq/size.hpp>
23 #include <boost/preprocessor/tuple/elem.hpp>
24 #include <boost/preprocessor/tuple/pop_front.hpp>
25 #include <boost/preprocessor/tuple/push_back.hpp>
26 #include <boost/preprocessor/tuple/replace.hpp>
27 #include <boost/preprocessor/tuple/size.hpp>
28 #include <boost/vmd/empty.hpp>
29 #include <boost/vmd/is_empty.hpp>
30 #include <boost/vmd/get_type.hpp>
31 #include <boost/vmd/detail/equal_type.hpp>
32 
33 #define BOOST_VMD_DETAIL_DATA_EQUAL_IS_BOTH_COMPOSITE(vseq1,vseq2) \
34     BOOST_PP_BITAND \
35         ( \
36         BOOST_PP_IS_BEGIN_PARENS(vseq1), \
37         BOOST_PP_IS_BEGIN_PARENS(vseq2) \
38         ) \
39 /**/
40 
41 #define BOOST_VMD_DETAIL_DATA_EQUAL_GET_ELEM_ARRAY(d,index,data) \
42     BOOST_PP_ARRAY_ELEM(index,data) \
43 /**/
44 
45 #define BOOST_VMD_DETAIL_DATA_EQUAL_GET_ELEM_LIST(d,index,data) \
46     BOOST_PP_LIST_AT_D(d,data,index) \
47 /**/
48 
49 #define BOOST_VMD_DETAIL_DATA_EQUAL_GET_ELEM_SEQ(d,index,data) \
50     BOOST_PP_SEQ_ELEM(index,data) \
51 /**/
52 
53 #define BOOST_VMD_DETAIL_DATA_EQUAL_GET_ELEM_TUPLE(d,index,data) \
54     BOOST_PP_TUPLE_ELEM(index,data) \
55 /**/
56 
57 #define BOOST_VMD_DETAIL_DATA_EQUAL_GET_SIZE_ARRAY(data) \
58     BOOST_PP_ARRAY_SIZE(data) \
59 /**/
60 
61 #define BOOST_VMD_DETAIL_DATA_EQUAL_GET_SIZE_LIST(data) \
62     BOOST_PP_LIST_SIZE(data) \
63 /**/
64 
65 #define BOOST_VMD_DETAIL_DATA_EQUAL_GET_SIZE_SEQ(data) \
66     BOOST_PP_SEQ_SIZE(data) \
67 /**/
68 
69 #define BOOST_VMD_DETAIL_DATA_EQUAL_GET_SIZE_TUPLE(data) \
70     BOOST_PP_TUPLE_SIZE(data) \
71 /**/
72 
73 #define BOOST_VMD_DETAIL_DATA_EQUAL_GET_SIZE_ARRAY_D(d,data) \
74     BOOST_PP_ARRAY_SIZE(data) \
75 /**/
76 
77 #define BOOST_VMD_DETAIL_DATA_EQUAL_GET_SIZE_LIST_D(d,data) \
78     BOOST_PP_LIST_SIZE_D(d,data) \
79 /**/
80 
81 #define BOOST_VMD_DETAIL_DATA_EQUAL_GET_SIZE_SEQ_D(d,data) \
82     BOOST_PP_SEQ_SIZE(data) \
83 /**/
84 
85 #define BOOST_VMD_DETAIL_DATA_EQUAL_GET_SIZE_TUPLE_D(d,data) \
86     BOOST_PP_TUPLE_SIZE(data) \
87 /**/
88 
89 #define BOOST_VMD_DETAIL_DATA_EQUAL_GET_ELEM(d,index,data,vtype) \
90     BOOST_PP_IIF \
91         ( \
92         BOOST_VMD_DETAIL_EQUAL_TYPE_D(d,vtype,BOOST_VMD_TYPE_ARRAY), \
93         BOOST_VMD_DETAIL_DATA_EQUAL_GET_ELEM_ARRAY, \
94         BOOST_PP_IIF \
95             ( \
96             BOOST_VMD_DETAIL_EQUAL_TYPE_D(d,vtype,BOOST_VMD_TYPE_LIST), \
97             BOOST_VMD_DETAIL_DATA_EQUAL_GET_ELEM_LIST, \
98             BOOST_PP_IIF \
99                 ( \
100                 BOOST_VMD_DETAIL_EQUAL_TYPE_D(d,vtype,BOOST_VMD_TYPE_SEQ), \
101                 BOOST_VMD_DETAIL_DATA_EQUAL_GET_ELEM_SEQ, \
102                 BOOST_VMD_DETAIL_DATA_EQUAL_GET_ELEM_TUPLE \
103                 ) \
104             ) \
105         ) \
106     (d,index,data) \
107 /**/
108 
109 #define BOOST_VMD_DETAIL_DATA_EQUAL_GET_SIZE(data,vtype) \
110     BOOST_PP_IIF \
111         ( \
112         BOOST_VMD_DETAIL_EQUAL_TYPE(vtype,BOOST_VMD_TYPE_ARRAY), \
113         BOOST_VMD_DETAIL_DATA_EQUAL_GET_SIZE_ARRAY, \
114         BOOST_PP_IIF \
115             ( \
116             BOOST_VMD_DETAIL_EQUAL_TYPE(vtype,BOOST_VMD_TYPE_LIST), \
117             BOOST_VMD_DETAIL_DATA_EQUAL_GET_SIZE_LIST, \
118             BOOST_PP_IIF \
119                 ( \
120                 BOOST_VMD_DETAIL_EQUAL_TYPE(vtype,BOOST_VMD_TYPE_SEQ), \
121                 BOOST_VMD_DETAIL_DATA_EQUAL_GET_SIZE_SEQ, \
122                 BOOST_VMD_DETAIL_DATA_EQUAL_GET_SIZE_TUPLE \
123                 ) \
124             ) \
125         ) \
126     (data) \
127 /**/
128 
129 #define BOOST_VMD_DETAIL_DATA_EQUAL_GET_SIZE_D(d,data,vtype) \
130     BOOST_PP_IIF \
131         ( \
132         BOOST_VMD_DETAIL_EQUAL_TYPE_D(d,vtype,BOOST_VMD_TYPE_ARRAY), \
133         BOOST_VMD_DETAIL_DATA_EQUAL_GET_SIZE_ARRAY_D, \
134         BOOST_PP_IIF \
135             ( \
136             BOOST_VMD_DETAIL_EQUAL_TYPE_D(d,vtype,BOOST_VMD_TYPE_LIST), \
137             BOOST_VMD_DETAIL_DATA_EQUAL_GET_SIZE_LIST_D, \
138             BOOST_PP_IIF \
139                 ( \
140                 BOOST_VMD_DETAIL_EQUAL_TYPE_D(d,vtype,BOOST_VMD_TYPE_SEQ), \
141                 BOOST_VMD_DETAIL_DATA_EQUAL_GET_SIZE_SEQ_D, \
142                 BOOST_VMD_DETAIL_DATA_EQUAL_GET_SIZE_TUPLE_D \
143                 ) \
144             ) \
145         ) \
146     (d,data) \
147 /**/
148 
149 #define BOOST_VMD_DETAIL_DATA_EQUAL_STATE_RESULT(state) \
150     BOOST_PP_TUPLE_ELEM(0,state) \
151 /**/
152 
153 #define BOOST_VMD_DETAIL_DATA_EQUAL_STATE_FIRST(state) \
154     BOOST_PP_TUPLE_ELEM(1,state) \
155 /**/
156 
157 #define BOOST_VMD_DETAIL_DATA_EQUAL_STATE_SECOND(state) \
158     BOOST_PP_TUPLE_ELEM(2,state) \
159 /**/
160 
161 #define BOOST_VMD_DETAIL_DATA_EQUAL_STATE_SIZE(state) \
162     BOOST_PP_TUPLE_ELEM(3,state) \
163 /**/
164 
165 #define BOOST_VMD_DETAIL_DATA_EQUAL_STATE_TYPE(state) \
166     BOOST_PP_TUPLE_ELEM(4,state) \
167 /**/
168 
169 #define BOOST_VMD_DETAIL_DATA_EQUAL_STATE_INDEX(state) \
170     BOOST_PP_TUPLE_ELEM(5,state) \
171 /**/
172 
173 #define BOOST_VMD_DETAIL_DATA_EQUAL_STATE_COMP(state) \
174     BOOST_PP_TUPLE_ELEM(6,state) \
175 /**/
176 
177 #define BOOST_VMD_DETAIL_DATA_EQUAL_STATE_COMP_PROCESSING(d,state) \
178     BOOST_PP_BITAND \
179         ( \
180         BOOST_PP_EQUAL_D \
181             ( \
182             d, \
183             BOOST_VMD_DETAIL_DATA_EQUAL_STATE_INDEX(state), \
184             BOOST_VMD_DETAIL_DATA_EQUAL_STATE_SIZE(state) \
185             ), \
186         BOOST_PP_COMPL(BOOST_VMD_DETAIL_DATA_EQUAL_STATE_COMP_EMPTY(state)) \
187         ) \
188 /**/
189 
190 #define BOOST_VMD_DETAIL_DATA_EQUAL_STATE_COMP_EMPTY(state) \
191     BOOST_VMD_IS_EMPTY(BOOST_VMD_DETAIL_DATA_EQUAL_STATE_COMP(state)) \
192 /**/
193 
194 #define BOOST_VMD_DETAIL_DATA_EQUAL_STATE_COMP_INDEX(state) \
195     BOOST_PP_IIF \
196         ( \
197         BOOST_VMD_DETAIL_DATA_EQUAL_STATE_COMP_EMPTY(state), \
198         BOOST_VMD_EMPTY, \
199         BOOST_PP_TUPLE_ELEM \
200         ) \
201     (0,BOOST_VMD_DETAIL_DATA_EQUAL_STATE_COMP(state)) \
202 /**/
203 
204 #define BOOST_VMD_DETAIL_DATA_EQUAL_STATE_COMP_POP_NE_EMPTY(d,state) \
205     BOOST_PP_TUPLE_REPLACE_D \
206         ( \
207         d, \
208         state, \
209         6, \
210         ) \
211 /**/
212 
213 #define BOOST_VMD_DETAIL_DATA_EQUAL_STATE_COMP_POP_NE_REMOVE(d,state) \
214     BOOST_PP_TUPLE_REPLACE_D \
215         ( \
216         d, \
217         state, \
218         6, \
219         BOOST_PP_TUPLE_POP_FRONT(BOOST_VMD_DETAIL_DATA_EQUAL_STATE_COMP(state)) \
220         ) \
221 /**/
222 
223 #define BOOST_VMD_DETAIL_DATA_EQUAL_STATE_COMP_POP(d,state) \
224     BOOST_PP_IIF \
225         ( \
226         BOOST_PP_EQUAL_D(d,BOOST_PP_TUPLE_SIZE(BOOST_VMD_DETAIL_DATA_EQUAL_STATE_COMP(state)),1), \
227         BOOST_VMD_DETAIL_DATA_EQUAL_STATE_COMP_POP_NE_EMPTY, \
228         BOOST_VMD_DETAIL_DATA_EQUAL_STATE_COMP_POP_NE_REMOVE \
229         ) \
230     (d,state) \
231 /**/
232 
233 #define BOOST_VMD_DETAIL_DATA_EQUAL_STATE_COMP_PUSH_CREATE(d,state) \
234     BOOST_VMD_DETAIL_DATA_EQUAL_OP_SUCCESS \
235         ( \
236         d, \
237         BOOST_PP_TUPLE_REPLACE_D \
238             ( \
239             d, \
240             state, \
241             6, \
242             (BOOST_VMD_DETAIL_DATA_EQUAL_STATE_INDEX(state)) \
243             ) \
244         ) \
245 /**/
246 
247 #define BOOST_VMD_DETAIL_DATA_EQUAL_STATE_COMP_PUSH_ADD(d,state) \
248     BOOST_VMD_DETAIL_DATA_EQUAL_OP_SUCCESS \
249         ( \
250         d, \
251         BOOST_PP_TUPLE_REPLACE_D \
252             ( \
253             d, \
254             state, \
255             6, \
256             BOOST_PP_TUPLE_PUSH_BACK \
257                 ( \
258                 BOOST_VMD_DETAIL_DATA_EQUAL_STATE_COMP(state), \
259                 BOOST_VMD_DETAIL_DATA_EQUAL_STATE_INDEX(state) \
260                 ) \
261             ) \
262         ) \
263 /**/
264 
265 #define BOOST_VMD_DETAIL_DATA_EQUAL_STATE_COMP_PUSH(d,state) \
266     BOOST_PP_IIF \
267         ( \
268         BOOST_VMD_DETAIL_DATA_EQUAL_STATE_COMP_EMPTY(state), \
269         BOOST_VMD_DETAIL_DATA_EQUAL_STATE_COMP_PUSH_CREATE, \
270         BOOST_VMD_DETAIL_DATA_EQUAL_STATE_COMP_PUSH_ADD \
271         ) \
272     (d,state) \
273 /**/
274 
275 #define BOOST_VMD_DETAIL_DATA_EQUAL_STATE_GET_INDEX(d,state) \
276     BOOST_PP_IIF \
277         ( \
278         BOOST_VMD_DETAIL_DATA_EQUAL_STATE_COMP_PROCESSING(d,state), \
279         BOOST_VMD_DETAIL_DATA_EQUAL_STATE_COMP_INDEX, \
280         BOOST_VMD_DETAIL_DATA_EQUAL_STATE_INDEX \
281         ) \
282     (state) \
283 /**/
284 
285 #define BOOST_VMD_DETAIL_DATA_EQUAL_STATE_GET_FIRST_ELEMENT(d,state) \
286     BOOST_VMD_DETAIL_DATA_EQUAL_GET_ELEM \
287         ( \
288         d, \
289         BOOST_VMD_DETAIL_DATA_EQUAL_STATE_GET_INDEX(d,state), \
290         BOOST_VMD_DETAIL_DATA_EQUAL_STATE_FIRST(state), \
291         BOOST_VMD_DETAIL_DATA_EQUAL_STATE_TYPE(state) \
292         ) \
293 /**/
294 
295 #define BOOST_VMD_DETAIL_DATA_EQUAL_STATE_GET_SECOND_ELEMENT(d,state) \
296     BOOST_VMD_DETAIL_DATA_EQUAL_GET_ELEM \
297         ( \
298         d, \
299         BOOST_VMD_DETAIL_DATA_EQUAL_STATE_GET_INDEX(d,state), \
300         BOOST_VMD_DETAIL_DATA_EQUAL_STATE_SECOND(state), \
301         BOOST_VMD_DETAIL_DATA_EQUAL_STATE_TYPE(state) \
302         ) \
303 /**/
304 
305 #define BOOST_VMD_DETAIL_DATA_EQUAL_PRED(d,state) \
306     BOOST_PP_BITAND \
307         ( \
308         BOOST_PP_EQUAL_D \
309             ( \
310             d, \
311             BOOST_VMD_DETAIL_DATA_EQUAL_STATE_RESULT(state), \
312             1 \
313             ), \
314         BOOST_PP_BITOR \
315             ( \
316             BOOST_PP_NOT_EQUAL_D \
317                 ( \
318                 d, \
319                 BOOST_VMD_DETAIL_DATA_EQUAL_STATE_INDEX(state), \
320                 BOOST_VMD_DETAIL_DATA_EQUAL_STATE_SIZE(state) \
321                 ), \
322             BOOST_PP_COMPL \
323                 ( \
324                 BOOST_VMD_DETAIL_DATA_EQUAL_STATE_COMP_EMPTY(state) \
325                 ) \
326             ) \
327         ) \
328 /**/
329 
330 #define BOOST_VMD_DETAIL_DATA_EQUAL_OP_SUCCESS_NCP(d,state) \
331     BOOST_PP_TUPLE_REPLACE_D \
332         ( \
333         d, \
334         state, \
335         5, \
336         BOOST_PP_INC(BOOST_VMD_DETAIL_DATA_EQUAL_STATE_INDEX(state)) \
337         ) \
338 /**/
339 
340 #define BOOST_VMD_DETAIL_DATA_EQUAL_OP_SUCCESS(d,state) \
341     BOOST_PP_IIF \
342         ( \
343         BOOST_VMD_DETAIL_DATA_EQUAL_STATE_COMP_PROCESSING(d,state), \
344         BOOST_VMD_DETAIL_DATA_EQUAL_STATE_COMP_POP, \
345         BOOST_VMD_DETAIL_DATA_EQUAL_OP_SUCCESS_NCP \
346         ) \
347     (d,state) \
348 /**/
349 
350 #define BOOST_VMD_DETAIL_DATA_EQUAL_OP_FAILURE(d,state) \
351     BOOST_PP_TUPLE_REPLACE_D \
352         ( \
353         d, \
354         state, \
355         0, \
356         0 \
357         ) \
358 /**/
359 
360 #define BOOST_VMD_DETAIL_DATA_EQUAL_OP_RESULT(d,state,result) \
361     BOOST_PP_IIF \
362         ( \
363         BOOST_PP_EQUAL_D(d,result,0), \
364         BOOST_VMD_DETAIL_DATA_EQUAL_OP_FAILURE, \
365         BOOST_PP_IIF \
366             ( \
367             BOOST_PP_EQUAL_D(d,result,1), \
368             BOOST_VMD_DETAIL_DATA_EQUAL_OP_SUCCESS, \
369             BOOST_VMD_DETAIL_DATA_EQUAL_STATE_COMP_PUSH \
370             ) \
371         ) \
372     (d,state) \
373 /**/
374 
375 #define BOOST_VMD_DETAIL_DATA_EQUAL_TYPE(emf,ems,vtype) \
376     BOOST_PP_BITAND \
377         ( \
378         BOOST_VMD_DETAIL_EQUAL_TYPE \
379             ( \
380             BOOST_VMD_GET_TYPE(emf), \
381             vtype \
382             ), \
383         BOOST_VMD_DETAIL_EQUAL_TYPE \
384             ( \
385             BOOST_VMD_GET_TYPE(ems), \
386             vtype \
387             ) \
388         ) \
389 /**/
390 
391 #define BOOST_VMD_DETAIL_DATA_EQUAL_TYPE_D(d,emf,ems,vtype) \
392     BOOST_PP_BITAND \
393         ( \
394         BOOST_VMD_DETAIL_EQUAL_TYPE_D \
395             ( \
396             d, \
397             BOOST_VMD_GET_TYPE(emf), \
398             vtype \
399             ), \
400         BOOST_VMD_DETAIL_EQUAL_TYPE_D \
401             ( \
402             d, \
403             BOOST_VMD_GET_TYPE(ems), \
404             vtype \
405             ) \
406         ) \
407 /**/
408 
409 #endif /* BOOST_VMD_DETAIL_DATA_EQUAL_COMMON_HPP */
410