Boost C++ Libraries Home Libraries People FAQ More

PrevUpHomeNext

Parsing v-numbers using optional parameters

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.

Complicated v-sequences

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.

Using the optional 2nd parameter

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 (,)

Using the optional 3rd parameter

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 (,)


PrevUpHomeNext