vmd_modifiers_identifier.qbk 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. [/
  2. (C) Copyright Edward Diener 2011-2015
  3. Distributed under the Boost Software License, Version 1.0.
  4. (See accompanying file LICENSE_1_0.txt or copy at
  5. http://www.boost.org/LICENSE_1_0.txt).
  6. ]
  7. [section:vmd_modifiers_identifier Identifier modifiers]
  8. Identifier modifiers are optional parameters which
  9. specify a set of identifiers to search in order to look
  10. for a particular identifier match rather than just any
  11. identifier.
  12. [heading Usage with BOOST_VMD_IS_IDENTIFIER]
  13. Once we have both registered and pre-detected an identifier we can test whether
  14. an identifier is a particular identifier using BOOST_VMD_IS_IDENTIFER and
  15. identifier modifiers. We do this by passing optional parameter(s) to
  16. BOOST_VMD_IS_IDENTIFER. The optional parameter(s) are either a single tuple of
  17. possible identifiers we are trying to match, or the individual identifiers
  18. themselves as separate parameters.
  19. Using the optional parameter(s) with BOOST_VMD_IS_IDENTIFER we are asking
  20. not only if our input is any of the registered identifiers but also if it is one
  21. of a number of pre-detected identifiers.
  22. As an example:
  23. #include <boost/vmd/is_identifier.hpp>
  24. #define BOOST_VMD_REGISTER_yellow (yellow)
  25. #define BOOST_VMD_REGISTER_green (green)
  26. #define BOOST_VMD_REGISTER_blue (blue)
  27. #define BOOST_VMD_REGISTER_red (red)
  28. #define BOOST_VMD_DETECT_yellow_yellow
  29. #define BOOST_VMD_DETECT_green_green
  30. #define BOOST_VMD_DETECT_blue_blue
  31. BOOST_VMD_IS_IDENTIFIER(some_input,yellow) // returns 1 only if 'some_input is 'yellow', else returns 0
  32. BOOST_VMD_IS_IDENTIFIER(some_input,yellow,blue) // returns 1 only if 'some_input is 'yellow' or 'blue', else returns 0
  33. BOOST_VMD_IS_IDENTIFIER(some_input,(yellow,green)) // returns 1 if 'some_input' is 'yellow' or 'green', else returns 0
  34. BOOST_VMD_IS_IDENTIFIER(some_input,red)
  35. // always returns 0, even if 'some_input' is 'red' since 'red' has not been pre-detected
  36. whereas
  37. BOOST_VMD_IS_IDENTIFIER(some_input) // returns 1 if 'some_input' is 'red' since 'red' has been registered
  38. If you invoke BOOST_VMD_IS_IDENTIFIER with the optional parameter(s), the invocation will
  39. only return 1 if the input matches one the identifier(s) of the optional parameters and the
  40. identifier it matches has been registered and pre-detected.
  41. Both VMD numbers and v-types are identifier subtypes so you can also use them
  42. as identifier modifiers. You do not have to register or pre-detect VMD numbers
  43. or v-types since VMD has already done that for you.
  44. As an example of using VMD numbers or v-types as identifier modifiers with BOOST_VMD_IS_IDENTIFIER:
  45. BOOST_VMD_IS_IDENTIFIER(some_input,1,3,5) // returns 1 only if 'some_input' is 1 or 3 or 5, else returns 0
  46. BOOST_VMD_IS_IDENTIFIER(some_input,BOOST_VMD_TYPE_TUPLE,BOOST_VMD_TYPE_LIST,59)
  47. // returns 1 only if 'some_input is the v-type BOOST_VMD_TYPE_TUPLE or the v-type BOOST_VMD_TYPE_LIST or 59, else returns 0
  48. [heading Usage with BOOST_VMD_ELEM]
  49. When we use the specific filter modifier BOOST_VMD_TYPE_IDENTIFIER as an optional
  50. parameter of BOOST_VMD_ELEM we are asking for a particular element of a sequence
  51. as long as it is a VMD identifier. With that specific filter modifier
  52. BOOST_VMD_TYPE_IDENTIFIER we can use identifier modifiers to ask for a particular
  53. element of a sequence as long as it matches one of our identifier modifiers. If
  54. the specific filter modifier BOOST_VMD_TYPE_IDENTIFIER is not being used then all
  55. identifier modifiers are ignored.
  56. The syntax for specifying identifier modifiers using BOOST_VMD_ELEM is
  57. exactly the same as the equivalent feature of the BOOST_VMD_IS_IDENTIFIER
  58. macro explained just previously. Optional parameters in the form of
  59. identifiers can be specified either singly any number of times or once
  60. as part of a tuple. For an identifier found as a sequence element to
  61. match against one of these possible identifiers, the possible
  62. identifiers must be both registered and pre-detected.
  63. Since filter modifiers, which are v-types, are also identifiers, if
  64. you want to use v-types as identifier modifiers you must use the form
  65. which places all identifier modifiers as part of a tuple. Otherwise any
  66. v-types specified singly as optional parameters are seen as filter
  67. modifiers and never as identifier modifiers. VMD numbers are also identifiers
  68. and may be used as identifier modifiers, but in this case VMD numbers as
  69. identifier modifiers do not need to be part of a tuple to be detected.
  70. Let's see how this works:
  71. #include <boost/vmd/elem.hpp>
  72. #define BOOST_VMD_REGISTER_ANAME (ANAME)
  73. #define BOOST_VMD_REGISTER_APLACE (APLACE)
  74. #define BOOST_VMD_REGISTER_ACOUNTRY (ACOUNTRY)
  75. #define BOOST_VMD_DETECT_ANAME_ANAME
  76. #define BOOST_VMD_DETECT_APLACE_APLACE
  77. #define A_SEQUENCE (1,2,3) ANAME 46 BOOST_VMD_TYPE_SEQ ACOUNTRY
  78. BOOST_VMD_ELEM(1,A_SEQUENCE) will return 'ANAME'
  79. BOOST_VMD_ELEM(1,A_SEQUENCE,BOOST_VMD_TYPE_IDENTIFIER) will return 'ANAME'
  80. BOOST_VMD_ELEM(1,A_SEQUENCE,BOOST_VMD_TYPE_IDENTIFIER,APLACE,ACOUNTRY) will return emptiness
  81. BOOST_VMD_ELEM(1,A_SEQUENCE,BOOST_VMD_TYPE_IDENTIFIER,ANAME,APLACE,ACOUNTRY) will return 'ANAME'
  82. BOOST_VMD_ELEM(1,A_SEQUENCE,BOOST_VMD_TYPE_IDENTIFIER,(APLACE,ACOUNTRY,ANAME)) will return 'ANAME'
  83. BOOST_VMD_ELEM(4,A_SEQUENCE) will return 'ACOUNTRY'
  84. BOOST_VMD_ELEM(4,A_SEQUENCE,BOOST_VMD_TYPE_IDENTIFIER) will return 'ACOUNTRY'
  85. BOOST_VMD_ELEM(4,A_SEQUENCE,BOOST_VMD_TYPE_IDENTIFIER,ACOUNTRY,ANAME)
  86. will return emptiness since ACOUNTRY is not pre-detected
  87. Let us illustrate the case where VMD identifiers can be represented as either
  88. filter modifiers or identifier modifiers.
  89. Using the sequence above:
  90. #include <boost/vmd/elem.hpp>
  91. BOOST_VMD_ELEM(3,A_SEQUENCE) will return the BOOST_VMD_TYPE_SEQ type
  92. BOOST_VMD_ELEM(3,A_SEQUENCE,BOOST_VMD_TYPE_IDENTIFIER)
  93. will return the BOOST_VMD_TYPE_SEQ type since a type is an identifier
  94. BOOST_VMD_ELEM(3,A_SEQUENCE,BOOST_VMD_TYPE_IDENTIFIER,BOOST_VMD_TYPE_SEQ,BOOST_VMD_TYPE_TUPLE) will return emptiness
  95. The last use of our macro returns emptiness because if there is more than one
  96. type specified as an optional parameter the last type is chosen for filtering.
  97. Since the last type for type filtering is BOOST_VMD_TYPE_TUPLE and our fourth
  98. element is a v-type and not a tuple, emptiness is returned. The syntax does not
  99. specifying filtering with identifiers as might be supposed since BOOST_VMD_TYPE_SEQ
  100. and BOOST_VMD_TYPE_TUPLE are not treated as identifier modifiers but rather as
  101. additional filter modifiers.
  102. In order to do filtering with an identifier and do it against
  103. various types themselves, since v-types are identifiers, we must
  104. use the tuple form to specify our identifier modifiers:
  105. #include <boost/vmd/elem.hpp>
  106. BOOST_VMD_ELEM(3,A_SEQUENCE,BOOST_VMD_TYPE_IDENTIFIER,(BOOST_VMD_TYPE_SEQ,BOOST_VMD_TYPE_TUPLE))
  107. will return BOOST_VMD_TYPE_SEQ
  108. Now BOOST_VMD_TYPE_SEQ and BOOST_VMD_TYPE_TUPLE are treated as identifiers
  109. modifiers to match against.
  110. [endsect]