vmd_examples.html 92 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994
  1. <html>
  2. <head>
  3. <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
  4. <title>Examples using VMD functionality</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_conv.html" title="Version 1.7 to 1.8 conversion">
  10. <link rel="next" href="../variadic_macro_data_reference.html" title="Variadic Macro Data Reference">
  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_conv.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="../variadic_macro_data_reference.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_examples"></a><a class="link" href="vmd_examples.html" title="Examples using VMD functionality">Examples using VMD functionality</a>
  28. </h2></div></div></div>
  29. <p>
  30. Examples of library use are always highly personal. Any given library employing
  31. macro programming can decide what macro facilities are needed based on the
  32. library itself and then decide if functionality in a macro library like VMD
  33. makes macro programming in that library easier. To that end the examples presented
  34. here are highly arbitrary and are just efforts to illustrate possible use of
  35. functionality of VMD features without worrying too much if those examples have
  36. any practical beneficial use in real programming situations. In these examples
  37. I have endeavored, therefore, to present macro programming "snippets"
  38. using VMD functionality rather than complete solutions to a given practical
  39. problem.
  40. </p>
  41. <h4>
  42. <a name="variadic_macro_data.vmd_examples.h0"></a>
  43. <span class="phrase"><a name="variadic_macro_data.vmd_examples.switch_macro"></a></span><a class="link" href="vmd_examples.html#variadic_macro_data.vmd_examples.switch_macro">Switch
  44. macro</a>
  45. </h4>
  46. <p>
  47. In C++ there is a 'switch' statement which we can emulate in macro programming
  48. using VMD. For the macro emulation we will have as parameters to our macro:
  49. </p>
  50. <div class="orderedlist"><ol class="orderedlist" type="1">
  51. <li class="listitem">
  52. A value, which can be any data type VMD can parse.
  53. </li>
  54. <li class="listitem">
  55. A tuple of calling values. These will be used when calling the matching
  56. macro.
  57. </li>
  58. <li class="listitem">
  59. Variadic parameters, each of which are tuples. Each tuple consists of two
  60. elements, the name of a value to match and the name of a macro to call.
  61. For the 'default' case the tuple is a single element which is the name
  62. of a macro to call. These are our equivalents to the C++ switch 'case'
  63. statements.
  64. </li>
  65. </ol></div>
  66. <p>
  67. The macro looks like:
  68. </p>
  69. <pre class="programlisting"><span class="identifier">BOOST_VMD_SWITCH</span><span class="special">(</span><span class="identifier">value</span><span class="special">,</span><span class="identifier">calling_values</span><span class="special">,...)</span>
  70. </pre>
  71. <p>
  72. We have to be careful not to parse the name of our macro to call in any way
  73. since this is a failing condition for BOOST_VMD_IS_EMPTY and subsequently for
  74. any parsing of input data we might want to do. Instead we will just extract
  75. the calling macro name and just call it, passing the calling values.
  76. </p>
  77. <p>
  78. Our processing is:
  79. </p>
  80. <div class="orderedlist"><ol class="orderedlist" type="1">
  81. <li class="listitem">
  82. Convert our variadic parameters to a tuple since access to tuple elements
  83. is easier.
  84. </li>
  85. <li class="listitem">
  86. Use a BOOST_PP_WHILE loop to find the matching value and extract the calling
  87. macro from it. We will use BOOST_VMD_EQUAL to find the matching value.
  88. </li>
  89. <li class="listitem">
  90. Call the calling macro with the calling values when we return from our
  91. BOOST_PP_WHILE loop.
  92. </li>
  93. </ol></div>
  94. <p>
  95. Here is our code:
  96. </p>
  97. <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">detail</span><span class="special">/</span><span class="identifier">setup</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  98. <span class="preprocessor">#if</span> <span class="identifier">BOOST_PP_VARIADICS</span>
  99. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">cat</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  100. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">arithmetic</span><span class="special">/</span><span class="identifier">inc</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  101. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">comparison</span><span class="special">/</span><span class="identifier">equal</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  102. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">control</span><span class="special">/</span><span class="identifier">expr_iif</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  103. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">control</span><span class="special">/</span><span class="identifier">iif</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  104. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">control</span><span class="special">/</span><span class="keyword">while</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  105. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">tuple</span><span class="special">/</span><span class="identifier">elem</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  106. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">tuple</span><span class="special">/</span><span class="keyword">enum</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  107. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">facilities</span><span class="special">/</span><span class="identifier">expand</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  108. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">tuple</span><span class="special">/</span><span class="identifier">replace</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  109. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">tuple</span><span class="special">/</span><span class="identifier">size</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  110. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">variadic</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>
  111. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">variadic</span><span class="special">/</span><span class="identifier">size</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  112. <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">equal</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  113. <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">identity</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  114. <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_empty</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  115. <span class="comment">/*
  116. State index into state values
  117. */</span>
  118. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_SWITCH_STATE_ELEM_INDEX</span> <span class="number">2</span>
  119. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_SWITCH_STATE_ELEM_DEFAULT</span> <span class="number">4</span>
  120. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_SWITCH_STATE_ELEM_RESULT</span> <span class="number">5</span>
  121. <span class="comment">/*
  122. Retrieve the state value, never changes
  123. */</span>
  124. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_SWITCH_STATE_GET_VALUE</span><span class="special">(</span><span class="identifier">state</span><span class="special">)</span> <span class="special">\</span>
  125. <span class="identifier">BOOST_PP_TUPLE_ELEM</span><span class="special">(</span><span class="number">0</span><span class="special">,</span><span class="identifier">state</span><span class="special">)</span> <span class="special">\</span>
  126. <span class="comment">/**/</span>
  127. <span class="comment">/*
  128. Retrieve the state tuple of values, never changes
  129. */</span>
  130. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_SWITCH_STATE_GET_CHOICES</span><span class="special">(</span><span class="identifier">state</span><span class="special">)</span> <span class="special">\</span>
  131. <span class="identifier">BOOST_PP_TUPLE_ELEM</span><span class="special">(</span><span class="number">1</span><span class="special">,</span><span class="identifier">state</span><span class="special">)</span> <span class="special">\</span>
  132. <span class="comment">/**/</span>
  133. <span class="comment">/*
  134. Retrieve the state index
  135. */</span>
  136. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_SWITCH_STATE_GET_INDEX</span><span class="special">(</span><span class="identifier">state</span><span class="special">)</span> <span class="special">\</span>
  137. <span class="identifier">BOOST_PP_TUPLE_ELEM</span><span class="special">(</span><span class="number">2</span><span class="special">,</span><span class="identifier">state</span><span class="special">)</span> <span class="special">\</span>
  138. <span class="comment">/**/</span>
  139. <span class="comment">/*
  140. Retrieve the state tuple of values size, never changes
  141. */</span>
  142. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_SWITCH_STATE_GET_SIZE</span><span class="special">(</span><span class="identifier">state</span><span class="special">)</span> <span class="special">\</span>
  143. <span class="identifier">BOOST_PP_TUPLE_ELEM</span><span class="special">(</span><span class="number">3</span><span class="special">,</span><span class="identifier">state</span><span class="special">)</span> <span class="special">\</span>
  144. <span class="comment">/**/</span>
  145. <span class="comment">/*
  146. Retrieve the state default tuple
  147. */</span>
  148. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_SWITCH_STATE_GET_DEFAULT</span><span class="special">(</span><span class="identifier">state</span><span class="special">)</span> <span class="special">\</span>
  149. <span class="identifier">BOOST_PP_TUPLE_ELEM</span><span class="special">(</span><span class="number">4</span><span class="special">,</span><span class="identifier">state</span><span class="special">)</span> <span class="special">\</span>
  150. <span class="comment">/**/</span>
  151. <span class="comment">/*
  152. Retrieve the state result tuple
  153. */</span>
  154. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_SWITCH_STATE_GET_RESULT</span><span class="special">(</span><span class="identifier">state</span><span class="special">)</span> <span class="special">\</span>
  155. <span class="identifier">BOOST_PP_TUPLE_ELEM</span><span class="special">(</span><span class="number">5</span><span class="special">,</span><span class="identifier">state</span><span class="special">)</span> <span class="special">\</span>
  156. <span class="comment">/**/</span>
  157. <span class="comment">/*
  158. Retrieve the current value tuple
  159. */</span>
  160. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_SWITCH_STATE_GET_CURRENT_CHOICE</span><span class="special">(</span><span class="identifier">state</span><span class="special">)</span> <span class="special">\</span>
  161. <span class="identifier">BOOST_PP_TUPLE_ELEM</span> <span class="special">\</span>
  162. <span class="special">(</span> <span class="special">\</span>
  163. <span class="identifier">BOOST_VMD_SWITCH_STATE_GET_INDEX</span><span class="special">(</span><span class="identifier">state</span><span class="special">),</span> <span class="special">\</span>
  164. <span class="identifier">BOOST_VMD_SWITCH_STATE_GET_CHOICES</span><span class="special">(</span><span class="identifier">state</span><span class="special">)</span> <span class="special">\</span>
  165. <span class="special">)</span> <span class="special">\</span>
  166. <span class="comment">/**/</span>
  167. <span class="comment">/*
  168. Expands to the state
  169. value = value to compare against
  170. tuple = choices as a tuple of values
  171. size = size of tuple of values
  172. None of these ever change in the WHILE state
  173. */</span>
  174. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_SWITCH_STATE_EXPAND</span><span class="special">(</span><span class="identifier">value</span><span class="special">,</span><span class="identifier">tuple</span><span class="special">,</span><span class="identifier">size</span><span class="special">)</span> <span class="special">\</span>
  175. <span class="special">(</span><span class="identifier">value</span><span class="special">,</span><span class="identifier">tuple</span><span class="special">,</span><span class="number">0</span><span class="special">,</span><span class="identifier">size</span><span class="special">,(</span><span class="number">0</span><span class="special">,),(,))</span> <span class="special">\</span>
  176. <span class="comment">/**/</span>
  177. <span class="comment">/*
  178. Expands to the WHILE state
  179. The state to our WHILE consists of a tuple of elements:
  180. 1: value to compare against
  181. 2: tuple of values. Each value is a value/macro pair or if the default just a macro
  182. 3: index into the values
  183. 4: tuple for default macro. 0 means no default macro, 1 means default macro and then second value is the default macro.
  184. 5: tuple of result matched. Emptiness means no result yet specified, 0 means no match, 1 means match and second value is the matching macro.
  185. */</span>
  186. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_SWITCH_STATE</span><span class="special">(</span><span class="identifier">value</span><span class="special">,...)</span> <span class="special">\</span>
  187. <span class="identifier">BOOST_VMD_SWITCH_STATE_EXPAND</span> <span class="special">\</span>
  188. <span class="special">(</span> <span class="special">\</span>
  189. <span class="identifier">value</span><span class="special">,</span> <span class="special">\</span>
  190. <span class="identifier">BOOST_PP_VARIADIC_TO_TUPLE</span><span class="special">(</span><span class="identifier">__VA_ARGS__</span><span class="special">),</span> <span class="special">\</span>
  191. <span class="identifier">BOOST_PP_VARIADIC_SIZE</span><span class="special">(</span><span class="identifier">__VA_ARGS__</span><span class="special">)</span> <span class="special">\</span>
  192. <span class="special">)</span> <span class="special">\</span>
  193. <span class="comment">/**/</span>
  194. <span class="comment">/*
  195. Sets the state upon a successful match.
  196. macro = is the matching macro found
  197. */</span>
  198. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_SWITCH_OP_SUCCESS</span><span class="special">(</span><span class="identifier">d</span><span class="special">,</span><span class="identifier">state</span><span class="special">,</span><span class="identifier">macro</span><span class="special">)</span> <span class="special">\</span>
  199. <span class="identifier">BOOST_PP_TUPLE_REPLACE_D</span> <span class="special">\</span>
  200. <span class="special">(</span> <span class="special">\</span>
  201. <span class="identifier">d</span><span class="special">,</span> <span class="special">\</span>
  202. <span class="identifier">state</span><span class="special">,</span> <span class="special">\</span>
  203. <span class="identifier">BOOST_VMD_SWITCH_STATE_ELEM_RESULT</span><span class="special">,</span> <span class="special">\</span>
  204. <span class="special">(</span><span class="number">1</span><span class="special">,</span><span class="identifier">macro</span><span class="special">)</span> <span class="special">\</span>
  205. <span class="special">)</span> <span class="special">\</span>
  206. <span class="comment">/**/</span>
  207. <span class="comment">/*
  208. Sets the state upon final failure to find a match.
  209. def = default tuple macro, ignored
  210. */</span>
  211. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_SWITCH_OP_FAILURE</span><span class="special">(</span><span class="identifier">d</span><span class="special">,</span><span class="identifier">state</span><span class="special">,</span><span class="identifier">def</span><span class="special">)</span> <span class="special">\</span>
  212. <span class="identifier">BOOST_PP_TUPLE_REPLACE_D</span> <span class="special">\</span>
  213. <span class="special">(</span> <span class="special">\</span>
  214. <span class="identifier">d</span><span class="special">,</span> <span class="special">\</span>
  215. <span class="identifier">state</span><span class="special">,</span> <span class="special">\</span>
  216. <span class="identifier">BOOST_VMD_SWITCH_STATE_ELEM_RESULT</span><span class="special">,</span> <span class="special">\</span>
  217. <span class="special">(</span><span class="number">0</span><span class="special">,)</span> <span class="special">\</span>
  218. <span class="special">)</span> <span class="special">\</span>
  219. <span class="comment">/**/</span>
  220. <span class="comment">/*
  221. Increments the state index into the tuple values
  222. */</span>
  223. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_SWITCH_OP_UPDATE_INDEX</span><span class="special">(</span><span class="identifier">d</span><span class="special">,</span><span class="identifier">state</span><span class="special">)</span> <span class="special">\</span>
  224. <span class="identifier">BOOST_PP_TUPLE_REPLACE_D</span> <span class="special">\</span>
  225. <span class="special">(</span> <span class="special">\</span>
  226. <span class="identifier">d</span><span class="special">,</span> <span class="special">\</span>
  227. <span class="identifier">state</span><span class="special">,</span> <span class="special">\</span>
  228. <span class="identifier">BOOST_VMD_SWITCH_STATE_ELEM_INDEX</span><span class="special">,</span> <span class="special">\</span>
  229. <span class="identifier">BOOST_PP_INC</span><span class="special">(</span><span class="identifier">BOOST_VMD_SWITCH_STATE_GET_INDEX</span><span class="special">(</span><span class="identifier">state</span><span class="special">))</span> <span class="special">\</span>
  230. <span class="special">)</span> <span class="special">\</span>
  231. <span class="comment">/**/</span>
  232. <span class="comment">/*
  233. Choose our current value's macro as our successful match
  234. tuple = current tuple to test
  235. */</span>
  236. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_SWITCH_OP_TEST_CURRENT_VALUE_MATCH</span><span class="special">(</span><span class="identifier">d</span><span class="special">,</span><span class="identifier">state</span><span class="special">,</span><span class="identifier">tuple</span><span class="special">)</span> <span class="special">\</span>
  237. <span class="identifier">BOOST_VMD_SWITCH_OP_SUCCESS</span><span class="special">(</span><span class="identifier">d</span><span class="special">,</span><span class="identifier">state</span><span class="special">,</span><span class="identifier">BOOST_PP_TUPLE_ELEM</span><span class="special">(</span><span class="number">1</span><span class="special">,</span><span class="identifier">tuple</span><span class="special">))</span> <span class="special">\</span>
  238. <span class="comment">/**/</span>
  239. <span class="comment">/*
  240. Update our state index
  241. tuple = current tuple to test, ignored
  242. */</span>
  243. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_SWITCH_OP_TEST_CURRENT_VALUE_UPDATE_INDEX</span><span class="special">(</span><span class="identifier">d</span><span class="special">,</span><span class="identifier">state</span><span class="special">,</span><span class="identifier">tuple</span><span class="special">)</span> <span class="special">\</span>
  244. <span class="identifier">BOOST_VMD_SWITCH_OP_UPDATE_INDEX</span><span class="special">(</span><span class="identifier">d</span><span class="special">,</span><span class="identifier">state</span><span class="special">)</span> <span class="special">\</span>
  245. <span class="comment">/**/</span>
  246. <span class="comment">/*
  247. Test our current value against our value to compare against
  248. tuple = current tuple to test
  249. */</span>
  250. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_SWITCH_OP_TEST_CURRENT_VALUE</span><span class="special">(</span><span class="identifier">d</span><span class="special">,</span><span class="identifier">state</span><span class="special">,</span><span class="identifier">tuple</span><span class="special">)</span> <span class="special">\</span>
  251. <span class="identifier">BOOST_PP_IIF</span> <span class="special">\</span>
  252. <span class="special">(</span> <span class="special">\</span>
  253. <span class="identifier">BOOST_VMD_EQUAL_D</span> <span class="special">\</span>
  254. <span class="special">(</span> <span class="special">\</span>
  255. <span class="identifier">d</span><span class="special">,</span> <span class="special">\</span>
  256. <span class="identifier">BOOST_VMD_SWITCH_STATE_GET_VALUE</span><span class="special">(</span><span class="identifier">state</span><span class="special">),</span> <span class="special">\</span>
  257. <span class="identifier">BOOST_PP_TUPLE_ELEM</span><span class="special">(</span><span class="number">0</span><span class="special">,</span><span class="identifier">tuple</span><span class="special">)</span> <span class="special">\</span>
  258. <span class="special">),</span> <span class="special">\</span>
  259. <span class="identifier">BOOST_VMD_SWITCH_OP_TEST_CURRENT_VALUE_MATCH</span><span class="special">,</span> <span class="special">\</span>
  260. <span class="identifier">BOOST_VMD_SWITCH_OP_TEST_CURRENT_VALUE_UPDATE_INDEX</span> <span class="special">\</span>
  261. <span class="special">)</span> <span class="special">\</span>
  262. <span class="special">(</span><span class="identifier">d</span><span class="special">,</span><span class="identifier">state</span><span class="special">,</span><span class="identifier">tuple</span><span class="special">)</span> <span class="special">\</span>
  263. <span class="comment">/**/</span>
  264. <span class="comment">/*
  265. Set our default macro and update the index in our WHILE state
  266. tuple = current tuple to test
  267. */</span>
  268. <span class="preprocessor">#if</span> <span class="identifier">BOOST_VMD_MSVC</span>
  269. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_SWITCH_OP_TEST_CURRENT_CREATE_DEFAULT_NN</span><span class="special">(</span><span class="identifier">number</span><span class="special">,</span><span class="identifier">name</span><span class="special">)</span> <span class="special">\</span>
  270. <span class="special">(</span><span class="identifier">number</span><span class="special">,</span><span class="identifier">name</span><span class="special">)</span> <span class="special">\</span>
  271. <span class="comment">/**/</span>
  272. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_SWITCH_OP_TEST_CURRENT_CREATE_DEFAULT</span><span class="special">(</span><span class="identifier">d</span><span class="special">,</span><span class="identifier">state</span><span class="special">,</span><span class="identifier">tuple</span><span class="special">)</span> <span class="special">\</span>
  273. <span class="identifier">BOOST_VMD_SWITCH_OP_UPDATE_INDEX</span> <span class="special">\</span>
  274. <span class="special">(</span> <span class="special">\</span>
  275. <span class="identifier">d</span><span class="special">,</span> <span class="special">\</span>
  276. <span class="identifier">BOOST_PP_TUPLE_REPLACE_D</span> <span class="special">\</span>
  277. <span class="special">(</span> <span class="special">\</span>
  278. <span class="identifier">d</span><span class="special">,</span> <span class="special">\</span>
  279. <span class="identifier">state</span><span class="special">,</span> <span class="special">\</span>
  280. <span class="identifier">BOOST_VMD_SWITCH_STATE_ELEM_DEFAULT</span><span class="special">,</span> <span class="special">\</span>
  281. <span class="identifier">BOOST_VMD_SWITCH_OP_TEST_CURRENT_CREATE_DEFAULT_NN</span><span class="special">(</span><span class="number">1</span><span class="special">,</span><span class="identifier">BOOST_PP_TUPLE_ENUM</span><span class="special">(</span><span class="identifier">tuple</span><span class="special">))</span> <span class="special">\</span>
  282. <span class="special">)</span> <span class="special">\</span>
  283. <span class="special">)</span> <span class="special">\</span>
  284. <span class="comment">/**/</span>
  285. <span class="preprocessor">#else</span>
  286. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_SWITCH_OP_TEST_CURRENT_CREATE_DEFAULT</span><span class="special">(</span><span class="identifier">d</span><span class="special">,</span><span class="identifier">state</span><span class="special">,</span><span class="identifier">tuple</span><span class="special">)</span> <span class="special">\</span>
  287. <span class="identifier">BOOST_VMD_SWITCH_OP_UPDATE_INDEX</span> <span class="special">\</span>
  288. <span class="special">(</span> <span class="special">\</span>
  289. <span class="identifier">d</span><span class="special">,</span> <span class="special">\</span>
  290. <span class="identifier">BOOST_PP_TUPLE_REPLACE_D</span> <span class="special">\</span>
  291. <span class="special">(</span> <span class="special">\</span>
  292. <span class="identifier">d</span><span class="special">,</span> <span class="special">\</span>
  293. <span class="identifier">state</span><span class="special">,</span> <span class="special">\</span>
  294. <span class="identifier">BOOST_VMD_SWITCH_STATE_ELEM_DEFAULT</span><span class="special">,</span> <span class="special">\</span>
  295. <span class="special">(</span><span class="number">1</span><span class="special">,</span><span class="identifier">BOOST_PP_TUPLE_ENUM</span><span class="special">(</span><span class="identifier">tuple</span><span class="special">))</span> <span class="special">\</span>
  296. <span class="special">)</span> <span class="special">\</span>
  297. <span class="special">)</span> <span class="special">\</span>
  298. <span class="comment">/**/</span>
  299. <span class="preprocessor">#endif</span>
  300. <span class="comment">/*
  301. If our current value is a default macro, just set the default macro,
  302. else test our current value.
  303. tuple = current tuple to test
  304. */</span>
  305. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_SWITCH_OP_TEST_CURRENT_TUPLE</span><span class="special">(</span><span class="identifier">d</span><span class="special">,</span><span class="identifier">state</span><span class="special">,</span><span class="identifier">tuple</span><span class="special">)</span> <span class="special">\</span>
  306. <span class="identifier">BOOST_PP_IIF</span> <span class="special">\</span>
  307. <span class="special">(</span> <span class="special">\</span>
  308. <span class="identifier">BOOST_PP_EQUAL_D</span> <span class="special">\</span>
  309. <span class="special">(</span> <span class="special">\</span>
  310. <span class="identifier">d</span><span class="special">,</span> <span class="special">\</span>
  311. <span class="identifier">BOOST_PP_TUPLE_SIZE</span><span class="special">(</span><span class="identifier">tuple</span><span class="special">),</span> <span class="special">\</span>
  312. <span class="number">1</span> <span class="special">\</span>
  313. <span class="special">),</span> <span class="special">\</span>
  314. <span class="identifier">BOOST_VMD_SWITCH_OP_TEST_CURRENT_CREATE_DEFAULT</span><span class="special">,</span> <span class="special">\</span>
  315. <span class="identifier">BOOST_VMD_SWITCH_OP_TEST_CURRENT_VALUE</span> <span class="special">\</span>
  316. <span class="special">)</span> <span class="special">\</span>
  317. <span class="special">(</span><span class="identifier">d</span><span class="special">,</span><span class="identifier">state</span><span class="special">,</span><span class="identifier">tuple</span><span class="special">)</span> <span class="special">\</span>
  318. <span class="comment">/**/</span>
  319. <span class="comment">/*
  320. Test the current value in our tuple of values
  321. */</span>
  322. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_SWITCH_OP_TEST_CURRENT</span><span class="special">(</span><span class="identifier">d</span><span class="special">,</span><span class="identifier">state</span><span class="special">)</span> <span class="special">\</span>
  323. <span class="identifier">BOOST_VMD_SWITCH_OP_TEST_CURRENT_TUPLE</span> <span class="special">\</span>
  324. <span class="special">(</span> <span class="special">\</span>
  325. <span class="identifier">d</span><span class="special">,</span> <span class="special">\</span>
  326. <span class="identifier">state</span><span class="special">,</span> <span class="special">\</span>
  327. <span class="identifier">BOOST_VMD_SWITCH_STATE_GET_CURRENT_CHOICE</span><span class="special">(</span><span class="identifier">state</span><span class="special">)</span> <span class="special">\</span>
  328. <span class="special">)</span> <span class="special">\</span>
  329. <span class="comment">/**/</span>
  330. <span class="comment">/*
  331. Choose the default macro as our successful match
  332. def = default tuple consisting of just the default macro name
  333. */</span>
  334. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_SWITCH_OP_DEFAULT_RET_CHOSEN</span><span class="special">(</span><span class="identifier">d</span><span class="special">,</span><span class="identifier">state</span><span class="special">,</span><span class="identifier">def</span><span class="special">)</span> <span class="special">\</span>
  335. <span class="identifier">BOOST_VMD_SWITCH_OP_SUCCESS</span> <span class="special">\</span>
  336. <span class="special">(</span> <span class="special">\</span>
  337. <span class="identifier">d</span><span class="special">,</span> <span class="special">\</span>
  338. <span class="identifier">state</span><span class="special">,</span> <span class="special">\</span>
  339. <span class="identifier">BOOST_PP_TUPLE_ELEM</span><span class="special">(</span><span class="number">1</span><span class="special">,</span><span class="identifier">def</span><span class="special">)</span> <span class="special">\</span>
  340. <span class="special">)</span> <span class="special">\</span>
  341. <span class="comment">/**/</span>
  342. <span class="comment">/*
  343. If the default macro exists, choose it else indicate no macro was found
  344. def = default tuple consisting of just the default macro name
  345. */</span>
  346. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_SWITCH_OP_DEFAULT_RET</span><span class="special">(</span><span class="identifier">d</span><span class="special">,</span><span class="identifier">state</span><span class="special">,</span><span class="identifier">def</span><span class="special">)</span> <span class="special">\</span>
  347. <span class="identifier">BOOST_PP_IIF</span> <span class="special">\</span>
  348. <span class="special">(</span> <span class="special">\</span>
  349. <span class="identifier">BOOST_PP_TUPLE_ELEM</span><span class="special">(</span><span class="number">0</span><span class="special">,</span><span class="identifier">def</span><span class="special">),</span> <span class="special">\</span>
  350. <span class="identifier">BOOST_VMD_SWITCH_OP_DEFAULT_RET_CHOSEN</span><span class="special">,</span> <span class="special">\</span>
  351. <span class="identifier">BOOST_VMD_SWITCH_OP_FAILURE</span> <span class="special">\</span>
  352. <span class="special">)</span> <span class="special">\</span>
  353. <span class="special">(</span><span class="identifier">d</span><span class="special">,</span><span class="identifier">state</span><span class="special">,</span><span class="identifier">def</span><span class="special">)</span> <span class="special">\</span>
  354. <span class="comment">/**/</span>
  355. <span class="comment">/*
  356. Try to choose the default macro if it exists
  357. */</span>
  358. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_SWITCH_OP_DEFAULT</span><span class="special">(</span><span class="identifier">d</span><span class="special">,</span><span class="identifier">state</span><span class="special">)</span> <span class="special">\</span>
  359. <span class="identifier">BOOST_VMD_SWITCH_OP_DEFAULT_RET</span> <span class="special">\</span>
  360. <span class="special">(</span> <span class="special">\</span>
  361. <span class="identifier">d</span><span class="special">,</span> <span class="special">\</span>
  362. <span class="identifier">state</span><span class="special">,</span> <span class="special">\</span>
  363. <span class="identifier">BOOST_VMD_SWITCH_STATE_GET_DEFAULT</span><span class="special">(</span><span class="identifier">state</span><span class="special">)</span> <span class="special">\</span>
  364. <span class="special">)</span> <span class="special">\</span>
  365. <span class="comment">/**/</span>
  366. <span class="comment">/*
  367. WHILE loop operation
  368. Check for the next value match or try to choose the default if all matches have been checked
  369. */</span>
  370. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_SWITCH_OP</span><span class="special">(</span><span class="identifier">d</span><span class="special">,</span><span class="identifier">state</span><span class="special">)</span> <span class="special">\</span>
  371. <span class="identifier">BOOST_PP_IIF</span> <span class="special">\</span>
  372. <span class="special">(</span> <span class="special">\</span>
  373. <span class="identifier">BOOST_PP_EQUAL_D</span> <span class="special">\</span>
  374. <span class="special">(</span> <span class="special">\</span>
  375. <span class="identifier">d</span><span class="special">,</span> <span class="special">\</span>
  376. <span class="identifier">BOOST_VMD_SWITCH_STATE_GET_INDEX</span><span class="special">(</span><span class="identifier">state</span><span class="special">),</span> <span class="special">\</span>
  377. <span class="identifier">BOOST_VMD_SWITCH_STATE_GET_SIZE</span><span class="special">(</span><span class="identifier">state</span><span class="special">)</span> <span class="special">\</span>
  378. <span class="special">),</span> <span class="special">\</span>
  379. <span class="identifier">BOOST_VMD_SWITCH_OP_DEFAULT</span><span class="special">,</span> <span class="special">\</span>
  380. <span class="identifier">BOOST_VMD_SWITCH_OP_TEST_CURRENT</span> <span class="special">\</span>
  381. <span class="special">)</span> <span class="special">\</span>
  382. <span class="special">(</span><span class="identifier">d</span><span class="special">,</span><span class="identifier">state</span><span class="special">)</span> <span class="special">\</span>
  383. <span class="comment">/**/</span>
  384. <span class="comment">/*
  385. WHILE loop predicate
  386. Continue the WHILE loop if a result has not yet been specified
  387. */</span>
  388. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_SWITCH_PRED</span><span class="special">(</span><span class="identifier">d</span><span class="special">,</span><span class="identifier">state</span><span class="special">)</span> <span class="special">\</span>
  389. <span class="identifier">BOOST_VMD_IS_EMPTY</span> <span class="special">\</span>
  390. <span class="special">(</span> <span class="special">\</span>
  391. <span class="identifier">BOOST_PP_TUPLE_ELEM</span> <span class="special">\</span>
  392. <span class="special">(</span> <span class="special">\</span>
  393. <span class="number">0</span><span class="special">,</span> <span class="special">\</span>
  394. <span class="identifier">BOOST_VMD_SWITCH_STATE_GET_RESULT</span><span class="special">(</span><span class="identifier">state</span><span class="special">)</span> <span class="special">\</span>
  395. <span class="special">)</span> <span class="special">\</span>
  396. <span class="special">)</span> <span class="special">\</span>
  397. <span class="comment">/**/</span>
  398. <span class="comment">/*
  399. Invokes the function-like macro
  400. macro = function-like macro name
  401. tparams = tuple of macro parameters
  402. */</span>
  403. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_SWITCH_PROCESS_INVOKE_MACRO</span><span class="special">(</span><span class="identifier">macro</span><span class="special">,</span><span class="identifier">tparams</span><span class="special">)</span> <span class="special">\</span>
  404. <span class="identifier">BOOST_PP_EXPAND</span><span class="special">(</span><span class="identifier">macro</span> <span class="identifier">tparams</span><span class="special">)</span> <span class="special">\</span>
  405. <span class="comment">/**/</span>
  406. <span class="comment">/*
  407. Processes our WHILE loop result
  408. callp = tuple of parameters for the called macro
  409. result = tuple. The first tuple element is 0
  410. if no macro has been found or 1 if a macro
  411. has been found. If 1 the second element is
  412. the name of a function-like macro
  413. */</span>
  414. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_SWITCH_PROCESS</span><span class="special">(</span><span class="identifier">callp</span><span class="special">,</span><span class="identifier">result</span><span class="special">)</span> <span class="special">\</span>
  415. <span class="identifier">BOOST_PP_EXPR_IIF</span> <span class="special">\</span>
  416. <span class="special">(</span> <span class="special">\</span>
  417. <span class="identifier">BOOST_PP_TUPLE_ELEM</span><span class="special">(</span><span class="number">0</span><span class="special">,</span><span class="identifier">result</span><span class="special">),</span> <span class="special">\</span>
  418. <span class="identifier">BOOST_VMD_SWITCH_PROCESS_INVOKE_MACRO</span> <span class="special">\</span>
  419. <span class="special">(</span> <span class="special">\</span>
  420. <span class="identifier">BOOST_PP_TUPLE_ELEM</span><span class="special">(</span><span class="number">1</span><span class="special">,</span><span class="identifier">result</span><span class="special">),</span> <span class="special">\</span>
  421. <span class="identifier">callp</span> <span class="special">\</span>
  422. <span class="special">)</span> <span class="special">\</span>
  423. <span class="special">)</span> <span class="special">\</span>
  424. <span class="comment">/**/</span>
  425. <span class="comment">/*
  426. Use BOOST_VMD_SWITCH_IDENTITY to pass a fixed value instead
  427. of a function-like macro as the second element of
  428. any tuple of the variadic parameters, or as the default
  429. value, to BOOST_VMD_SWITCH.
  430. */</span>
  431. <span class="preprocessor">#if</span> <span class="identifier">BOOST_VMD_MSVC</span>
  432. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_SWITCH_IDENTITY</span><span class="special">(</span><span class="identifier">item</span><span class="special">)</span> <span class="identifier">BOOST_PP_CAT</span><span class="special">(</span><span class="identifier">BOOST_VMD_IDENTITY</span><span class="special">(</span><span class="identifier">item</span><span class="special">),)</span>
  433. <span class="preprocessor">#else</span>
  434. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_SWITCH_IDENTITY</span> <span class="identifier">BOOST_VMD_IDENTITY</span>
  435. <span class="preprocessor">#endif</span>
  436. <span class="comment">/*
  437. Switch macro
  438. Parameters are:
  439. value = value to compare against. May be any VMD data value.
  440. callp = tuple of parameters for the called macro
  441. variadic parameters = each parameter must be a tuple.
  442. Each tuple consists of a two-element tuple. The first element is
  443. a value, which may be any VMD data value, and the second element
  444. is the name of a function-like macro to be called if the value
  445. is equal to the value to compare against. For a default value
  446. the tuple is a single-element tuple which contains the name of
  447. a function-like macro to be called if no other value matches.
  448. */</span>
  449. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_SWITCH</span><span class="special">(</span><span class="identifier">value</span><span class="special">,</span><span class="identifier">callp</span><span class="special">,...)</span> <span class="special">\</span>
  450. <span class="identifier">BOOST_VMD_SWITCH_PROCESS</span> <span class="special">\</span>
  451. <span class="special">(</span> <span class="special">\</span>
  452. <span class="identifier">callp</span><span class="special">,</span> <span class="special">\</span>
  453. <span class="identifier">BOOST_VMD_SWITCH_STATE_GET_RESULT</span> <span class="special">\</span>
  454. <span class="special">(</span> <span class="special">\</span>
  455. <span class="identifier">BOOST_PP_WHILE</span> <span class="special">\</span>
  456. <span class="special">(</span> <span class="special">\</span>
  457. <span class="identifier">BOOST_VMD_SWITCH_PRED</span><span class="special">,</span> <span class="special">\</span>
  458. <span class="identifier">BOOST_VMD_SWITCH_OP</span><span class="special">,</span> <span class="special">\</span>
  459. <span class="identifier">BOOST_VMD_SWITCH_STATE</span><span class="special">(</span><span class="identifier">value</span><span class="special">,</span><span class="identifier">__VA_ARGS__</span><span class="special">)</span> <span class="special">\</span>
  460. <span class="special">)</span> <span class="special">\</span>
  461. <span class="special">)</span> <span class="special">\</span>
  462. <span class="special">)</span> <span class="special">\</span>
  463. <span class="comment">/**/</span>
  464. <span class="preprocessor">#endif</span> <span class="comment">/* BOOST_PP_VARIADICS */</span>
  465. </pre>
  466. <p>
  467. The code is fairly involved but it is commented so that it can be understood.
  468. There are a few workarounds for a VC++ preprocessor problem, which I discovered,
  469. having to do with passing the name of a function-like macro in a tuple.
  470. </p>
  471. <p>
  472. The BOOST_VMD_SWITCH macro can be used with either macros to call or with fixed
  473. values to return. When specifying macros to call the macro name is the second
  474. element of the corresponding value-macro tuple, or in the 'default' case it
  475. is just the macro name itself. When specifying fixed values to return the macro
  476. 'name' is BOOST_VMD_SWITCH_IDENTITY(fixed_value), whether as the second element
  477. of the corresponding value-macro tuple or as the macro 'name' of the 'default'
  478. case. In the variadic parameters the user can mix macro names and fixed values
  479. as he likes.
  480. </p>
  481. <p>
  482. Some simple examples:
  483. </p>
  484. <pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_SWITCH_TEST_1</span><span class="special">(</span><span class="identifier">number</span><span class="special">)</span> <span class="special">\</span>
  485. <span class="identifier">test1_</span> <span class="special">##</span> <span class="identifier">number</span>
  486. <span class="comment">/**/</span>
  487. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_SWITCH_TEST_2</span><span class="special">(</span><span class="identifier">number</span><span class="special">)</span> <span class="special">\</span>
  488. <span class="identifier">test2_</span> <span class="special">##</span> <span class="identifier">number</span>
  489. <span class="comment">/**/</span>
  490. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_SWITCH_TEST_3</span><span class="special">(</span><span class="identifier">number</span><span class="special">)</span> <span class="special">\</span>
  491. <span class="identifier">test3_</span> <span class="special">##</span> <span class="identifier">number</span>
  492. <span class="comment">/**/</span>
  493. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_SWITCH_TEST_DEFAULT</span><span class="special">(</span><span class="identifier">number</span><span class="special">)</span> <span class="special">\</span>
  494. <span class="identifier">test_default_</span> <span class="special">##</span> <span class="identifier">number</span>
  495. <span class="comment">/**/</span>
  496. </pre>
  497. <p>
  498. We will use these simple macros in our calls to BOOST_VMD_SWITCH.
  499. </p>
  500. <pre class="programlisting"><span class="identifier">BOOST_VMD_SWITCH</span><span class="special">(</span><span class="number">1</span><span class="special">,</span>
  501. <span class="special">(</span><span class="number">7</span><span class="special">),</span>
  502. <span class="special">(</span><span class="identifier">BOOST_VMD_SWITCH_TEST_DEFAULT</span><span class="special">),</span>
  503. <span class="special">(</span><span class="number">3</span><span class="special">,</span><span class="identifier">BOOST_VMD_SWITCH_TEST_3</span><span class="special">),</span>
  504. <span class="special">(</span><span class="number">1</span><span class="special">,</span><span class="identifier">BOOST_VMD_SWITCH_TEST_1</span><span class="special">),</span>
  505. <span class="special">(</span><span class="number">2</span><span class="special">,</span><span class="identifier">BOOST_VMD_SWITCH_TEST_2</span><span class="special">)</span>
  506. <span class="special">)</span>
  507. </pre>
  508. <p>
  509. Here our macro will return 'test1_7'.
  510. </p>
  511. <p>
  512. Notice that 'cases' can be in any order.
  513. </p>
  514. <pre class="programlisting"><span class="identifier">BOOST_VMD_SWITCH</span><span class="special">(</span><span class="number">4</span><span class="special">,</span>
  515. <span class="special">(</span><span class="number">7</span><span class="special">),</span>
  516. <span class="special">(</span><span class="identifier">BOOST_VMD_SWITCH_TEST_DEFAULT</span><span class="special">),</span>
  517. <span class="special">(</span><span class="number">2</span><span class="special">,</span><span class="identifier">BOOST_VMD_SWITCH_TEST_2</span><span class="special">),</span>
  518. <span class="special">(</span><span class="number">1</span><span class="special">,</span><span class="identifier">BOOST_VMD_SWITCH_TEST_1</span><span class="special">),</span>
  519. <span class="special">(</span><span class="number">3</span><span class="special">,</span><span class="identifier">BOOST_VMD_SWITCH_TEST_3</span><span class="special">)</span>
  520. <span class="special">)</span>
  521. </pre>
  522. <p>
  523. Here are macro uses the default case and returns 'test_default_7'.
  524. </p>
  525. <pre class="programlisting"><span class="identifier">BOOST_VMD_SWITCH</span><span class="special">(</span><span class="number">143</span><span class="special">,</span>
  526. <span class="special">(</span><span class="number">7</span><span class="special">),</span>
  527. <span class="special">(</span><span class="identifier">BOOST_VMD_SWITCH_TEST_DEFAULT</span><span class="special">),</span>
  528. <span class="special">(</span><span class="number">1</span><span class="special">,</span><span class="identifier">BOOST_VMD_SWITCH_TEST_1</span><span class="special">),</span>
  529. <span class="special">(</span><span class="number">2</span><span class="special">,</span><span class="identifier">BOOST_VMD_SWITCH_TEST_2</span><span class="special">),</span>
  530. <span class="special">(</span><span class="number">3</span><span class="special">,</span><span class="identifier">BOOST_VMD_SWITCH_TEST_3</span><span class="special">),</span>
  531. <span class="special">(</span><span class="number">143</span><span class="special">,</span><span class="identifier">BOOST_VMD_SWITCH_IDENTITY</span><span class="special">(</span><span class="number">55</span><span class="special">))</span>
  532. <span class="special">)</span>
  533. </pre>
  534. <p>
  535. This shows how the matching case can be a fixed_value as the macro 'name'.
  536. </p>
  537. <pre class="programlisting"><span class="identifier">BOOST_VMD_SWITCH</span><span class="special">(</span><span class="number">155</span><span class="special">,</span>
  538. <span class="special">(</span><span class="number">7</span><span class="special">),</span>
  539. <span class="special">(</span><span class="identifier">BOOST_VMD_SWITCH_IDENTITY</span><span class="special">(</span><span class="number">77</span><span class="special">)),</span>
  540. <span class="special">(</span><span class="number">1</span><span class="special">,</span><span class="identifier">BOOST_VMD_SWITCH_TEST_1</span><span class="special">),</span>
  541. <span class="special">(</span><span class="number">2</span><span class="special">,</span><span class="identifier">BOOST_VMD_SWITCH_TEST_2</span><span class="special">),</span>
  542. <span class="special">(</span><span class="number">3</span><span class="special">,</span><span class="identifier">BOOST_VMD_SWITCH_TEST_3</span><span class="special">),</span>
  543. <span class="special">(</span><span class="number">143</span><span class="special">,</span><span class="identifier">BOOST_VMD_SWITCH_IDENTITY</span><span class="special">(</span><span class="number">55</span><span class="special">))</span>
  544. <span class="special">)</span>
  545. </pre>
  546. <p>
  547. This shows how the default value can be a fixed_value as the macro 'name'.
  548. </p>
  549. <pre class="programlisting"><span class="identifier">BOOST_VMD_SWITCH</span><span class="special">(</span><span class="identifier">BOOST_VMD_TYPE_TUPLE</span><span class="special">,</span>
  550. <span class="special">(</span><span class="number">7</span><span class="special">),</span>
  551. <span class="special">(</span><span class="identifier">BOOST_VMD_SWITCH_TEST_DEFAULT</span><span class="special">),</span>
  552. <span class="special">(</span><span class="identifier">BOOST_VMD_TYPE_TUPLE</span><span class="special">,</span><span class="identifier">BOOST_VMD_SWITCH_TEST_1</span><span class="special">),</span>
  553. <span class="special">((</span><span class="number">1</span><span class="special">,</span><span class="number">2</span><span class="special">,</span><span class="number">3</span><span class="special">),</span><span class="identifier">BOOST_VMD_SWITCH_TEST_3</span><span class="special">),</span>
  554. <span class="special">(</span><span class="number">2</span><span class="special">,</span><span class="identifier">BOOST_VMD_SWITCH_TEST_2</span><span class="special">)</span>
  555. <span class="special">)</span>
  556. </pre>
  557. <p>
  558. This shows that the 'value' and each 'case' matching values can be different
  559. data types just as long as the types are one which VMD can parse.
  560. </p>
  561. <p>
  562. There is more that can be done with the BOOST_VMD_SWITCH code but as it is
  563. I believe it could be useful for programmers writing macro code. For instance
  564. there is no checking that more than one 'case' value is the same. We could
  565. generate a BOOST_VMD_ASSERT if that were the situation. There is no concept
  566. of falling through to the next 'case' as their is when 'break' is not used
  567. at the bottom of a particular C++ 'case' statement. Nonetheless the example
  568. gives the macro programmer an idea of what can be done using the BOOST_VMD_EQUAL
  569. macro in treating data types generically, using BOOST_VMD_IS_EMPTY to test
  570. for emptiness and using BOOST_VMD_IDENTITY to generate a fixed value when a
  571. macro call is made.
  572. </p>
  573. <h4>
  574. <a name="variadic_macro_data.vmd_examples.h1"></a>
  575. <span class="phrase"><a name="variadic_macro_data.vmd_examples.tti_inner_template"></a></span><a class="link" href="vmd_examples.html#variadic_macro_data.vmd_examples.tti_inner_template">TTI
  576. inner template</a>
  577. </h4>
  578. <p>
  579. As a more practical example, just to show the possible use of VMD functionality
  580. in current Boost code, I will briefly illustrate a change that could be made
  581. to the TTI library when using VMD functionality.
  582. </p>
  583. <p>
  584. The Boost TTI library, of which the current developer of VMD is also the developer,
  585. specifies a way to introspect an inner class template of a class. The introspection
  586. can occur for an inner class template of specific template parameters.
  587. </p>
  588. <p>
  589. In the library a macro is used to generate the metafunction which allows the
  590. introspection to work. The macro used is called BOOST_TTI_TEMPLATE. The macro
  591. has both a variadic version and a non-variadic version.
  592. </p>
  593. <p>
  594. In the non-variadic version the macro always takes two parameters for introspecting
  595. for specific template parameters. The first parameter is the name of the template
  596. and the second parameter is an array of the specific template parameters (
  597. with or without the parameter names themselves ). So for a class template of
  598. the form:
  599. </p>
  600. <pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">X</span><span class="special">,</span><span class="keyword">int</span> <span class="identifier">Y</span><span class="special">&gt;</span> <span class="keyword">class</span> <span class="identifier">MyTemplate</span> <span class="special">{</span> <span class="special">...</span> <span class="identifier">code</span> <span class="special">};</span>
  601. </pre>
  602. <p>
  603. the non-variadic macro would be:
  604. </p>
  605. <pre class="programlisting"><span class="identifier">BOOST_TTI_TEMPLATE</span><span class="special">(</span><span class="identifier">MyTemplate</span><span class="special">,(</span><span class="number">2</span><span class="special">,(</span><span class="keyword">class</span><span class="special">,</span><span class="keyword">int</span><span class="special">)))</span> <span class="comment">// uses array</span>
  606. </pre>
  607. <p>
  608. I chose a Boost PP array rather than a Boost PP seq or a Boost PP list as I
  609. felt the notation for specifying the template parameters was closer with the
  610. array than with the others. Choosing a Boost PP tuple was not an option since
  611. for non-variadic macros there is no way to automatically know the tuple size,
  612. so an array was preferred.
  613. </p>
  614. <p>
  615. For the variadic version variadic parameters are used so the notation would
  616. be:
  617. </p>
  618. <pre class="programlisting"><span class="identifier">BOOST_TTI_TEMPLATE</span><span class="special">(</span><span class="identifier">MyTemplate</span><span class="special">,</span><span class="keyword">class</span><span class="special">,</span><span class="keyword">int</span><span class="special">)</span> <span class="comment">// uses variadic parameters</span>
  619. </pre>
  620. <p>
  621. since this is the most natural notation.
  622. </p>
  623. <p>
  624. But for compatibility with the non-variadic version the end-user with variadic
  625. macro support could also choose the Boost PP array form above.
  626. </p>
  627. <p>
  628. Using VMD the variadic version could support any of the other Boost PP composite
  629. types for the specific template parameters, even though I feel that the variadic
  630. parameters form is easiest to use. In this scenario a user could specify:
  631. </p>
  632. <pre class="programlisting"><span class="identifier">BOOST_TTI_TEMPLATE</span><span class="special">(</span><span class="identifier">MyTemplate</span><span class="special">,(</span><span class="keyword">class</span><span class="special">,(</span><span class="keyword">int</span><span class="special">,</span><span class="identifier">BOOST_PP_NIL</span><span class="special">)))</span> <span class="comment">// use a list</span>
  633. </pre>
  634. <p>
  635. or
  636. </p>
  637. <pre class="programlisting"><span class="identifier">BOOST_TTI_TEMPLATE</span><span class="special">(</span><span class="identifier">MyTemplate</span><span class="special">,(</span><span class="keyword">class</span><span class="special">)(</span><span class="keyword">int</span><span class="special">))</span> <span class="comment">// use a seq</span>
  638. </pre>
  639. <p>
  640. or
  641. </p>
  642. <pre class="programlisting"><span class="identifier">BOOST_TTI_TEMPLATE</span><span class="special">(</span><span class="identifier">MyTemplate</span><span class="special">,(</span><span class="keyword">class</span><span class="special">,</span><span class="keyword">int</span><span class="special">))</span> <span class="comment">// use a tuple</span>
  643. </pre>
  644. <p>
  645. The only change needed would be in the code which takes the second parameter
  646. and converts it to the final form used internally ( a Boost PP array ). This
  647. occurs in the macro BOOST_TTI_DETAIL_TRAIT_CALL_HAS_TEMPLATE_CHECK_PARAMS in
  648. the &lt;boost/tti/detail/dtemplate_params.hpp&gt; file. The code has two situations,
  649. one for VC++8 or below and one for all other compilers. For our example we
  650. will concentrate just on the one for all other compilers. You do not need to
  651. know what the code does internally to complete the creation of the appropriate
  652. metafunction to follow this example. The macro code in question looks like
  653. this:
  654. </p>
  655. <pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">BOOST_TTI_DETAIL_TRAIT_CALL_HAS_TEMPLATE_CHECK_PARAMS</span><span class="special">(</span><span class="identifier">trait</span><span class="special">,</span><span class="identifier">name</span><span class="special">,</span><span class="identifier">tpArray</span><span class="special">)</span> <span class="special">\</span>
  656. <span class="identifier">BOOST_TTI_DETAIL_HAS_MEMBER_WITH_TEMPLATE_SFINAE</span> <span class="special">\</span>
  657. <span class="special">(</span> <span class="special">\</span>
  658. <span class="special">(</span> <span class="identifier">BOOST_PP_ADD</span><span class="special">(</span><span class="identifier">BOOST_PP_ARRAY_SIZE</span><span class="special">(</span><span class="identifier">tpArray</span><span class="special">),</span><span class="number">4</span><span class="special">),</span> <span class="special">(</span> <span class="identifier">trait</span><span class="special">,</span> <span class="identifier">name</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="keyword">false</span><span class="special">,</span> <span class="identifier">BOOST_PP_ARRAY_ENUM</span><span class="special">(</span><span class="identifier">tpArray</span><span class="special">)</span> <span class="special">)</span> <span class="special">)</span> <span class="special">\</span>
  659. <span class="special">)</span> <span class="special">\</span>
  660. <span class="comment">/**/</span>
  661. </pre>
  662. <p>
  663. In this code we are taking the name of the metafunction ( trait ), the name
  664. of the template ( name ), and our specific template parameters ( tpArray )
  665. and passing the information in the form of a Boost PP array to another macro,
  666. which will eventually create the metafunction which the end-user uses to test
  667. if such a class template exists within some enclosing class. Even if tpArray
  668. were a list, seq, or tuple we still want to pass the information internally
  669. to BOOST_TTI_DETAIL_HAS_MEMBER_WITH_TEMPLATE_SFINAE in the form you can see
  670. above, which is a Boost PP array. We don't need or want to change that internal
  671. representation.
  672. </p>
  673. <p>
  674. The current code, used by both the non-variadic and variadic version of the
  675. BOOST_TTI_TEMPLATE template, assumes the 'tpArray' parameter is a Boost PP
  676. array. But if it could be a tuple, seq, or list in the variadic version the
  677. code could become, with the appropriate Boost PP and VMD header files:
  678. </p>
  679. <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">preprocessor</span><span class="special">/</span><span class="identifier">arithmetic</span><span class="special">/</span><span class="identifier">add</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  680. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">array</span><span class="special">/</span><span class="keyword">enum</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  681. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">array</span><span class="special">/</span><span class="identifier">size</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  682. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">control</span><span class="special">/</span><span class="identifier">expr_iif</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  683. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">control</span><span class="special">/</span><span class="identifier">iif</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  684. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">list</span><span class="special">/</span><span class="keyword">enum</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  685. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">list</span><span class="special">/</span><span class="identifier">size</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  686. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">seq</span><span class="special">/</span><span class="keyword">enum</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  687. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">seq</span><span class="special">/</span><span class="identifier">size</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  688. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">tuple</span><span class="special">/</span><span class="keyword">enum</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  689. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">tuple</span><span class="special">/</span><span class="identifier">size</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  690. <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">identity</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  691. <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_array</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  692. <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_list</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  693. <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>
  694. <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>
  695. <span class="preprocessor">#if</span> <span class="identifier">BOOST_PP_VARIADICS</span>
  696. <span class="preprocessor">#define</span> <span class="identifier">BOOST_TTI_DETAIL_TRAIT_CALL_HAS_TEMPLATE_CHECK_PARAMS</span><span class="special">(</span><span class="identifier">trait</span><span class="special">,</span><span class="identifier">name</span><span class="special">,</span><span class="identifier">tpArray</span><span class="special">)</span> <span class="special">\</span>
  697. <span class="identifier">BOOST_TTI_DETAIL_HAS_MEMBER_WITH_TEMPLATE_SFINAE</span> <span class="special">\</span>
  698. <span class="special">(</span> <span class="special">\</span>
  699. <span class="identifier">BOOST_TTI_DETAIL_TRAIT_CALL_HAS_TEMPLATE_CHECK_PARAMS_TYPE_CONCAT</span> <span class="special">\</span>
  700. <span class="special">(</span> <span class="special">\</span>
  701. <span class="identifier">trait</span><span class="special">,</span><span class="identifier">name</span><span class="special">,</span><span class="identifier">tpArray</span><span class="special">,</span> <span class="special">\</span>
  702. <span class="identifier">BOOST_TTI_DETAIL_TRAIT_CALL_HAS_TEMPLATE_CHECK_PARAMS_TYPE</span><span class="special">(</span><span class="identifier">tpArray</span><span class="special">)</span> <span class="special">\</span>
  703. <span class="special">)</span> <span class="special">\</span>
  704. <span class="special">)</span> <span class="special">\</span>
  705. <span class="comment">/**/</span>
  706. <span class="preprocessor">#define</span> <span class="identifier">BOOST_TTI_DETAIL_TRAIT_CALL_HAS_TEMPLATE_CHECK_PARAMS_TYPE</span><span class="special">(</span><span class="identifier">tpArray</span><span class="special">)</span> <span class="special">\</span>
  707. <span class="identifier">BOOST_VMD_IDENTITY_RESULT</span> <span class="special">\</span>
  708. <span class="special">(</span> <span class="special">\</span>
  709. <span class="identifier">BOOST_PP_IIF</span> <span class="special">\</span>
  710. <span class="special">(</span> <span class="special">\</span>
  711. <span class="identifier">BOOST_VMD_IS_ARRAY</span><span class="special">(</span><span class="identifier">tpArray</span><span class="special">),</span> <span class="special">\</span>
  712. <span class="identifier">BOOST_VMD_IDENTITY</span><span class="special">(</span><span class="identifier">ARRAY</span><span class="special">),</span> <span class="special">\</span>
  713. <span class="identifier">BOOST_TTI_DETAIL_TRAIT_CALL_HAS_TEMPLATE_CHECK_PARAMS_TYPE_LIST</span> <span class="special">\</span>
  714. <span class="special">)</span> <span class="special">\</span>
  715. <span class="special">(</span><span class="identifier">tpArray</span><span class="special">)</span> <span class="special">\</span>
  716. <span class="special">)</span> <span class="special">\</span>
  717. <span class="comment">/**/</span>
  718. <span class="preprocessor">#define</span> <span class="identifier">BOOST_TTI_DETAIL_TRAIT_CALL_HAS_TEMPLATE_CHECK_PARAMS_TYPE_LIST</span><span class="special">(</span><span class="identifier">tpArray</span><span class="special">)</span> <span class="special">\</span>
  719. <span class="identifier">BOOST_VMD_IDENTITY_RESULT</span> <span class="special">\</span>
  720. <span class="special">(</span> <span class="special">\</span>
  721. <span class="identifier">BOOST_PP_IIF</span> <span class="special">\</span>
  722. <span class="special">(</span> <span class="special">\</span>
  723. <span class="identifier">BOOST_VMD_IS_LIST</span><span class="special">(</span><span class="identifier">tpArray</span><span class="special">),</span> <span class="special">\</span>
  724. <span class="identifier">BOOST_VMD_IDENTITY</span><span class="special">(</span><span class="identifier">LIST</span><span class="special">),</span> <span class="special">\</span>
  725. <span class="identifier">BOOST_TTI_DETAIL_TRAIT_CALL_HAS_TEMPLATE_CHECK_PARAMS_TYPE_SEQ</span> <span class="special">\</span>
  726. <span class="special">)</span> <span class="special">\</span>
  727. <span class="special">(</span><span class="identifier">tpArray</span><span class="special">)</span> <span class="special">\</span>
  728. <span class="special">)</span> <span class="special">\</span>
  729. <span class="comment">/**/</span>
  730. <span class="preprocessor">#define</span> <span class="identifier">BOOST_TTI_DETAIL_TRAIT_CALL_HAS_TEMPLATE_CHECK_PARAMS_TYPE_SEQ</span><span class="special">(</span><span class="identifier">tpArray</span><span class="special">)</span> <span class="special">\</span>
  731. <span class="identifier">BOOST_VMD_IDENTITY_RESULT</span> <span class="special">\</span>
  732. <span class="special">(</span> <span class="special">\</span>
  733. <span class="identifier">BOOST_PP_IIF</span> <span class="special">\</span>
  734. <span class="special">(</span> <span class="special">\</span>
  735. <span class="identifier">BOOST_VMD_IS_SEQ</span><span class="special">(</span><span class="identifier">tpArray</span><span class="special">),</span> <span class="special">\</span>
  736. <span class="identifier">BOOST_VMD_IDENTITY</span><span class="special">(</span><span class="identifier">SEQ</span><span class="special">),</span> <span class="special">\</span>
  737. <span class="identifier">BOOST_TTI_DETAIL_TRAIT_CALL_HAS_TEMPLATE_CHECK_PARAMS_TYPE_TUPLE</span> <span class="special">\</span>
  738. <span class="special">)</span> <span class="special">\</span>
  739. <span class="special">(</span><span class="identifier">tpArray</span><span class="special">)</span> <span class="special">\</span>
  740. <span class="special">)</span> <span class="special">\</span>
  741. <span class="comment">/**/</span>
  742. <span class="preprocessor">#define</span> <span class="identifier">BOOST_TTI_DETAIL_TRAIT_CALL_HAS_TEMPLATE_CHECK_PARAMS_TYPE_TUPLE</span><span class="special">(</span><span class="identifier">tpArray</span><span class="special">)</span> <span class="special">\</span>
  743. <span class="identifier">BOOST_VMD_IDENTITY_RESULT</span> <span class="special">\</span>
  744. <span class="special">(</span> <span class="special">\</span>
  745. <span class="identifier">BOOST_PP_EXPR_IIF</span> <span class="special">\</span>
  746. <span class="special">(</span> <span class="special">\</span>
  747. <span class="identifier">BOOST_VMD_IS_TUPLE</span><span class="special">(</span><span class="identifier">tpArray</span><span class="special">),</span> <span class="special">\</span>
  748. <span class="identifier">BOOST_VMD_IDENTITY</span><span class="special">(</span><span class="identifier">TUPLE</span><span class="special">)</span> <span class="special">\</span>
  749. <span class="special">)</span> <span class="special">\</span>
  750. <span class="special">)</span> <span class="special">\</span>
  751. <span class="comment">/**/</span>
  752. <span class="preprocessor">#define</span> <span class="identifier">BOOST_TTI_DETAIL_TRAIT_CALL_HAS_TEMPLATE_CHECK_PARAMS_TYPE_CONCAT</span><span class="special">(</span><span class="identifier">trait</span><span class="special">,</span><span class="identifier">name</span><span class="special">,</span><span class="identifier">tpArray</span><span class="special">,</span><span class="identifier">name</span><span class="special">)</span> <span class="special">\</span>
  753. <span class="special">(</span> <span class="identifier">BOOST_PP_ADD</span><span class="special">(</span><span class="identifier">BOOST_PP_</span> <span class="special">##</span> <span class="identifier">name</span> <span class="special">##</span> <span class="identifier">_SIZE</span><span class="special">(</span><span class="identifier">tpArray</span><span class="special">),</span><span class="number">4</span><span class="special">),</span> <span class="special">(</span> <span class="identifier">trait</span><span class="special">,</span> <span class="identifier">name</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="keyword">false</span><span class="special">,</span> <span class="identifier">BOOST_PP_</span> <span class="special">##</span> <span class="identifier">name</span> <span class="special">##</span> <span class="identifier">_ENUM</span><span class="special">(</span><span class="identifier">tpArray</span><span class="special">)</span> <span class="special">)</span> <span class="special">)</span> <span class="special">\</span>
  754. <span class="comment">/**/</span>
  755. <span class="preprocessor">#else</span>
  756. <span class="preprocessor">#define</span> <span class="identifier">BOOST_TTI_DETAIL_TRAIT_CALL_HAS_TEMPLATE_CHECK_PARAMS</span><span class="special">(</span><span class="identifier">trait</span><span class="special">,</span><span class="identifier">name</span><span class="special">,</span><span class="identifier">tpArray</span><span class="special">)</span> <span class="special">\</span>
  757. <span class="identifier">BOOST_TTI_DETAIL_HAS_MEMBER_WITH_TEMPLATE_SFINAE</span> <span class="special">\</span>
  758. <span class="special">(</span> <span class="special">\</span>
  759. <span class="special">(</span> <span class="identifier">BOOST_PP_ADD</span><span class="special">(</span><span class="identifier">BOOST_PP_ARRAY_SIZE</span><span class="special">(</span><span class="identifier">tpArray</span><span class="special">),</span><span class="number">4</span><span class="special">),</span> <span class="special">(</span> <span class="identifier">trait</span><span class="special">,</span> <span class="identifier">name</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="keyword">false</span><span class="special">,</span> <span class="identifier">BOOST_PP_ARRAY_ENUM</span><span class="special">(</span><span class="identifier">tpArray</span><span class="special">)</span> <span class="special">)</span> <span class="special">)</span> <span class="special">\</span>
  760. <span class="special">)</span> <span class="special">\</span>
  761. <span class="comment">/**/</span>
  762. <span class="preprocessor">#endif</span>
  763. </pre>
  764. <p>
  765. This of course gets more elaborate, but could be shortened considerably if
  766. we chose to use BOOST_VMD_GET_TYPE and the invented BOOST_VMD_SWITCH of our
  767. first example. We will assume in this second version of the code above that
  768. our BOOST_VMD_SWITCH macro has been #included from somewhere.
  769. </p>
  770. <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">preprocessor</span><span class="special">/</span><span class="identifier">arithmetic</span><span class="special">/</span><span class="identifier">add</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  771. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">array</span><span class="special">/</span><span class="keyword">enum</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  772. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">array</span><span class="special">/</span><span class="identifier">size</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  773. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">list</span><span class="special">/</span><span class="keyword">enum</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  774. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">list</span><span class="special">/</span><span class="identifier">size</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  775. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">seq</span><span class="special">/</span><span class="keyword">enum</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  776. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">seq</span><span class="special">/</span><span class="identifier">size</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  777. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">tuple</span><span class="special">/</span><span class="keyword">enum</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  778. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">tuple</span><span class="special">/</span><span class="identifier">size</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  779. <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>
  780. <span class="preprocessor">#if</span> <span class="identifier">BOOST_PP_VARIADICS</span>
  781. <span class="preprocessor">#define</span> <span class="identifier">BOOST_TTI_DETAIL_TRAIT_CALL_HAS_TEMPLATE_CHECK_PARAMS</span><span class="special">(</span><span class="identifier">trait</span><span class="special">,</span><span class="identifier">name</span><span class="special">,</span><span class="identifier">tpArray</span><span class="special">)</span> <span class="special">\</span>
  782. <span class="identifier">BOOST_TTI_DETAIL_HAS_MEMBER_WITH_TEMPLATE_SFINAE</span> <span class="special">\</span>
  783. <span class="special">(</span> <span class="special">\</span>
  784. <span class="identifier">BOOST_TTI_DETAIL_TRAIT_CALL_HAS_TEMPLATE_CHECK_PARAMS_TYPE_CONCAT</span> <span class="special">\</span>
  785. <span class="special">(</span> <span class="special">\</span>
  786. <span class="identifier">trait</span><span class="special">,</span><span class="identifier">name</span><span class="special">,</span><span class="identifier">tpArray</span><span class="special">,</span> <span class="special">\</span>
  787. <span class="identifier">BOOST_VMD_SWITCH</span> <span class="special">\</span>
  788. <span class="special">(</span> <span class="special">\</span>
  789. <span class="identifier">BOOST_VMD_GET_TYPE</span><span class="special">(</span><span class="identifier">tpArray</span><span class="special">),</span> <span class="special">\</span>
  790. <span class="special">(</span><span class="number">1</span><span class="special">),</span> <span class="special">\</span>
  791. <span class="special">(</span><span class="identifier">BOOST_VMD_TYPE_ARRAY</span><span class="special">,</span><span class="identifier">BOOST_VMD_SWITCH_IDENTITY</span><span class="special">(</span><span class="identifier">ARRAY</span><span class="special">)),</span> <span class="special">\</span>
  792. <span class="special">(</span><span class="identifier">BOOST_VMD_TYPE_LIST</span><span class="special">,</span><span class="identifier">BOOST_VMD_SWITCH_IDENTITY</span><span class="special">(</span><span class="identifier">LIST</span><span class="special">)),</span> <span class="special">\</span>
  793. <span class="special">(</span><span class="identifier">BOOST_VMD_TYPE_SEQ</span><span class="special">,</span><span class="identifier">BOOST_VMD_SWITCH_IDENTITY</span><span class="special">(</span><span class="identifier">SEQ</span><span class="special">)),</span> <span class="special">\</span>
  794. <span class="special">(</span><span class="identifier">BOOST_VMD_TYPE_TUPLE</span><span class="special">,</span><span class="identifier">BOOST_VMD_SWITCH_IDENTITY</span><span class="special">(</span><span class="identifier">TUPLE</span><span class="special">))</span> <span class="special">\</span>
  795. <span class="special">)</span> <span class="special">\</span>
  796. <span class="special">)</span> <span class="special">\</span>
  797. <span class="special">)</span> <span class="special">\</span>
  798. <span class="comment">/**/</span>
  799. <span class="preprocessor">#define</span> <span class="identifier">BOOST_TTI_DETAIL_TRAIT_CALL_HAS_TEMPLATE_CHECK_PARAMS_TYPE_CONCAT</span><span class="special">(</span><span class="identifier">trait</span><span class="special">,</span><span class="identifier">name</span><span class="special">,</span><span class="identifier">tpArray</span><span class="special">,</span><span class="identifier">name</span><span class="special">)</span> <span class="special">\</span>
  800. <span class="special">(</span> <span class="identifier">BOOST_PP_ADD</span><span class="special">(</span><span class="identifier">BOOST_PP_</span> <span class="special">##</span> <span class="identifier">name</span> <span class="special">##</span> <span class="identifier">_SIZE</span><span class="special">(</span><span class="identifier">tpArray</span><span class="special">),</span><span class="number">4</span><span class="special">),</span> <span class="special">(</span> <span class="identifier">trait</span><span class="special">,</span> <span class="identifier">name</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="keyword">false</span><span class="special">,</span> <span class="identifier">BOOST_PP_</span> <span class="special">##</span> <span class="identifier">name</span> <span class="special">##</span> <span class="identifier">_ENUM</span><span class="special">(</span><span class="identifier">tpArray</span><span class="special">)</span> <span class="special">)</span> <span class="special">)</span> <span class="special">\</span>
  801. <span class="comment">/**/</span>
  802. <span class="preprocessor">#else</span>
  803. <span class="preprocessor">#define</span> <span class="identifier">BOOST_TTI_DETAIL_TRAIT_CALL_HAS_TEMPLATE_CHECK_PARAMS</span><span class="special">(</span><span class="identifier">trait</span><span class="special">,</span><span class="identifier">name</span><span class="special">,</span><span class="identifier">tpArray</span><span class="special">)</span> <span class="special">\</span>
  804. <span class="identifier">BOOST_TTI_DETAIL_HAS_MEMBER_WITH_TEMPLATE_SFINAE</span> <span class="special">\</span>
  805. <span class="special">(</span> <span class="special">\</span>
  806. <span class="special">(</span> <span class="identifier">BOOST_PP_ADD</span><span class="special">(</span><span class="identifier">BOOST_PP_ARRAY_SIZE</span><span class="special">(</span><span class="identifier">tpArray</span><span class="special">),</span><span class="number">4</span><span class="special">),</span> <span class="special">(</span> <span class="identifier">trait</span><span class="special">,</span> <span class="identifier">name</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="keyword">false</span><span class="special">,</span> <span class="identifier">BOOST_PP_ARRAY_ENUM</span><span class="special">(</span><span class="identifier">tpArray</span><span class="special">)</span> <span class="special">)</span> <span class="special">)</span> <span class="special">\</span>
  807. <span class="special">)</span> <span class="special">\</span>
  808. <span class="comment">/**/</span>
  809. <span class="preprocessor">#endif</span>
  810. </pre>
  811. <p>
  812. This is shorter and easier to understand. The '(1)' passed as the calling values
  813. to BOOST_VMD_SWITCH could just as well be '()' but VC8 has trouble with empty
  814. parentheses so I avoid it here.
  815. </p>
  816. <p>
  817. In the case of the TTI, is such a change worth it to give more flexibility
  818. to the end-user ? In reality, because the variadic version of passing the specific
  819. template parameters as variadic data is syntactically easier to use than any
  820. of the Boost PP composite forms, I am actually happy enough with that use not
  821. to pursue the sort of functionality I presented in this example. But the example
  822. nonetheless shows the power of the VMD functionality for creating macros which
  823. add flexibility when the macro programmer feels he needs it for his library.
  824. </p>
  825. </div>
  826. <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
  827. <td align="left"></td>
  828. <td align="right"><div class="copyright-footer">Copyright &#169; 2010-2017 Tropic Software
  829. East Inc</div></td>
  830. </tr></table>
  831. <hr>
  832. <div class="spirit-nav">
  833. <a accesskey="p" href="vmd_conv.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="../variadic_macro_data_reference.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
  834. </div>
  835. </body>
  836. </html>