vmd_whyhow.html 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. <html>
  2. <head>
  3. <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
  4. <title>Why and how to use</title>
  5. <link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
  6. <meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
  7. <link rel="home" href="../index.html" title="Chapter&#160;1.&#160;The Variadic Macro Data Library 1.9">
  8. <link rel="up" href="../index.html" title="Chapter&#160;1.&#160;The Variadic Macro Data Library 1.9">
  9. <link rel="prev" href="vmd_naming.html" title="Naming conventions">
  10. <link rel="next" href="vmd_vmacros.html" title="Using variadic macros">
  11. </head>
  12. <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
  13. <table cellpadding="2" width="100%"><tr>
  14. <td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
  15. <td align="center"><a href="../../../../../index.html">Home</a></td>
  16. <td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
  17. <td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
  18. <td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
  19. <td align="center"><a href="../../../../../more/index.htm">More</a></td>
  20. </tr></table>
  21. <hr>
  22. <div class="spirit-nav">
  23. <a accesskey="p" href="vmd_naming.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="vmd_vmacros.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
  24. </div>
  25. <div class="section">
  26. <div class="titlepage"><div><div><h2 class="title" style="clear: both">
  27. <a name="variadic_macro_data.vmd_whyhow"></a><a class="link" href="vmd_whyhow.html" title="Why and how to use">Why and how to use</a>
  28. </h2></div></div></div>
  29. <p>
  30. The VMD library provides the ability to create a macro which takes different
  31. types of parameters and can therefore generate different output depending on
  32. the parameter types as well as their values.
  33. </p>
  34. <p>
  35. This is equivalent to the way that overloaded functions provide the ability
  36. for a singularly named function to provide different functionality depending
  37. on the parameter types.
  38. </p>
  39. <p>
  40. In the case of macros, where more than one macro of the same name but different
  41. macro expansion is not allowed, a single macro name can create different expansions.
  42. </p>
  43. <p>
  44. As a simple example:
  45. </p>
  46. <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">is_seq</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  47. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">is_tuple</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  48. <span class="preprocessor">#define</span> <span class="identifier">AMACRO</span><span class="special">(</span><span class="identifier">param</span><span class="special">)</span> <span class="special">\</span>
  49. <span class="identifier">BOOST_PP_IIF</span> <span class="special">\</span>
  50. <span class="special">(</span> <span class="special">\</span>
  51. <span class="identifier">BOOST_VMD_IS_SEQ</span><span class="special">(</span><span class="identifier">param</span><span class="special">),</span> <span class="special">\</span>
  52. <span class="identifier">Seq</span><span class="special">,</span> <span class="special">\</span>
  53. <span class="identifier">BOOST_PP_IIF</span> <span class="special">\</span>
  54. <span class="special">(</span> <span class="special">\</span>
  55. <span class="identifier">BOOST_VMD_IS_TUPLE</span><span class="special">(</span><span class="identifier">param</span><span class="special">),</span> <span class="special">\</span>
  56. <span class="identifier">Tuple</span><span class="special">,</span> <span class="special">\</span>
  57. <span class="identifier">Unknown</span> <span class="special">\</span>
  58. <span class="special">)</span> <span class="special">\</span>
  59. <span class="special">)</span>
  60. </pre>
  61. <p>
  62. If the param passed is a seq the output of the macro is 'Seq'. If the param
  63. passed is a tuple the output of the macro is 'Tuple'. Otherwise the output
  64. of the macro is 'Unknown'.
  65. </p>
  66. <p>
  67. Obviously much more complicated cases can be created in which the types and
  68. values of various parameters are parsed in order to produce variable macro
  69. output depending on the input. Using variadic macros, macros with variable
  70. numbers and types of arguments give the macro programmer even greater freedom
  71. to design macros with flexibility.
  72. </p>
  73. <p>
  74. Another feature of the VMD library is the ability to parse identifiers. A system
  75. of registering identifiers which VMD can recognize has been created. Once an
  76. identifier is registered VMD can recognize it as part of macro input as an
  77. identifier and return the identifier. Furthermore VMD can compare identifiers
  78. for equality or inequality once an identifier has been pre-detected using VMD's
  79. system for pre-detecting identifiers.
  80. </p>
  81. <p>
  82. As another simple example:
  83. </p>
  84. <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">is_identifier</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  85. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_REGISTER_NAME</span> <span class="special">(</span><span class="identifier">NAME</span><span class="special">)</span>
  86. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_REGISTER_ADDRESS</span> <span class="special">(</span><span class="identifier">ADDRESS</span><span class="special">)</span>
  87. <span class="preprocessor">#define</span> <span class="identifier">AMACRO1</span><span class="special">(</span><span class="identifier">param</span><span class="special">)</span> <span class="special">\</span>
  88. <span class="identifier">BOOST_PP_IIF</span> <span class="special">\</span>
  89. <span class="special">(</span> <span class="special">\</span>
  90. <span class="identifier">BOOST_VMD_IS_IDENTIFIER</span><span class="special">(</span><span class="identifier">param</span><span class="special">),</span> <span class="special">\</span>
  91. <span class="identifier">AMACRO1_IDENTIFIER</span><span class="special">,</span> <span class="special">\</span>
  92. <span class="identifier">AMACRO1_NO_IDENTIFIER</span> <span class="special">\</span>
  93. <span class="special">)</span> <span class="special">\</span>
  94. <span class="special">(</span><span class="identifier">param</span><span class="special">)</span>
  95. <span class="preprocessor">#define</span> <span class="identifier">AMACRO1_IDENTIFIER</span><span class="special">(</span><span class="identifier">param</span><span class="special">)</span> <span class="identifier">AMACRO1_</span> <span class="special">##</span> <span class="identifier">param</span>
  96. <span class="preprocessor">#define</span> <span class="identifier">AMACRO1_NO_IDENTIFIER</span><span class="special">(</span><span class="identifier">param</span><span class="special">)</span> <span class="identifier">Parameter</span> <span class="identifier">is</span> <span class="keyword">not</span> <span class="identifier">an</span> <span class="identifier">identifier</span>
  97. <span class="preprocessor">#define</span> <span class="identifier">AMACRO1_NAME</span> <span class="identifier">Identifier</span> <span class="identifier">is</span> <span class="identifier">a</span> <span class="identifier">NAME</span>
  98. <span class="preprocessor">#define</span> <span class="identifier">AMACRO1_ADDRESS</span> <span class="identifier">Identifier</span> <span class="identifier">is</span> <span class="identifier">an</span> <span class="identifier">ADDRESS</span>
  99. </pre>
  100. <p>
  101. Here we use VMD's identifier registration system to determine and handle a
  102. particular identifier we may be expecting as a macro parameter. If the input
  103. to 'AMACRO1' is 'NAME' the output is 'Identifier is a NAME'. If the input to
  104. 'AMACRO1' is 'ADDRESS' the output is 'Identifier is an ADDRESS'. Otherwise
  105. the output is 'Parameter is not an identifier'.
  106. </p>
  107. <p>
  108. Identifier pre-detection makes things clearer, allowing us to detect within
  109. VMD whether macro input matches a particular identifier. Using the same setup
  110. as our previous example, but with identifier pre-detection:
  111. </p>
  112. <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">is_identifier</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  113. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_REGISTER_NAME</span> <span class="special">(</span><span class="identifier">NAME</span><span class="special">)</span>
  114. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_DETECT_NAME_NAME</span>
  115. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_REGISTER_ADDRESS</span> <span class="special">(</span><span class="identifier">ADDRESS</span><span class="special">)</span>
  116. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_DETECT_ADDRESS_ADDRESS</span>
  117. <span class="preprocessor">#define</span> <span class="identifier">AMACRO2</span><span class="special">(</span><span class="identifier">param</span><span class="special">)</span> <span class="special">\</span>
  118. <span class="identifier">BOOST_PP_IIF</span> <span class="special">\</span>
  119. <span class="special">(</span> <span class="special">\</span>
  120. <span class="identifier">BOOST_VMD_IS_IDENTIFIER</span><span class="special">(</span><span class="identifier">param</span><span class="special">,</span><span class="identifier">NAME</span><span class="special">),</span> <span class="special">\</span>
  121. <span class="identifier">AMACRO2_NAME</span><span class="special">,</span> <span class="special">\</span>
  122. <span class="identifier">BOOST_PP_IIF</span> <span class="special">\</span>
  123. <span class="special">(</span> <span class="special">\</span>
  124. <span class="identifier">BOOST_VMD_IS_IDENTIFIER</span><span class="special">(</span><span class="identifier">param</span><span class="special">,</span><span class="identifier">ADDRESS</span><span class="special">),</span> <span class="special">\</span>
  125. <span class="identifier">AMACRO2_ADDRESS</span><span class="special">,</span> <span class="special">\</span>
  126. <span class="identifier">AMACRO2_NO_IDENTIFIER</span> <span class="special">\</span>
  127. <span class="special">)</span> <span class="special">\</span>
  128. <span class="special">)</span> <span class="special">\</span>
  129. <span class="special">(</span><span class="identifier">param</span><span class="special">)</span>
  130. <span class="preprocessor">#define</span> <span class="identifier">AMACRO2_NO_IDENTIFIER</span><span class="special">(</span><span class="identifier">param</span><span class="special">)</span> <span class="identifier">Parameter</span> <span class="identifier">is</span> <span class="keyword">not</span> <span class="identifier">a</span> <span class="identifier">NAME</span> <span class="keyword">or</span> <span class="identifier">ADDRESS</span> <span class="identifier">identifier</span>
  131. <span class="preprocessor">#define</span> <span class="identifier">AMACRO2_NAME</span><span class="special">(</span><span class="identifier">param</span><span class="special">)</span> <span class="identifier">Identifier</span> <span class="identifier">is</span> <span class="identifier">a</span> <span class="identifier">NAME</span>
  132. <span class="preprocessor">#define</span> <span class="identifier">AMACRO2_ADDRESS</span><span class="special">(</span><span class="identifier">param</span><span class="special">)</span> <span class="identifier">Identifier</span> <span class="identifier">is</span> <span class="identifier">an</span> <span class="identifier">ADDRESS</span>
  133. </pre>
  134. <p>
  135. If the input to 'AMACRO2' is 'NAME' the output is 'Identifier is a NAME'. If
  136. the input to 'AMACRO2' is 'ADDRESS' the output is 'Identifier is an ADDRESS'.
  137. Otherwise the output is 'Parameter is not a NAME or ADDRESS identifier'.
  138. </p>
  139. <p>
  140. The VMD library also has 2 different subtypes of identifiers which can always
  141. be recognized. The first are numbers, equivalent to the number in Boost PP,
  142. numeric values with a range of 0-256. The second are v-types, which are identifiers
  143. starting with BOOST_VMD_TYPE_ followed by a name for the type of data. As an
  144. example, the v-type of a Boost PP tuple is BOOST_VMD_TYPE_TUPLE and the v-type
  145. of a v-type itself is BOOST_VMD_TYPE_TYPE. All data types have their own v-type
  146. identifier; types are recognized by the VMD macros and may be passed as input
  147. data just like any other of the types of data VMD recognizes.
  148. </p>
  149. <p>
  150. The VMD identifier system even has a way, to be explained later, for the end-user
  151. to create his own subtype identifiers.
  152. </p>
  153. <p>
  154. Another reason to use VMD is that VMD understands 'sequences' of the VMD data
  155. types. You can have a sequence of data types and VMD can convert the sequence
  156. to any of the Boost PP data types, or access any individual data type in a
  157. sequence.
  158. </p>
  159. <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">elem</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  160. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">to_tuple</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  161. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_REGISTER_NAME</span> <span class="special">(</span><span class="identifier">NAME</span><span class="special">)</span>
  162. <span class="preprocessor">#define</span> <span class="identifier">ASEQUENCE</span> <span class="special">(</span><span class="number">1</span><span class="special">,</span><span class="number">2</span><span class="special">)</span> <span class="identifier">NAME</span> <span class="number">147</span> <span class="identifier">BOOST_VMD_TYPE_NUMBER</span> <span class="special">(</span><span class="identifier">a</span><span class="special">)(</span><span class="identifier">b</span><span class="special">)</span>
  163. <span class="identifier">BOOST_VMD_TO_TUPLE</span><span class="special">(</span><span class="identifier">ASEQUENCE</span><span class="special">)</span>
  164. <span class="identifier">BOOST_VMD_ELEM</span><span class="special">(</span><span class="number">2</span><span class="special">,</span><span class="identifier">ASEQUENCE</span><span class="special">)</span>
  165. </pre>
  166. <p>
  167. Our first expansion returns the tuple:
  168. </p>
  169. <pre class="programlisting"><span class="special">((</span><span class="number">1</span><span class="special">,</span><span class="number">2</span><span class="special">),</span><span class="identifier">NAME</span><span class="special">,</span><span class="number">147</span><span class="special">,</span><span class="identifier">BOOST_VMD_TYPE_NUMBER</span><span class="special">,(</span><span class="identifier">a</span><span class="special">)(</span><span class="identifier">b</span><span class="special">))</span>
  170. </pre>
  171. <p>
  172. Our second expansion returns the sequence element:
  173. </p>
  174. <pre class="programlisting"><span class="number">147</span>
  175. </pre>
  176. <p>
  177. Sequences give the macro programmer the ability to accept input data from the
  178. user which may more closely mimic C++ constructs.
  179. </p>
  180. <p>
  181. Another reason to use VMD is that VMD understands data types. Besides specifically
  182. asking if a particular input is a particular data type, you can use the macro
  183. BOOST_VMD_GET_TYPE to retrieve the type of any VMD data.
  184. </p>
  185. <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">get_type</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  186. <span class="identifier">BOOST_VMD_GET_TYPE</span><span class="special">((</span><span class="number">1</span><span class="special">,</span><span class="number">2</span><span class="special">))</span> <span class="comment">// expands to BOOST_VMD_TYPE_TUPLE</span>
  187. <span class="identifier">BOOST_VMD_GET_TYPE</span><span class="special">(</span><span class="number">235</span><span class="special">)</span> <span class="comment">// expands to BOOST_VMD_TYPE_NUMBER</span>
  188. </pre>
  189. <p>
  190. etc.
  191. </p>
  192. <p>
  193. There is still much more of VMD functionality but hopefully this brief introduction
  194. of what VMD can do will interest you so that you will read on to understand
  195. VMD's functionality for the macro programmer.
  196. </p>
  197. </div>
  198. <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
  199. <td align="left"></td>
  200. <td align="right"><div class="copyright-footer">Copyright &#169; 2010-2017 Tropic Software
  201. East Inc</div></td>
  202. </tr></table>
  203. <hr>
  204. <div class="spirit-nav">
  205. <a accesskey="p" href="vmd_naming.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="vmd_vmacros.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
  206. </div>
  207. </body>
  208. </html>