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_IDENTIFIER_HPP) 8 #define BOOST_VMD_DETAIL_IDENTIFIER_HPP 9 10 #include <boost/preprocessor/arithmetic/dec.hpp> 11 #include <boost/preprocessor/comparison/equal.hpp> 12 #include <boost/preprocessor/control/expr_iif.hpp> 13 #include <boost/preprocessor/control/iif.hpp> 14 #include <boost/preprocessor/logical/bitand.hpp> 15 #include <boost/preprocessor/logical/bitor.hpp> 16 #include <boost/preprocessor/punctuation/is_begin_parens.hpp> 17 #include <boost/preprocessor/tuple/elem.hpp> 18 #include <boost/preprocessor/variadic/elem.hpp> 19 #include <boost/vmd/identity.hpp> 20 #include <boost/vmd/is_empty.hpp> 21 #include <boost/vmd/detail/identifier_concat.hpp> 22 #include <boost/vmd/detail/is_entire.hpp> 23 #include <boost/vmd/detail/match_identifier.hpp> 24 #include <boost/vmd/detail/mods.hpp> 25 #include <boost/vmd/detail/not_empty.hpp> 26 #include <boost/vmd/detail/parens.hpp> 27 28 #define BOOST_VMD_DETAIL_IDENTIFIER_PROCESS_KEYS_SUCCESS(id,rest,keymatch,mods) \ 29 BOOST_VMD_DETAIL_IDENTIFIER_SUCCESS_MODS(id,rest,BOOST_PP_DEC(keymatch),mods) \ 30 /**/ 31 32 #define BOOST_VMD_DETAIL_IDENTIFIER_PROCESS_KEYS_FAILURE(id,rest,keymatch,mods) \ 33 BOOST_VMD_DETAIL_IDENTIFIER_FAILURE_MODS(mods) \ 34 /**/ 35 36 #define BOOST_VMD_DETAIL_IDENTIFIER_PROCESS_KEYS_TUPLE_RESULT(id,rest,keymatch,mods) \ 37 BOOST_PP_IIF \ 38 ( \ 39 BOOST_PP_EQUAL(keymatch,0), \ 40 BOOST_VMD_DETAIL_IDENTIFIER_PROCESS_KEYS_FAILURE, \ 41 BOOST_VMD_DETAIL_IDENTIFIER_PROCESS_KEYS_SUCCESS \ 42 ) \ 43 (id,rest,keymatch,mods) \ 44 /**/ 45 46 #define BOOST_VMD_DETAIL_IDENTIFIER_PROCESS_KEYS_TUPLE_RESULT_D(d,id,rest,keymatch,mods) \ 47 BOOST_PP_IIF \ 48 ( \ 49 BOOST_PP_EQUAL_D(d,keymatch,0), \ 50 BOOST_VMD_DETAIL_IDENTIFIER_PROCESS_KEYS_FAILURE, \ 51 BOOST_VMD_DETAIL_IDENTIFIER_PROCESS_KEYS_SUCCESS \ 52 ) \ 53 (id,rest,keymatch,mods) \ 54 /**/ 55 56 #define BOOST_VMD_DETAIL_IDENTIFIER_PROCESS_KEYS_TUPLE(id,rest,keytuple,mods) \ 57 BOOST_VMD_DETAIL_IDENTIFIER_PROCESS_KEYS_TUPLE_RESULT \ 58 ( \ 59 id, \ 60 rest, \ 61 BOOST_VMD_DETAIL_MATCH_IDENTIFIER(id,keytuple), \ 62 mods \ 63 ) \ 64 /**/ 65 66 #define BOOST_VMD_DETAIL_IDENTIFIER_PROCESS_KEYS_TUPLE_D(d,id,rest,keytuple,mods) \ 67 BOOST_VMD_DETAIL_IDENTIFIER_PROCESS_KEYS_TUPLE_RESULT_D \ 68 ( \ 69 d, \ 70 id, \ 71 rest, \ 72 BOOST_VMD_DETAIL_MATCH_IDENTIFIER_D(d,id,keytuple), \ 73 mods \ 74 ) \ 75 /**/ 76 77 #define BOOST_VMD_DETAIL_IDENTIFIER_MAKE_SPLIT(tuple) \ 78 ( \ 79 BOOST_PP_TUPLE_ELEM \ 80 ( \ 81 0, \ 82 BOOST_PP_TUPLE_ELEM(0,tuple) \ 83 ), \ 84 BOOST_PP_TUPLE_ELEM(1,tuple) \ 85 ) \ 86 /**/ 87 88 #define BOOST_VMD_DETAIL_IDENTIFIER_SPLIT_SEQUENCE_CONCAT_DATA(tuple) \ 89 BOOST_VMD_IDENTITY_RESULT \ 90 ( \ 91 BOOST_PP_IIF \ 92 ( \ 93 BOOST_VMD_IS_EMPTY \ 94 ( \ 95 BOOST_PP_TUPLE_ELEM(0,tuple) \ 96 ), \ 97 BOOST_VMD_IDENTITY(tuple), \ 98 BOOST_VMD_DETAIL_IDENTIFIER_MAKE_SPLIT \ 99 ) \ 100 (tuple) \ 101 ) \ 102 /**/ 103 104 #define BOOST_VMD_DETAIL_IDENTIFIER_SPLIT_SEQUENCE_CONCAT(vcseq) \ 105 BOOST_VMD_DETAIL_IDENTIFIER_SPLIT_SEQUENCE_CONCAT_DATA \ 106 ( \ 107 BOOST_VMD_DETAIL_PARENS(vcseq,BOOST_VMD_RETURN_AFTER) \ 108 ) \ 109 /**/ 110 111 #define BOOST_VMD_DETAIL_IDENTIFIER_GETID_TID(tid) \ 112 BOOST_VMD_IDENTITY_RESULT \ 113 ( \ 114 BOOST_PP_IIF \ 115 ( \ 116 BOOST_VMD_IS_EMPTY(tid), \ 117 BOOST_VMD_IDENTITY(tid), \ 118 BOOST_PP_TUPLE_ELEM \ 119 ) \ 120 (0,tid) \ 121 ) \ 122 /**/ 123 124 #define BOOST_VMD_DETAIL_IDENTIFIER_GETID_SEQUENCE(vseq) \ 125 BOOST_VMD_DETAIL_IDENTIFIER_GETID_TID \ 126 ( \ 127 BOOST_VMD_DETAIL_PARENS(BOOST_VMD_DETAIL_IDENTIFIER_CONCATENATE(vseq)) \ 128 ) \ 129 /**/ 130 131 #define BOOST_VMD_DETAIL_IDENTIFIER_SPLIT_SEQUENCE(vseq) \ 132 BOOST_VMD_DETAIL_IDENTIFIER_SPLIT_SEQUENCE_CONCAT \ 133 ( \ 134 BOOST_VMD_DETAIL_IDENTIFIER_CONCATENATE(vseq) \ 135 ) \ 136 /**/ 137 138 #define BOOST_VMD_DETAIL_IDENTIFIER_PROCESS_KEYS(id,rest,mods) \ 139 BOOST_VMD_DETAIL_IDENTIFIER_PROCESS_KEYS_TUPLE \ 140 ( \ 141 id, \ 142 rest, \ 143 BOOST_VMD_DETAIL_MODS_RESULT_OTHER(mods), \ 144 mods \ 145 ) \ 146 /**/ 147 148 #define BOOST_VMD_DETAIL_IDENTIFIER_PROCESS_KEYS_D(d,id,rest,mods) \ 149 BOOST_VMD_DETAIL_IDENTIFIER_PROCESS_KEYS_TUPLE_D \ 150 ( \ 151 d, \ 152 id, \ 153 rest, \ 154 BOOST_VMD_DETAIL_MODS_RESULT_OTHER(mods), \ 155 mods \ 156 ) \ 157 /**/ 158 159 #define BOOST_VMD_DETAIL_IDENTIFIER_JUST(id,rest,mods) \ 160 BOOST_VMD_DETAIL_IDENTIFIER_SUCCESS_MODS(id,rest,0,mods) \ 161 /**/ 162 163 #define BOOST_VMD_DETAIL_IDENTIFIER_JUST_D(d,id,rest,mods) \ 164 BOOST_VMD_DETAIL_IDENTIFIER_SUCCESS_MODS(id,rest,0,mods) \ 165 /**/ 166 167 #define BOOST_VMD_DETAIL_IDENTIFIER_CHECK_KEYS(id,rest,mods) \ 168 BOOST_PP_IIF \ 169 ( \ 170 BOOST_VMD_IS_EMPTY \ 171 ( \ 172 BOOST_VMD_DETAIL_MODS_RESULT_OTHER(mods) \ 173 ), \ 174 BOOST_VMD_DETAIL_IDENTIFIER_JUST, \ 175 BOOST_VMD_DETAIL_IDENTIFIER_PROCESS_KEYS \ 176 ) \ 177 (id,rest,mods) \ 178 /**/ 179 180 #define BOOST_VMD_DETAIL_IDENTIFIER_CHECK_KEYS_D(d,id,rest,mods) \ 181 BOOST_PP_IIF \ 182 ( \ 183 BOOST_VMD_IS_EMPTY \ 184 ( \ 185 BOOST_VMD_DETAIL_MODS_RESULT_OTHER(mods) \ 186 ), \ 187 BOOST_VMD_DETAIL_IDENTIFIER_JUST_D, \ 188 BOOST_VMD_DETAIL_IDENTIFIER_PROCESS_KEYS_D \ 189 ) \ 190 (d,id,rest,mods) \ 191 /**/ 192 193 #define BOOST_VMD_DETAIL_IDENTIFIER_MKEYS(mods) \ 194 BOOST_PP_BITAND \ 195 ( \ 196 BOOST_VMD_DETAIL_MODS_IS_RESULT_INDEX(mods), \ 197 BOOST_VMD_DETAIL_NOT_EMPTY \ 198 ( \ 199 BOOST_VMD_DETAIL_MODS_RESULT_OTHER(mods) \ 200 ) \ 201 ) \ 202 /**/ 203 204 #define BOOST_VMD_DETAIL_IDENTIFIER_SUCCESS_MODS(id,rest,keymatch,mods) \ 205 BOOST_PP_IIF \ 206 ( \ 207 BOOST_VMD_DETAIL_IDENTIFIER_MKEYS(mods), \ 208 BOOST_PP_IIF \ 209 ( \ 210 BOOST_VMD_DETAIL_MODS_IS_RESULT_AFTER(mods), \ 211 (id,rest,keymatch), \ 212 (id,keymatch) \ 213 ), \ 214 BOOST_PP_IIF \ 215 ( \ 216 BOOST_VMD_DETAIL_MODS_IS_RESULT_AFTER(mods), \ 217 (id,rest), \ 218 id \ 219 ) \ 220 ) \ 221 /**/ 222 223 #define BOOST_VMD_DETAIL_IDENTIFIER_FAILURE_MODS(mods) \ 224 BOOST_PP_IIF \ 225 ( \ 226 BOOST_VMD_DETAIL_IDENTIFIER_MKEYS(mods), \ 227 BOOST_PP_IIF \ 228 ( \ 229 BOOST_VMD_DETAIL_MODS_IS_RESULT_AFTER(mods), \ 230 (,,), \ 231 (,) \ 232 ), \ 233 BOOST_PP_EXPR_IIF \ 234 ( \ 235 BOOST_VMD_DETAIL_MODS_IS_RESULT_AFTER(mods), \ 236 (,) \ 237 ) \ 238 ) \ 239 /**/ 240 241 #define BOOST_VMD_DETAIL_IDENTIFIER_FAILURE_REST(id,rest,mods) \ 242 BOOST_VMD_DETAIL_IDENTIFIER_FAILURE_MODS(mods) \ 243 /**/ 244 245 #define BOOST_VMD_DETAIL_IDENTIFIER_FAILURE_REST_D(d,id,rest,mods) \ 246 BOOST_VMD_DETAIL_IDENTIFIER_FAILURE_MODS(mods) \ 247 /**/ 248 249 #define BOOST_VMD_DETAIL_IDENTIFIER_ID_REST(id,rest,mods) \ 250 BOOST_PP_IIF \ 251 ( \ 252 BOOST_VMD_IS_EMPTY(id), \ 253 BOOST_VMD_DETAIL_IDENTIFIER_FAILURE_REST, \ 254 BOOST_VMD_DETAIL_IDENTIFIER_CHECK_KEYS \ 255 ) \ 256 (id,rest,mods) \ 257 /**/ 258 259 #define BOOST_VMD_DETAIL_IDENTIFIER_ID_REST_D(d,id,rest,mods) \ 260 BOOST_PP_IIF \ 261 ( \ 262 BOOST_VMD_IS_EMPTY(id), \ 263 BOOST_VMD_DETAIL_IDENTIFIER_FAILURE_REST_D, \ 264 BOOST_VMD_DETAIL_IDENTIFIER_CHECK_KEYS_D \ 265 ) \ 266 (d,id,rest,mods) \ 267 /**/ 268 269 #define BOOST_VMD_DETAIL_IDENTIFIER_PROCESS_DATA(tuple,mods) \ 270 BOOST_VMD_DETAIL_IDENTIFIER_ID_REST \ 271 ( \ 272 BOOST_PP_TUPLE_ELEM(0,tuple), \ 273 BOOST_PP_TUPLE_ELEM(1,tuple), \ 274 mods \ 275 ) \ 276 /**/ 277 278 #define BOOST_VMD_DETAIL_IDENTIFIER_PROCESS_ID(id,mods) \ 279 BOOST_PP_IIF \ 280 ( \ 281 BOOST_VMD_IS_EMPTY(id), \ 282 BOOST_VMD_DETAIL_IDENTIFIER_FAILURE_REST, \ 283 BOOST_VMD_DETAIL_IDENTIFIER_CHECK_KEYS \ 284 ) \ 285 (id,,mods) \ 286 /**/ 287 288 #define BOOST_VMD_DETAIL_IDENTIFIER_PROCESS_ID_D(d,id,mods) \ 289 BOOST_PP_IIF \ 290 ( \ 291 BOOST_VMD_IS_EMPTY(id), \ 292 BOOST_VMD_DETAIL_IDENTIFIER_FAILURE_REST_D, \ 293 BOOST_VMD_DETAIL_IDENTIFIER_CHECK_KEYS_D \ 294 ) \ 295 (d,id,,mods) \ 296 /**/ 297 298 #define BOOST_VMD_DETAIL_IDENTIFIER_PROCESS_DATA_D(d,tuple,mods) \ 299 BOOST_VMD_DETAIL_IDENTIFIER_ID_REST_D \ 300 ( \ 301 d, \ 302 BOOST_PP_TUPLE_ELEM(0,tuple), \ 303 BOOST_PP_TUPLE_ELEM(1,tuple), \ 304 mods \ 305 ) \ 306 /**/ 307 308 #define BOOST_VMD_DETAIL_IDENTIFIER_SEQUENCE_AFTER(vseq,mods) \ 309 BOOST_VMD_DETAIL_IDENTIFIER_PROCESS_DATA \ 310 ( \ 311 BOOST_VMD_DETAIL_IDENTIFIER_SPLIT_SEQUENCE(vseq), \ 312 mods \ 313 ) \ 314 /**/ 315 316 #define BOOST_VMD_DETAIL_IDENTIFIER_SEQUENCE_AFTER_D(d,vseq,mods) \ 317 BOOST_VMD_DETAIL_IDENTIFIER_PROCESS_DATA_D \ 318 ( \ 319 d, \ 320 BOOST_VMD_DETAIL_IDENTIFIER_SPLIT_SEQUENCE(vseq), \ 321 mods \ 322 ) \ 323 /**/ 324 325 #define BOOST_VMD_DETAIL_IDENTIFIER_SEQUENCE_ID(vseq,mods) \ 326 BOOST_VMD_DETAIL_IDENTIFIER_PROCESS_ID \ 327 ( \ 328 BOOST_VMD_DETAIL_IDENTIFIER_GETID_SEQUENCE(vseq), \ 329 mods \ 330 ) \ 331 /**/ 332 333 #define BOOST_VMD_DETAIL_IDENTIFIER_SEQUENCE_ID_D(d,vseq,mods) \ 334 BOOST_VMD_DETAIL_IDENTIFIER_PROCESS_ID_D \ 335 ( \ 336 d, \ 337 BOOST_VMD_DETAIL_IDENTIFIER_GETID_SEQUENCE(vseq), \ 338 mods \ 339 ) \ 340 /**/ 341 342 #define BOOST_VMD_DETAIL_IDENTIFIER_SEQUENCE(vseq,mods) \ 343 BOOST_PP_IIF \ 344 ( \ 345 BOOST_VMD_DETAIL_MODS_IS_RESULT_AFTER(mods), \ 346 BOOST_VMD_DETAIL_IDENTIFIER_SEQUENCE_AFTER, \ 347 BOOST_VMD_DETAIL_IDENTIFIER_SEQUENCE_ID \ 348 ) \ 349 (vseq,mods) \ 350 /**/ 351 352 #define BOOST_VMD_DETAIL_IDENTIFIER_SEQUENCE_D(d,vseq,mods) \ 353 BOOST_PP_IIF \ 354 ( \ 355 BOOST_VMD_DETAIL_MODS_IS_RESULT_AFTER(mods), \ 356 BOOST_VMD_DETAIL_IDENTIFIER_SEQUENCE_AFTER_D, \ 357 BOOST_VMD_DETAIL_IDENTIFIER_SEQUENCE_ID_D \ 358 ) \ 359 (d,vseq,mods) \ 360 /**/ 361 362 #define BOOST_VMD_DETAIL_IDENTIFIER_EX_FAILURE(vseq,mods) \ 363 BOOST_VMD_DETAIL_IDENTIFIER_FAILURE_MODS(mods) \ 364 /**/ 365 366 #define BOOST_VMD_DETAIL_IDENTIFIER_EX_FAILURE_D(d,vseq,mods) \ 367 BOOST_VMD_DETAIL_IDENTIFIER_FAILURE_MODS(mods) \ 368 /**/ 369 370 #define BOOST_VMD_DETAIL_IDENTIFIER_EX(vseq,mods) \ 371 BOOST_PP_IIF \ 372 ( \ 373 BOOST_PP_BITOR \ 374 ( \ 375 BOOST_VMD_IS_EMPTY(vseq), \ 376 BOOST_PP_IS_BEGIN_PARENS(vseq) \ 377 ), \ 378 BOOST_VMD_DETAIL_IDENTIFIER_EX_FAILURE, \ 379 BOOST_VMD_DETAIL_IDENTIFIER_SEQUENCE \ 380 ) \ 381 (vseq,mods) \ 382 /**/ 383 384 #define BOOST_VMD_DETAIL_IDENTIFIER_EX_D(d,vseq,mods) \ 385 BOOST_PP_IIF \ 386 ( \ 387 BOOST_PP_BITOR \ 388 ( \ 389 BOOST_VMD_IS_EMPTY(vseq), \ 390 BOOST_PP_IS_BEGIN_PARENS(vseq) \ 391 ), \ 392 BOOST_VMD_DETAIL_IDENTIFIER_EX_FAILURE_D, \ 393 BOOST_VMD_DETAIL_IDENTIFIER_SEQUENCE_D \ 394 ) \ 395 (d,vseq,mods) \ 396 /**/ 397 398 #define BOOST_VMD_DETAIL_IDENTIFIER(...) \ 399 BOOST_VMD_DETAIL_IDENTIFIER_EX \ 400 ( \ 401 BOOST_PP_VARIADIC_ELEM(0,__VA_ARGS__), \ 402 BOOST_VMD_DETAIL_NEW_MODS(BOOST_VMD_ALLOW_INDEX,__VA_ARGS__) \ 403 ) \ 404 /**/ 405 406 #define BOOST_VMD_DETAIL_IDENTIFIER_D(d,...) \ 407 BOOST_VMD_DETAIL_IDENTIFIER_EX_D \ 408 ( \ 409 d, \ 410 BOOST_PP_VARIADIC_ELEM(0,__VA_ARGS__), \ 411 BOOST_VMD_DETAIL_NEW_MODS_D(d,BOOST_VMD_ALLOW_INDEX,__VA_ARGS__) \ 412 ) \ 413 /**/ 414 415 #define BOOST_VMD_DETAIL_IS_IDENTIFIER_MULTIPLE(...) \ 416 BOOST_VMD_DETAIL_IS_ENTIRE \ 417 ( \ 418 BOOST_VMD_DETAIL_IDENTIFIER(__VA_ARGS__,BOOST_VMD_RETURN_AFTER) \ 419 ) \ 420 /**/ 421 422 #define BOOST_VMD_DETAIL_IS_IDENTIFIER_MULTIPLE_D(d,...) \ 423 BOOST_VMD_DETAIL_IS_ENTIRE \ 424 ( \ 425 BOOST_VMD_DETAIL_IDENTIFIER_D(d,__VA_ARGS__,BOOST_VMD_RETURN_AFTER) \ 426 ) \ 427 /**/ 428 429 #endif /* BOOST_VMD_DETAIL_IDENTIFIER_HPP */ 430