vmd_sequence.qbk 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  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_sequence Parsing sequences]
  8. In the normal use of Boost PP data is passed as arguments to a macro in
  9. discrete units so that each parameter expects a single data type. A typical
  10. macro might be:
  11. #define AMACRO(anumber,atuple,anidentifier) someoutput
  12. where the 'atuple', having the form of ( data1, data2, data3 ), itself may
  13. contain different data types of elements.
  14. This is the standard macro design and internally it is the easiest way
  15. to pass macro data back and forth. The Boost PP library has a rich set of
  16. functionality to deal with all of its high-level data types, and variadic data,
  17. with its own simpler functionality, also offers another alternative to
  18. representing data.
  19. Occasionally designers of macros, especially for the use of others programmers within
  20. a particular library, have expressed the need for a macro parameter to allow a more
  21. C/C++ like syntax where a single parameter might mimic a C++ function-call or a
  22. C-like type modification syntax, or some other more complicated construct.
  23. Something along the lines of:
  24. areturn afunction ( aparameter1, aparameter2, aparameter3 )
  25. or
  26. ( type ) data
  27. etc. etc.
  28. In other words, from a syntactical level when designing possible macro input,
  29. is it possible to design parameter data to look more like C/C++ when macros
  30. are used in a library and still do a certain amount of preprocessor metaprogramming
  31. with such mixed token input ?
  32. VMD has functionality which allows more than one type of preprocessing token,
  33. excluding an 'empty' token which always refers to some entire input, to be part of a
  34. single parameter of input data. These preprocessing tokens as a single parameter are
  35. syntactically a consecutive series of data. The single limitation of this consecutive
  36. series of data is that each top-level part of the data of this series is of some VMD data type.
  37. What this means is that if some input consists of a series of data types it is possible
  38. to extract the data for each data type in that series.
  39. In practicality what this means is that, given the examples just above, if
  40. 'areturn', 'afunction', and 'data' are identifiers it would be possible to
  41. parse either of the two inputs above so that one could identify the different
  42. data types involved and do preprocessor metaprogramming based on those results.
  43. [heading Sequence definition]
  44. I will be calling such input data, which consists of all top-level data types in a series,
  45. by the term of a 'sequence'. Each separate data type in the sequence is called an 'element'.
  46. In this definition of a 'sequence' we can have 0 or more elements, so that a sequence
  47. is a general name for any VMD input. A sequence is therefore
  48. any input VMD can parse, whether it is emptiness, a single element, or more than one
  49. element in a series. Therefore when we speak of VMD macros parsing input data we are
  50. really speaking of VMD macros parsing a sequence. A sequence can therefore also be part of
  51. a Boost PP composite data type, or variadic data, and VMD can still parse such an embedded
  52. sequence if asked to do so.
  53. [heading Sequence parsing]
  54. Parsing a sequence means that VMD can step through each element of a sequence
  55. sequentially, determine the type and data of each element, then move on to the
  56. next element. Parsing is sequential and can only be done in a forward direction,
  57. but it can be done any number of times. In C++ iterator terms parsing of a
  58. sequence is a forward iterator.
  59. Working with a sequence is equivalent to using VMD macros 'generically'.
  60. Before I give an explanation of how to use a sequence using VMD generic
  61. functionality I would like to make two points:
  62. * The possibility of working with a sequence which contains more than one
  63. data type can be easily abused. In general
  64. keeping things simple is usually better than making things overly complicated
  65. when it comes to the syntactical side of things in a computer language. A macro
  66. parameter syntactical possibility has to be understandable to be used.
  67. * Using VMD to parse the individual data types of a sequence takes more
  68. preprocessing time than functionality offered with Boost PP data types,
  69. because it is based on forward access through each top-level type of the sequence.
  70. The one constraint in a sequence is that the top-level must
  71. consist of VMD data types, in other words preprocessor tokens which VMD understands.
  72. By top-level it is meant that a Boost PP composite data may have elements which
  73. VMD cannot parse but as long as the input consists of the composite data types and
  74. not the inner unparsable elements, VMD can parse the input.
  75. Therefore if preprocessor data is one of the examples above, you will be successful
  76. in using VMD. However if your preprocessor data takes the form of:
  77. &name identifier ( param )
  78. or
  79. identifier "string literal"
  80. or
  81. identifier + number
  82. or
  83. identifier += 4.3
  84. etc. etc.
  85. you will not be able to parse the data using VMD since '&', "string literal",
  86. '+', '+=', and "4.3" are preprocessor tokens which are not VMD top-level data types and
  87. therefore VMD cannot handle them at the parsing level. You can still of course
  88. pass such data as preprocessing input to macros but you cannot use VMD to recognize
  89. the parts of such data.
  90. This is similar to the fact that VMD cannot tell you what type preprocessor data
  91. is as a whole, using any of the VMD identifying macros already discussed, if the
  92. type is not one that VMD can handle.
  93. On the other hand you can still use VMD to parse such tokens in the input if you use
  94. Boost PP data types as top-level data types to do so. Such as:
  95. ( &name ) identifier ( param )
  96. or
  97. identifier ( "string literal" )
  98. or
  99. identifier ( + ) number
  100. or
  101. identifier ( += ) 4 ( . ) 3
  102. The succeeding topics explain the VMD functionality for parsing a sequence
  103. for each individual VMD data type in that sequence.
  104. [heading Sequence types]
  105. A VMD sequence can be seen as one of either three general types:
  106. # An empty sequence
  107. # A single element sequence
  108. # A multi-element sequence
  109. An empty sequence is merely input that is empty, what VMD calls "emptiness". Use the previously
  110. explained BOOST_VMD_IS_EMPTY macro to test for an empty sequence.
  111. #include <boost/vmd/is_empty.hpp>
  112. #define AN_EMPTY_SEQUENCE
  113. BOOST_VMD_IS_EMPTY(AN_EMPTY_SEQUENCE) will return 1
  114. The type of an empty sequence is BOOST_VMD_TYPE_EMPTY.
  115. A single element sequence is a single VMD data type. This is what
  116. we have been previously discussing as data which VMD can parse in this
  117. documentation with our identifying macros. You can use the
  118. BOOST_VMD_IS_UNARY macro to test for a single element sequence.
  119. #include <boost/vmd/is_unary.hpp>
  120. #define A_SINGLE_ELEMENT_SEQUENCE (1,2)
  121. BOOST_VMD_IS_UNARY(A_SINGLE_ELEMENT_SEQUENCE) will return 1
  122. The type of a single element sequence is the type of the individual data type.
  123. In our example above the type of A_SINGLE_ELEMENT_SEQUENCE is BOOST_VMD_TYPE_TUPLE.
  124. A multi-element sequence consists of more than one data type. This is the
  125. "new" type which VMD can parse. You can use the BOOST_VMD_IS_MULTI macro
  126. to test for a multi-element sequence.
  127. #define A_MULTI_ELEMENT_SEQUENCE (1,2) (1)(2) 45
  128. The A_MULTI_ELEMENT_SEQUENCE consists of a tuple followed by a seq followed by a number.
  129. #include <boost/vmd/is_multi.hpp>
  130. BOOST_VMD_IS_MULTI(A_MULTI_ELEMENT_SEQUENCE) will return 1
  131. The type of a multi-element sequence is always BOOST_VMD_TYPE_SEQUENCE.
  132. The type of a sequence can be obtained generically with the BOOST_VMD_GET_TYPE
  133. macro. We will be explaining this further in the documentation.
  134. [heading Sequence size]
  135. The size of any sequence can be accessed using the BOOST_VMD_SIZE macro.
  136. For an empty sequence the size is always 0. For a single element sequence
  137. the size is always 1. For a multi-element sequence the size is the number
  138. of individual top-level data types in the sequence.
  139. #include <boost/vmd/size.hpp>
  140. BOOST_VMD_SIZE(AN_EMPTY_SEQUENCE) will return 0
  141. BOOST_VMD_SIZE(A_SINGLE_ELEMENT_SEQUENCE) will return 1
  142. BOOST_VMD_SIZE(A_MULTI_ELEMENT_SEQUENCE) will return 3
  143. [heading Using VMD to parse sequence input]
  144. For a VMD sequence essentially two ways of parsing into individual data
  145. types are offered by the VMD library:
  146. # The sequence can be converted to any of the Boost PP data types, or
  147. to variadic data, where each individual data type in the sequence becomes
  148. a separate element of the particular composite data type chosen. The
  149. conversion to a particular Boost PP data type or variadic data is slow,
  150. because it is based on forward access through each top-level type of the sequence,
  151. but afterwards accessing any individual element is as fast as accessing
  152. any element in the Boost PP data type or among variadic data.
  153. # The sequence can be accessed directly through its individual elements.
  154. This is slower than accessing an element of a Boost PP data type
  155. or variadic data but offers conceptual access to the original sequence
  156. as a series of elements.
  157. These two techniques will be discussed in succeeding topics.
  158. [include vmd_sequence_convert.qbk]
  159. [include vmd_sequence_access.qbk]
  160. [endsect]