1<html> 2<head> 3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 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 1. The Variadic Macro Data Library 1.9"> 8<link rel="up" href="../index.html" title="Chapter 1. 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"><</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">></span> 98 99<span class="preprocessor">#if</span> <span class="identifier">BOOST_PP_VARIADICS</span> 100 101<span class="preprocessor">#include</span> <span class="special"><</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">></span> 102<span class="preprocessor">#include</span> <span class="special"><</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">></span> 103<span class="preprocessor">#include</span> <span class="special"><</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">></span> 104<span class="preprocessor">#include</span> <span class="special"><</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">></span> 105<span class="preprocessor">#include</span> <span class="special"><</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">></span> 106<span class="preprocessor">#include</span> <span class="special"><</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">></span> 107<span class="preprocessor">#include</span> <span class="special"><</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">></span> 108<span class="preprocessor">#include</span> <span class="special"><</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">></span> 109<span class="preprocessor">#include</span> <span class="special"><</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">></span> 110<span class="preprocessor">#include</span> <span class="special"><</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">></span> 111<span class="preprocessor">#include</span> <span class="special"><</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">></span> 112<span class="preprocessor">#include</span> <span class="special"><</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">></span> 113<span class="preprocessor">#include</span> <span class="special"><</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">></span> 114<span class="preprocessor">#include</span> <span class="special"><</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">></span> 115<span class="preprocessor">#include</span> <span class="special"><</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">></span> 116<span class="preprocessor">#include</span> <span class="special"><</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">></span> 117 118<span class="comment">/* 119 120 State index into state values 121 122*/</span> 123 124<span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_SWITCH_STATE_ELEM_INDEX</span> <span class="number">2</span> 125<span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_SWITCH_STATE_ELEM_DEFAULT</span> <span class="number">4</span> 126<span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_SWITCH_STATE_ELEM_RESULT</span> <span class="number">5</span> 127 128<span class="comment">/* 129 130 Retrieve the state value, never changes 131 132*/</span> 133 134<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> 135 <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> 136<span class="comment">/**/</span> 137 138<span class="comment">/* 139 140 Retrieve the state tuple of values, never changes 141 142*/</span> 143 144<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> 145 <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> 146<span class="comment">/**/</span> 147 148<span class="comment">/* 149 150 Retrieve the state index 151 152*/</span> 153 154<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> 155 <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> 156<span class="comment">/**/</span> 157 158<span class="comment">/* 159 160 Retrieve the state tuple of values size, never changes 161 162*/</span> 163 164<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> 165 <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> 166<span class="comment">/**/</span> 167 168<span class="comment">/* 169 170 Retrieve the state default tuple 171 172*/</span> 173 174<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> 175 <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> 176<span class="comment">/**/</span> 177 178<span class="comment">/* 179 180 Retrieve the state result tuple 181 182*/</span> 183 184<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> 185 <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> 186<span class="comment">/**/</span> 187 188<span class="comment">/* 189 190 Retrieve the current value tuple 191 192*/</span> 193 194<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> 195 <span class="identifier">BOOST_PP_TUPLE_ELEM</span> <span class="special">\</span> 196 <span class="special">(</span> <span class="special">\</span> 197 <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> 198 <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> 199 <span class="special">)</span> <span class="special">\</span> 200<span class="comment">/**/</span> 201 202<span class="comment">/* 203 204 Expands to the state 205 206 value = value to compare against 207 tuple = choices as a tuple of values 208 size = size of tuple of values 209 210 None of these ever change in the WHILE state 211 212*/</span> 213 214<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> 215 <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> 216<span class="comment">/**/</span> 217 218<span class="comment">/* 219 220 Expands to the WHILE state 221 222 The state to our WHILE consists of a tuple of elements: 223 224 1: value to compare against 225 2: tuple of values. Each value is a value/macro pair or if the default just a macro 226 3: index into the values 227 4: tuple for default macro. 0 means no default macro, 1 means default macro and then second value is the default macro. 228 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. 229 230*/</span> 231 232<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> 233 <span class="identifier">BOOST_VMD_SWITCH_STATE_EXPAND</span> <span class="special">\</span> 234 <span class="special">(</span> <span class="special">\</span> 235 <span class="identifier">value</span><span class="special">,</span> <span class="special">\</span> 236 <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> 237 <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> 238 <span class="special">)</span> <span class="special">\</span> 239<span class="comment">/**/</span> 240 241<span class="comment">/* 242 243 Sets the state upon a successful match. 244 245 macro = is the matching macro found 246 247*/</span> 248 249<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> 250 <span class="identifier">BOOST_PP_TUPLE_REPLACE_D</span> <span class="special">\</span> 251 <span class="special">(</span> <span class="special">\</span> 252 <span class="identifier">d</span><span class="special">,</span> <span class="special">\</span> 253 <span class="identifier">state</span><span class="special">,</span> <span class="special">\</span> 254 <span class="identifier">BOOST_VMD_SWITCH_STATE_ELEM_RESULT</span><span class="special">,</span> <span class="special">\</span> 255 <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> 256 <span class="special">)</span> <span class="special">\</span> 257<span class="comment">/**/</span> 258 259<span class="comment">/* 260 261 Sets the state upon final failure to find a match. 262 263 def = default tuple macro, ignored 264 265*/</span> 266 267<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> 268 <span class="identifier">BOOST_PP_TUPLE_REPLACE_D</span> <span class="special">\</span> 269 <span class="special">(</span> <span class="special">\</span> 270 <span class="identifier">d</span><span class="special">,</span> <span class="special">\</span> 271 <span class="identifier">state</span><span class="special">,</span> <span class="special">\</span> 272 <span class="identifier">BOOST_VMD_SWITCH_STATE_ELEM_RESULT</span><span class="special">,</span> <span class="special">\</span> 273 <span class="special">(</span><span class="number">0</span><span class="special">,)</span> <span class="special">\</span> 274 <span class="special">)</span> <span class="special">\</span> 275<span class="comment">/**/</span> 276 277<span class="comment">/* 278 279 Increments the state index into the tuple values 280 281*/</span> 282 283<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> 284 <span class="identifier">BOOST_PP_TUPLE_REPLACE_D</span> <span class="special">\</span> 285 <span class="special">(</span> <span class="special">\</span> 286 <span class="identifier">d</span><span class="special">,</span> <span class="special">\</span> 287 <span class="identifier">state</span><span class="special">,</span> <span class="special">\</span> 288 <span class="identifier">BOOST_VMD_SWITCH_STATE_ELEM_INDEX</span><span class="special">,</span> <span class="special">\</span> 289 <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> 290 <span class="special">)</span> <span class="special">\</span> 291<span class="comment">/**/</span> 292 293<span class="comment">/* 294 295 Choose our current value's macro as our successful match 296 297 tuple = current tuple to test 298 299*/</span> 300 301<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> 302 <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> 303<span class="comment">/**/</span> 304 305<span class="comment">/* 306 307 Update our state index 308 309 tuple = current tuple to test, ignored 310 311*/</span> 312 313<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> 314 <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> 315<span class="comment">/**/</span> 316 317<span class="comment">/* 318 319 Test our current value against our value to compare against 320 321 tuple = current tuple to test 322 323*/</span> 324 325<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> 326 <span class="identifier">BOOST_PP_IIF</span> <span class="special">\</span> 327 <span class="special">(</span> <span class="special">\</span> 328 <span class="identifier">BOOST_VMD_EQUAL_D</span> <span class="special">\</span> 329 <span class="special">(</span> <span class="special">\</span> 330 <span class="identifier">d</span><span class="special">,</span> <span class="special">\</span> 331 <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> 332 <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> 333 <span class="special">),</span> <span class="special">\</span> 334 <span class="identifier">BOOST_VMD_SWITCH_OP_TEST_CURRENT_VALUE_MATCH</span><span class="special">,</span> <span class="special">\</span> 335 <span class="identifier">BOOST_VMD_SWITCH_OP_TEST_CURRENT_VALUE_UPDATE_INDEX</span> <span class="special">\</span> 336 <span class="special">)</span> <span class="special">\</span> 337 <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> 338<span class="comment">/**/</span> 339 340<span class="comment">/* 341 342 Set our default macro and update the index in our WHILE state 343 344 tuple = current tuple to test 345 346*/</span> 347 348<span class="preprocessor">#if</span> <span class="identifier">BOOST_VMD_MSVC</span> 349 350<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> 351 <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> 352<span class="comment">/**/</span> 353 354<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> 355 <span class="identifier">BOOST_VMD_SWITCH_OP_UPDATE_INDEX</span> <span class="special">\</span> 356 <span class="special">(</span> <span class="special">\</span> 357 <span class="identifier">d</span><span class="special">,</span> <span class="special">\</span> 358 <span class="identifier">BOOST_PP_TUPLE_REPLACE_D</span> <span class="special">\</span> 359 <span class="special">(</span> <span class="special">\</span> 360 <span class="identifier">d</span><span class="special">,</span> <span class="special">\</span> 361 <span class="identifier">state</span><span class="special">,</span> <span class="special">\</span> 362 <span class="identifier">BOOST_VMD_SWITCH_STATE_ELEM_DEFAULT</span><span class="special">,</span> <span class="special">\</span> 363 <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> 364 <span class="special">)</span> <span class="special">\</span> 365 <span class="special">)</span> <span class="special">\</span> 366<span class="comment">/**/</span> 367 368<span class="preprocessor">#else</span> 369 370<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> 371 <span class="identifier">BOOST_VMD_SWITCH_OP_UPDATE_INDEX</span> <span class="special">\</span> 372 <span class="special">(</span> <span class="special">\</span> 373 <span class="identifier">d</span><span class="special">,</span> <span class="special">\</span> 374 <span class="identifier">BOOST_PP_TUPLE_REPLACE_D</span> <span class="special">\</span> 375 <span class="special">(</span> <span class="special">\</span> 376 <span class="identifier">d</span><span class="special">,</span> <span class="special">\</span> 377 <span class="identifier">state</span><span class="special">,</span> <span class="special">\</span> 378 <span class="identifier">BOOST_VMD_SWITCH_STATE_ELEM_DEFAULT</span><span class="special">,</span> <span class="special">\</span> 379 <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> 380 <span class="special">)</span> <span class="special">\</span> 381 <span class="special">)</span> <span class="special">\</span> 382<span class="comment">/**/</span> 383 384<span class="preprocessor">#endif</span> 385 386<span class="comment">/* 387 388 If our current value is a default macro, just set the default macro, 389 else test our current value. 390 391 tuple = current tuple to test 392 393*/</span> 394 395<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> 396 <span class="identifier">BOOST_PP_IIF</span> <span class="special">\</span> 397 <span class="special">(</span> <span class="special">\</span> 398 <span class="identifier">BOOST_PP_EQUAL_D</span> <span class="special">\</span> 399 <span class="special">(</span> <span class="special">\</span> 400 <span class="identifier">d</span><span class="special">,</span> <span class="special">\</span> 401 <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> 402 <span class="number">1</span> <span class="special">\</span> 403 <span class="special">),</span> <span class="special">\</span> 404 <span class="identifier">BOOST_VMD_SWITCH_OP_TEST_CURRENT_CREATE_DEFAULT</span><span class="special">,</span> <span class="special">\</span> 405 <span class="identifier">BOOST_VMD_SWITCH_OP_TEST_CURRENT_VALUE</span> <span class="special">\</span> 406 <span class="special">)</span> <span class="special">\</span> 407 <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> 408<span class="comment">/**/</span> 409 410<span class="comment">/* 411 412 Test the current value in our tuple of values 413 414*/</span> 415 416<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> 417 <span class="identifier">BOOST_VMD_SWITCH_OP_TEST_CURRENT_TUPLE</span> <span class="special">\</span> 418 <span class="special">(</span> <span class="special">\</span> 419 <span class="identifier">d</span><span class="special">,</span> <span class="special">\</span> 420 <span class="identifier">state</span><span class="special">,</span> <span class="special">\</span> 421 <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> 422 <span class="special">)</span> <span class="special">\</span> 423<span class="comment">/**/</span> 424 425<span class="comment">/* 426 427 Choose the default macro as our successful match 428 429 def = default tuple consisting of just the default macro name 430 431*/</span> 432 433<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> 434 <span class="identifier">BOOST_VMD_SWITCH_OP_SUCCESS</span> <span class="special">\</span> 435 <span class="special">(</span> <span class="special">\</span> 436 <span class="identifier">d</span><span class="special">,</span> <span class="special">\</span> 437 <span class="identifier">state</span><span class="special">,</span> <span class="special">\</span> 438 <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> 439 <span class="special">)</span> <span class="special">\</span> 440<span class="comment">/**/</span> 441 442<span class="comment">/* 443 444 If the default macro exists, choose it else indicate no macro was found 445 446 def = default tuple consisting of just the default macro name 447 448*/</span> 449 450<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> 451 <span class="identifier">BOOST_PP_IIF</span> <span class="special">\</span> 452 <span class="special">(</span> <span class="special">\</span> 453 <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> 454 <span class="identifier">BOOST_VMD_SWITCH_OP_DEFAULT_RET_CHOSEN</span><span class="special">,</span> <span class="special">\</span> 455 <span class="identifier">BOOST_VMD_SWITCH_OP_FAILURE</span> <span class="special">\</span> 456 <span class="special">)</span> <span class="special">\</span> 457 <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> 458<span class="comment">/**/</span> 459 460<span class="comment">/* 461 462 Try to choose the default macro if it exists 463 464*/</span> 465 466<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> 467 <span class="identifier">BOOST_VMD_SWITCH_OP_DEFAULT_RET</span> <span class="special">\</span> 468 <span class="special">(</span> <span class="special">\</span> 469 <span class="identifier">d</span><span class="special">,</span> <span class="special">\</span> 470 <span class="identifier">state</span><span class="special">,</span> <span class="special">\</span> 471 <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> 472 <span class="special">)</span> <span class="special">\</span> 473<span class="comment">/**/</span> 474 475<span class="comment">/* 476 477 WHILE loop operation 478 479 Check for the next value match or try to choose the default if all matches have been checked 480 481*/</span> 482 483<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> 484 <span class="identifier">BOOST_PP_IIF</span> <span class="special">\</span> 485 <span class="special">(</span> <span class="special">\</span> 486 <span class="identifier">BOOST_PP_EQUAL_D</span> <span class="special">\</span> 487 <span class="special">(</span> <span class="special">\</span> 488 <span class="identifier">d</span><span class="special">,</span> <span class="special">\</span> 489 <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> 490 <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> 491 <span class="special">),</span> <span class="special">\</span> 492 <span class="identifier">BOOST_VMD_SWITCH_OP_DEFAULT</span><span class="special">,</span> <span class="special">\</span> 493 <span class="identifier">BOOST_VMD_SWITCH_OP_TEST_CURRENT</span> <span class="special">\</span> 494 <span class="special">)</span> <span class="special">\</span> 495 <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> 496<span class="comment">/**/</span> 497 498<span class="comment">/* 499 500 WHILE loop predicate 501 502 Continue the WHILE loop if a result has not yet been specified 503 504*/</span> 505 506<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> 507 <span class="identifier">BOOST_VMD_IS_EMPTY</span> <span class="special">\</span> 508 <span class="special">(</span> <span class="special">\</span> 509 <span class="identifier">BOOST_PP_TUPLE_ELEM</span> <span class="special">\</span> 510 <span class="special">(</span> <span class="special">\</span> 511 <span class="number">0</span><span class="special">,</span> <span class="special">\</span> 512 <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> 513 <span class="special">)</span> <span class="special">\</span> 514 <span class="special">)</span> <span class="special">\</span> 515<span class="comment">/**/</span> 516 517<span class="comment">/* 518 519 Invokes the function-like macro 520 521 macro = function-like macro name 522 tparams = tuple of macro parameters 523 524*/</span> 525 526<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> 527 <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> 528<span class="comment">/**/</span> 529 530<span class="comment">/* 531 532 Processes our WHILE loop result 533 534 callp = tuple of parameters for the called macro 535 result = tuple. The first tuple element is 0 536 if no macro has been found or 1 if a macro 537 has been found. If 1 the second element is 538 the name of a function-like macro 539 540*/</span> 541 542<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> 543 <span class="identifier">BOOST_PP_EXPR_IIF</span> <span class="special">\</span> 544 <span class="special">(</span> <span class="special">\</span> 545 <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> 546 <span class="identifier">BOOST_VMD_SWITCH_PROCESS_INVOKE_MACRO</span> <span class="special">\</span> 547 <span class="special">(</span> <span class="special">\</span> 548 <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> 549 <span class="identifier">callp</span> <span class="special">\</span> 550 <span class="special">)</span> <span class="special">\</span> 551 <span class="special">)</span> <span class="special">\</span> 552<span class="comment">/**/</span> 553 554<span class="comment">/* 555 556 Use BOOST_VMD_SWITCH_IDENTITY to pass a fixed value instead 557 of a function-like macro as the second element of 558 any tuple of the variadic parameters, or as the default 559 value, to BOOST_VMD_SWITCH. 560 561*/</span> 562 563<span class="preprocessor">#if</span> <span class="identifier">BOOST_VMD_MSVC</span> 564<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> 565<span class="preprocessor">#else</span> 566<span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_SWITCH_IDENTITY</span> <span class="identifier">BOOST_VMD_IDENTITY</span> 567<span class="preprocessor">#endif</span> 568 569<span class="comment">/* 570 571 Switch macro 572 573 Parameters are: 574 575 value = value to compare against. May be any VMD data value. 576 callp = tuple of parameters for the called macro 577 variadic parameters = each parameter must be a tuple. 578 Each tuple consists of a two-element tuple. The first element is 579 a value, which may be any VMD data value, and the second element 580 is the name of a function-like macro to be called if the value 581 is equal to the value to compare against. For a default value 582 the tuple is a single-element tuple which contains the name of 583 a function-like macro to be called if no other value matches. 584 585*/</span> 586 587<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> 588 <span class="identifier">BOOST_VMD_SWITCH_PROCESS</span> <span class="special">\</span> 589 <span class="special">(</span> <span class="special">\</span> 590 <span class="identifier">callp</span><span class="special">,</span> <span class="special">\</span> 591 <span class="identifier">BOOST_VMD_SWITCH_STATE_GET_RESULT</span> <span class="special">\</span> 592 <span class="special">(</span> <span class="special">\</span> 593 <span class="identifier">BOOST_PP_WHILE</span> <span class="special">\</span> 594 <span class="special">(</span> <span class="special">\</span> 595 <span class="identifier">BOOST_VMD_SWITCH_PRED</span><span class="special">,</span> <span class="special">\</span> 596 <span class="identifier">BOOST_VMD_SWITCH_OP</span><span class="special">,</span> <span class="special">\</span> 597 <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> 598 <span class="special">)</span> <span class="special">\</span> 599 <span class="special">)</span> <span class="special">\</span> 600 <span class="special">)</span> <span class="special">\</span> 601<span class="comment">/**/</span> 602 603<span class="preprocessor">#endif</span> <span class="comment">/* BOOST_PP_VARIADICS */</span> 604</pre> 605<p> 606 The code is fairly involved but it is commented so that it can be understood. 607 There are a few workarounds for a VC++ preprocessor problem, which I discovered, 608 having to do with passing the name of a function-like macro in a tuple. 609 </p> 610<p> 611 The BOOST_VMD_SWITCH macro can be used with either macros to call or with fixed 612 values to return. When specifying macros to call the macro name is the second 613 element of the corresponding value-macro tuple, or in the 'default' case it 614 is just the macro name itself. When specifying fixed values to return the macro 615 'name' is BOOST_VMD_SWITCH_IDENTITY(fixed_value), whether as the second element 616 of the corresponding value-macro tuple or as the macro 'name' of the 'default' 617 case. In the variadic parameters the user can mix macro names and fixed values 618 as he likes. 619 </p> 620<p> 621 Some simple examples: 622 </p> 623<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> 624 <span class="identifier">test1_</span> <span class="special">##</span> <span class="identifier">number</span> 625<span class="comment">/**/</span> 626 627<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> 628 <span class="identifier">test2_</span> <span class="special">##</span> <span class="identifier">number</span> 629<span class="comment">/**/</span> 630 631<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> 632 <span class="identifier">test3_</span> <span class="special">##</span> <span class="identifier">number</span> 633<span class="comment">/**/</span> 634 635<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> 636 <span class="identifier">test_default_</span> <span class="special">##</span> <span class="identifier">number</span> 637<span class="comment">/**/</span> 638</pre> 639<p> 640 We will use these simple macros in our calls to BOOST_VMD_SWITCH. 641 </p> 642<pre class="programlisting"><span class="identifier">BOOST_VMD_SWITCH</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> 643 <span class="special">(</span><span class="number">7</span><span class="special">),</span> 644 <span class="special">(</span><span class="identifier">BOOST_VMD_SWITCH_TEST_DEFAULT</span><span class="special">),</span> 645 <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> 646 <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> 647 <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> 648 <span class="special">)</span> 649</pre> 650<p> 651 Here our macro will return 'test1_7'. 652 </p> 653<p> 654 Notice that 'cases' can be in any order. 655 </p> 656<pre class="programlisting"><span class="identifier">BOOST_VMD_SWITCH</span><span class="special">(</span><span class="number">4</span><span class="special">,</span> 657 <span class="special">(</span><span class="number">7</span><span class="special">),</span> 658 <span class="special">(</span><span class="identifier">BOOST_VMD_SWITCH_TEST_DEFAULT</span><span class="special">),</span> 659 <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> 660 <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> 661 <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> 662 <span class="special">)</span> 663</pre> 664<p> 665 Here are macro uses the default case and returns 'test_default_7'. 666 </p> 667<pre class="programlisting"><span class="identifier">BOOST_VMD_SWITCH</span><span class="special">(</span><span class="number">143</span><span class="special">,</span> 668 <span class="special">(</span><span class="number">7</span><span class="special">),</span> 669 <span class="special">(</span><span class="identifier">BOOST_VMD_SWITCH_TEST_DEFAULT</span><span class="special">),</span> 670 <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> 671 <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> 672 <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> 673 <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> 674 <span class="special">)</span> 675</pre> 676<p> 677 This shows how the matching case can be a fixed_value as the macro 'name'. 678 </p> 679<pre class="programlisting"><span class="identifier">BOOST_VMD_SWITCH</span><span class="special">(</span><span class="number">155</span><span class="special">,</span> 680 <span class="special">(</span><span class="number">7</span><span class="special">),</span> 681 <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> 682 <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> 683 <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> 684 <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> 685 <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> 686 <span class="special">)</span> 687</pre> 688<p> 689 This shows how the default value can be a fixed_value as the macro 'name'. 690 </p> 691<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> 692 <span class="special">(</span><span class="number">7</span><span class="special">),</span> 693 <span class="special">(</span><span class="identifier">BOOST_VMD_SWITCH_TEST_DEFAULT</span><span class="special">),</span> 694 <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> 695 <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> 696 <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> 697 <span class="special">)</span> 698</pre> 699<p> 700 This shows that the 'value' and each 'case' matching values can be different 701 data types just as long as the types are one which VMD can parse. 702 </p> 703<p> 704 There is more that can be done with the BOOST_VMD_SWITCH code but as it is 705 I believe it could be useful for programmers writing macro code. For instance 706 there is no checking that more than one 'case' value is the same. We could 707 generate a BOOST_VMD_ASSERT if that were the situation. There is no concept 708 of falling through to the next 'case' as their is when 'break' is not used 709 at the bottom of a particular C++ 'case' statement. Nonetheless the example 710 gives the macro programmer an idea of what can be done using the BOOST_VMD_EQUAL 711 macro in treating data types generically, using BOOST_VMD_IS_EMPTY to test 712 for emptiness and using BOOST_VMD_IDENTITY to generate a fixed value when a 713 macro call is made. 714 </p> 715<h4> 716<a name="variadic_macro_data.vmd_examples.h1"></a> 717 <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 718 inner template</a> 719 </h4> 720<p> 721 As a more practical example, just to show the possible use of VMD functionality 722 in current Boost code, I will briefly illustrate a change that could be made 723 to the TTI library when using VMD functionality. 724 </p> 725<p> 726 The Boost TTI library, of which the current developer of VMD is also the developer, 727 specifies a way to introspect an inner class template of a class. The introspection 728 can occur for an inner class template of specific template parameters. 729 </p> 730<p> 731 In the library a macro is used to generate the metafunction which allows the 732 introspection to work. The macro used is called BOOST_TTI_TEMPLATE. The macro 733 has both a variadic version and a non-variadic version. 734 </p> 735<p> 736 In the non-variadic version the macro always takes two parameters for introspecting 737 for specific template parameters. The first parameter is the name of the template 738 and the second parameter is an array of the specific template parameters ( 739 with or without the parameter names themselves ). So for a class template of 740 the form: 741 </p> 742<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</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">></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> 743</pre> 744<p> 745 the non-variadic macro would be: 746 </p> 747<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> 748</pre> 749<p> 750 I chose a Boost PP array rather than a Boost PP seq or a Boost PP list as I 751 felt the notation for specifying the template parameters was closer with the 752 array than with the others. Choosing a Boost PP tuple was not an option since 753 for non-variadic macros there is no way to automatically know the tuple size, 754 so an array was preferred. 755 </p> 756<p> 757 For the variadic version variadic parameters are used so the notation would 758 be: 759 </p> 760<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> 761</pre> 762<p> 763 since this is the most natural notation. 764 </p> 765<p> 766 But for compatibility with the non-variadic version the end-user with variadic 767 macro support could also choose the Boost PP array form above. 768 </p> 769<p> 770 Using VMD the variadic version could support any of the other Boost PP composite 771 types for the specific template parameters, even though I feel that the variadic 772 parameters form is easiest to use. In this scenario a user could specify: 773 </p> 774<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> 775</pre> 776<p> 777 or 778 </p> 779<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> 780</pre> 781<p> 782 or 783 </p> 784<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> 785</pre> 786<p> 787 The only change needed would be in the code which takes the second parameter 788 and converts it to the final form used internally ( a Boost PP array ). This 789 occurs in the macro BOOST_TTI_DETAIL_TRAIT_CALL_HAS_TEMPLATE_CHECK_PARAMS in 790 the <boost/tti/detail/dtemplate_params.hpp> file. The code has two situations, 791 one for VC++8 or below and one for all other compilers. For our example we 792 will concentrate just on the one for all other compilers. You do not need to 793 know what the code does internally to complete the creation of the appropriate 794 metafunction to follow this example. The macro code in question looks like 795 this: 796 </p> 797<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> 798 <span class="identifier">BOOST_TTI_DETAIL_HAS_MEMBER_WITH_TEMPLATE_SFINAE</span> <span class="special">\</span> 799 <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_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> 801 <span class="special">)</span> <span class="special">\</span> 802<span class="comment">/**/</span> 803</pre> 804<p> 805 In this code we are taking the name of the metafunction ( trait ), the name 806 of the template ( name ), and our specific template parameters ( tpArray ) 807 and passing the information in the form of a Boost PP array to another macro, 808 which will eventually create the metafunction which the end-user uses to test 809 if such a class template exists within some enclosing class. Even if tpArray 810 were a list, seq, or tuple we still want to pass the information internally 811 to BOOST_TTI_DETAIL_HAS_MEMBER_WITH_TEMPLATE_SFINAE in the form you can see 812 above, which is a Boost PP array. We don't need or want to change that internal 813 representation. 814 </p> 815<p> 816 The current code, used by both the non-variadic and variadic version of the 817 BOOST_TTI_TEMPLATE template, assumes the 'tpArray' parameter is a Boost PP 818 array. But if it could be a tuple, seq, or list in the variadic version the 819 code could become, with the appropriate Boost PP and VMD header files: 820 </p> 821<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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">></span> 822<span class="preprocessor">#include</span> <span class="special"><</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">></span> 823<span class="preprocessor">#include</span> <span class="special"><</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">></span> 824<span class="preprocessor">#include</span> <span class="special"><</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">></span> 825<span class="preprocessor">#include</span> <span class="special"><</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">></span> 826<span class="preprocessor">#include</span> <span class="special"><</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">></span> 827<span class="preprocessor">#include</span> <span class="special"><</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">></span> 828<span class="preprocessor">#include</span> <span class="special"><</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">></span> 829<span class="preprocessor">#include</span> <span class="special"><</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">></span> 830<span class="preprocessor">#include</span> <span class="special"><</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">></span> 831<span class="preprocessor">#include</span> <span class="special"><</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">></span> 832<span class="preprocessor">#include</span> <span class="special"><</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">></span> 833<span class="preprocessor">#include</span> <span class="special"><</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">></span> 834<span class="preprocessor">#include</span> <span class="special"><</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">></span> 835<span class="preprocessor">#include</span> <span class="special"><</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">></span> 836<span class="preprocessor">#include</span> <span class="special"><</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">></span> 837 838<span class="preprocessor">#if</span> <span class="identifier">BOOST_PP_VARIADICS</span> 839 840<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> 841 <span class="identifier">BOOST_TTI_DETAIL_HAS_MEMBER_WITH_TEMPLATE_SFINAE</span> <span class="special">\</span> 842 <span class="special">(</span> <span class="special">\</span> 843 <span class="identifier">BOOST_TTI_DETAIL_TRAIT_CALL_HAS_TEMPLATE_CHECK_PARAMS_TYPE_CONCAT</span> <span class="special">\</span> 844 <span class="special">(</span> <span class="special">\</span> 845 <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> 846 <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> 847 <span class="special">)</span> <span class="special">\</span> 848 <span class="special">)</span> <span class="special">\</span> 849<span class="comment">/**/</span> 850 851<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> 852 <span class="identifier">BOOST_VMD_IDENTITY_RESULT</span> <span class="special">\</span> 853 <span class="special">(</span> <span class="special">\</span> 854 <span class="identifier">BOOST_PP_IIF</span> <span class="special">\</span> 855 <span class="special">(</span> <span class="special">\</span> 856 <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> 857 <span class="identifier">BOOST_VMD_IDENTITY</span><span class="special">(</span><span class="identifier">ARRAY</span><span class="special">),</span> <span class="special">\</span> 858 <span class="identifier">BOOST_TTI_DETAIL_TRAIT_CALL_HAS_TEMPLATE_CHECK_PARAMS_TYPE_LIST</span> <span class="special">\</span> 859 <span class="special">)</span> <span class="special">\</span> 860 <span class="special">(</span><span class="identifier">tpArray</span><span class="special">)</span> <span class="special">\</span> 861 <span class="special">)</span> <span class="special">\</span> 862<span class="comment">/**/</span> 863 864<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> 865 <span class="identifier">BOOST_VMD_IDENTITY_RESULT</span> <span class="special">\</span> 866 <span class="special">(</span> <span class="special">\</span> 867 <span class="identifier">BOOST_PP_IIF</span> <span class="special">\</span> 868 <span class="special">(</span> <span class="special">\</span> 869 <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> 870 <span class="identifier">BOOST_VMD_IDENTITY</span><span class="special">(</span><span class="identifier">LIST</span><span class="special">),</span> <span class="special">\</span> 871 <span class="identifier">BOOST_TTI_DETAIL_TRAIT_CALL_HAS_TEMPLATE_CHECK_PARAMS_TYPE_SEQ</span> <span class="special">\</span> 872 <span class="special">)</span> <span class="special">\</span> 873 <span class="special">(</span><span class="identifier">tpArray</span><span class="special">)</span> <span class="special">\</span> 874 <span class="special">)</span> <span class="special">\</span> 875<span class="comment">/**/</span> 876 877<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> 878 <span class="identifier">BOOST_VMD_IDENTITY_RESULT</span> <span class="special">\</span> 879 <span class="special">(</span> <span class="special">\</span> 880 <span class="identifier">BOOST_PP_IIF</span> <span class="special">\</span> 881 <span class="special">(</span> <span class="special">\</span> 882 <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> 883 <span class="identifier">BOOST_VMD_IDENTITY</span><span class="special">(</span><span class="identifier">SEQ</span><span class="special">),</span> <span class="special">\</span> 884 <span class="identifier">BOOST_TTI_DETAIL_TRAIT_CALL_HAS_TEMPLATE_CHECK_PARAMS_TYPE_TUPLE</span> <span class="special">\</span> 885 <span class="special">)</span> <span class="special">\</span> 886 <span class="special">(</span><span class="identifier">tpArray</span><span class="special">)</span> <span class="special">\</span> 887 <span class="special">)</span> <span class="special">\</span> 888<span class="comment">/**/</span> 889 890<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> 891 <span class="identifier">BOOST_VMD_IDENTITY_RESULT</span> <span class="special">\</span> 892 <span class="special">(</span> <span class="special">\</span> 893 <span class="identifier">BOOST_PP_EXPR_IIF</span> <span class="special">\</span> 894 <span class="special">(</span> <span class="special">\</span> 895 <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> 896 <span class="identifier">BOOST_VMD_IDENTITY</span><span class="special">(</span><span class="identifier">TUPLE</span><span class="special">)</span> <span class="special">\</span> 897 <span class="special">)</span> <span class="special">\</span> 898 <span class="special">)</span> <span class="special">\</span> 899<span class="comment">/**/</span> 900 901<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> 902 <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> 903<span class="comment">/**/</span> 904 905<span class="preprocessor">#else</span> 906 907<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> 908 <span class="identifier">BOOST_TTI_DETAIL_HAS_MEMBER_WITH_TEMPLATE_SFINAE</span> <span class="special">\</span> 909 <span class="special">(</span> <span class="special">\</span> 910 <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> 911 <span class="special">)</span> <span class="special">\</span> 912<span class="comment">/**/</span> 913 914<span class="preprocessor">#endif</span> 915</pre> 916<p> 917 This of course gets more elaborate, but could be shortened considerably if 918 we chose to use BOOST_VMD_GET_TYPE and the invented BOOST_VMD_SWITCH of our 919 first example. We will assume in this second version of the code above that 920 our BOOST_VMD_SWITCH macro has been #included from somewhere. 921 </p> 922<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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">></span> 923<span class="preprocessor">#include</span> <span class="special"><</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">></span> 924<span class="preprocessor">#include</span> <span class="special"><</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">></span> 925<span class="preprocessor">#include</span> <span class="special"><</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">></span> 926<span class="preprocessor">#include</span> <span class="special"><</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">></span> 927<span class="preprocessor">#include</span> <span class="special"><</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">></span> 928<span class="preprocessor">#include</span> <span class="special"><</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">></span> 929<span class="preprocessor">#include</span> <span class="special"><</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">></span> 930<span class="preprocessor">#include</span> <span class="special"><</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">></span> 931<span class="preprocessor">#include</span> <span class="special"><</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">></span> 932 933<span class="preprocessor">#if</span> <span class="identifier">BOOST_PP_VARIADICS</span> 934 935<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> 936 <span class="identifier">BOOST_TTI_DETAIL_HAS_MEMBER_WITH_TEMPLATE_SFINAE</span> <span class="special">\</span> 937 <span class="special">(</span> <span class="special">\</span> 938 <span class="identifier">BOOST_TTI_DETAIL_TRAIT_CALL_HAS_TEMPLATE_CHECK_PARAMS_TYPE_CONCAT</span> <span class="special">\</span> 939 <span class="special">(</span> <span class="special">\</span> 940 <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> 941 <span class="identifier">BOOST_VMD_SWITCH</span> <span class="special">\</span> 942 <span class="special">(</span> <span class="special">\</span> 943 <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> 944 <span class="special">(</span><span class="number">1</span><span class="special">),</span> <span class="special">\</span> 945 <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> 946 <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> 947 <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> 948 <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> 949 <span class="special">)</span> <span class="special">\</span> 950 <span class="special">)</span> <span class="special">\</span> 951 <span class="special">)</span> <span class="special">\</span> 952<span class="comment">/**/</span> 953 954<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> 955 <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> 956<span class="comment">/**/</span> 957 958<span class="preprocessor">#else</span> 959 960<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> 961 <span class="identifier">BOOST_TTI_DETAIL_HAS_MEMBER_WITH_TEMPLATE_SFINAE</span> <span class="special">\</span> 962 <span class="special">(</span> <span class="special">\</span> 963 <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> 964 <span class="special">)</span> <span class="special">\</span> 965<span class="comment">/**/</span> 966 967<span class="preprocessor">#endif</span> 968</pre> 969<p> 970 This is shorter and easier to understand. The '(1)' passed as the calling values 971 to BOOST_VMD_SWITCH could just as well be '()' but VC8 has trouble with empty 972 parentheses so I avoid it here. 973 </p> 974<p> 975 In the case of the TTI, is such a change worth it to give more flexibility 976 to the end-user ? In reality, because the variadic version of passing the specific 977 template parameters as variadic data is syntactically easier to use than any 978 of the Boost PP composite forms, I am actually happy enough with that use not 979 to pursue the sort of functionality I presented in this example. But the example 980 nonetheless shows the power of the VMD functionality for creating macros which 981 add flexibility when the macro programmer feels he needs it for his library. 982 </p> 983</div> 984<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> 985<td align="left"></td> 986<td align="right"><div class="copyright-footer">Copyright © 2010-2017 Tropic Software 987 East Inc</div></td> 988</tr></table> 989<hr> 990<div class="spirit-nav"> 991<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> 992</div> 993</body> 994</html> 995