Home | Libraries | People | FAQ | More |
While parsing a v-sequence starting with a v-number can always be done for the fairly simple v-sequences situations previously mentioned, it is more challenging to do so when the v-number is followed by one or more other v-numbers, or one or more v-identifiers, or a combination of the two possible v-sequences. To do this one needs to use optional parameters to the BOOST_VMD_NUMBER macro.
Recall that the BOOST_VMD_NUMBER macro takes a single mandatory parameter, the v-sequence. The BOOST_VMD_NUMBER macro also takes optional parameters to parse the more difficult sequences involving further v-numbers or v-identifiers.
Before I explain the optional parameters here are the forms of the more difficult v-sequences which BOOST_VMD_NUMBER can parse with their help:
v-number v-numbers ... tuple-or-end-of-input v-number v-identifiers ... tuple-or-end-of-input v-number v-numbers ... v-identifiers ... tuple-or-end-of-input
These three supported situations also allow * a v-number to be followed by from one to four additional v-numbers followed by a tuple, or end-of-sequence. * a v-number to be followed by from one to five v-identifiers followed by a tuple or end-of-sequence. * a v-number to be followed by from one to four additional v-numbers, followed by from one to five v-identifiers before encountering a tuple or end-of-sequence.
Parsing input sequences beginning with v-number(s), immediately followed by v-identifier(s), immediately followed by further v-number(s) are not supported. But of course this can be modified by having v-number(s), immediately followed followed by v-identifier(s), immediately followed followed by a tuple, followed by further v-number(s), which is supported by the third case above.
In order to find a v-number at the beginning of a v-sequence when it could be followed by a maximum of four subsequent v-numbers, the optional 2nd parameter to BOOST_VMD_NUMBER must be used. This is our v-sequence of:
v-number v-numbers ... tuple-or-end-of-input
In this case the optional 2nd parameter is just a number, with a maximum of four, which specifies the maximum number of subsequent v-numbers which can follow the beginning v-number. You can specify a number which is greater than the actual number of v-numbers which follow the beginning v-identifier and the parsing will still succeed as long as the beginning v-number is found. But if you specify a number that is less than the number of subsequent v-numbers, the parsing will fail. You never need to specify the optional 2nd parameter as a number if the v-number in the beginning of a v-sequence is followed by a tuple or end-of-input, but you are allowed to do so.
Some examples:
#define SOME_INPUT_N7 37 142 (telem1,telem2) BOOST_VMD_NUMBER ( SOME_INPUT_N7 /* v-sequence */, /* The optional 2nd parameter as a number */ 3 /* succeeds because there are less than or equal to 3 following v-numbers */ )
expands to (37,142 (telem1,telem2))
#define SOME_INPUT_N8 25 99 234 56 BOOST_VMD_NUMBER ( SOME_INPUT_N8 /* v-sequence */, /* The optional 2nd parameter as a number */ 2 /* fails because there are more than 2 following v-numbers */ )
expands to (,)
#define SOME_INPUT_N9 226 BOOST_VMD_NUMBER ( SOME_INPUT_N9 /* v-sequence */, /* The optional 2nd parameter as a number */ 1 /* Not needed but it does no harm */ )
expands to (226,)
The optional 2nd parameter is also used in order to find a v-number at the beginning of a v-sequence when it is followed by one or more v-identifiers before a tuple or end-of-sequence is encountered. This is our v-sequence of:
v-number v-identifiers ... tuple-or-end-of-input
This optional 2nd parameter is a seq, where each element is a v-key to possible subsequent v-identifiers. You can specify more seq elements than are actually found in the v-sequence as long as the seq elements specified match v-identifiers that are found.
Some examples:
#define BOOST_VMD_MAP_MYLIB_KEY6_APPLE #define BOOST_VMD_MAP_MYLIB_KEY7_BANANA #define BOOST_VMD_MAP_MYLIB_KEY8_CHERRY #define BOOST_VMD_MAP_MYLIB_KEY9_ORANGE #define BOOST_VMD_MAP_MYLIB_KEY10_PEACH #define BOOST_VMD_MAP_MYLIB_KEY11_PEAR #define SOME_INPUT_N10 165 CHERRY BANANA PEACH (telem1,telem2) BOOST_VMD_NUMBER ( SOME_INPUT_N10 /* v-sequence */, /* The optional 2nd parameter as a seq */ ((MYLIB_KEY8_ /* CHERRY, which matches */,MYLIB_KEY7_ /* BANANA */)) ((MYLIB_KEY11_ /* PEAR */,MYLIB_KEY7_ /* BANANA, which matches */)) (MYLIB_KEY10_ /* PEACH, which matches */) ((MYLIB_KEY6_ /* APPLE */,MYLIB_KEY9_ /* ORANGE */)) /* This last seq element is extraneous for the particular input because the first three seq elements cover the three v-identifiers. But this shows you can have extra seq elements without affecting the ability to match */ )
expands to (165,CHERRY BANANA PEACH (telem1,telem2))
#define SOME_INPUT_N11 27 PEAR ORANGE APPLE PEACH BOOST_VMD_NUMBER ( SOME_INPUT_N11 /* v-sequence */, /* The optional 2nd parameter as a seq */ ((MYLIB_KEY7_ /* BANANA */,MYLIB_KEY11_ /* PEAR, which matches */)) (MYLIB_KEY9_ /* ORANGE, which matches */) ((MYLIB_KEY7_ /* BANANA */,MYLIB_KEY6_ /* APPLE, which matches */)) /* No subsequent seq element to match PEACH so beginning v-identifier is not found */ )
expands to (,)
The optional 3rd parameter is used in order to find a v-number at the beginning of the v-sequence when it is followed by one to four v-numbers and one to five v-identifiers before a tuple or end-of-sequence. This is our v-sequence of:
v-number v-numbers ... v-identifiers ... tuple-or-end-of-input
In this situation the optional 2nd parameter is the number we used for subsequent v-numbers and the optional 3rd parameter is the seq we used for subsequent v-identifiers. When we use both optional parameters we may still succeed if we encounter a tuple or end-of-sequence before the v-number matches are exhausted or, once we start matching v-identifiers, if we encounter a tuple or end-of-sequence before the v-identifiers matches are exhausted. But once we encounter v-identifiers in the v-sequence, we need to have matched exactly the number of v-numbers specified.
Some examples, using our key-identifier macros above:
#define SOME_INPUT_N12 25 99 234 CHERRY BANANA (telem1,telem2) BOOST_VMD_NUMBER ( SOME_INPUT_N12 /* v-sequence */, 2, which matches the 2 subsequent v-numbers (MYLIB_KEY8_ /* CHERRY, which matches */) ((MYLIB_KEY11_ /* PEAR */,MYLIB_KEY7_ /* BANANA, which matches */)) )
expands to (25,99 234 CHERRY BANANA (telem1,telem2))
#define SOME_INPUT_N13 8 253 PEAR ORANGE BOOST_VMD_NUMBER ( SOME_INPUT_N13 /* v-sequence */, 1, which matches the 1 subsequent v-number ((MYLIB_KEY11_ /* PEAR, which matches */, MYLIB_KEY8_ /* CHERRY*/)) ((MYLIB_KEY7_ /* BANANA */,MYLIB_KEY9_ /* ORANGE, which matches */)) ((MYLIB_KEY9_ /* ORANGE */,MYLIB_KEY8_ /* CHERRY */)) /* This last seq element is extraneous for the particular input because the first two seq element covers the subsequent v-identifiers. This shows you can have extra seq elements without affecting the ability to match as long as you have the correct number of subsequent v-numbers specified. */ )
expands to (8,253 PEAR ORANGE)
#define SOME_INPUT_N14 37 42 156 254 BOOST_VMD_NUMBER ( SOME_INPUT_N14 /* v-sequence */, 4, /* Succeeds because he number is greater or equal to the amount of subsequent v-numbers and there are no subsequent v-identifiers in the input before a tuple or end-of-sequence is encoumntered */ /* The 3rd parameter seq is extraneous for the given input because there are no subsequent v-identifiers to match, but do not negate the match because it i specified */ ((MYLIB_KEY7_ /* BANANA */,MYLIB_KEY9_ /* ORANGE */,MYLIB_KEY10_ /* PEACH */)) (MYLIB_KEY11_ /* PEAR, which matches */) (MYLIB_KEY8_ /* CHERRY */) )
expands to (37,42 156 254)
#define SOME_INPUT_N15 142 50 133 29 BANANA CHERRY BOOST_VMD_NUMBER ( SOME_INPUT_N15 /* v-sequence */, 4, /* Fails because there must be exactly the correct number of subsequent v-numbers if there are subsequent v-identifiers */ (MYLIB_KEY7_ /* BANANA, which matches */) ((MYLIB_KEY7_ /* BANANA */,MYLIB_KEY8_ /* CHERRY, which matches */,MYLIB_KEY10_ /* PEACH */)) )
expands to (,)