• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">detail</span><span class="special">/</span><span class="identifier">setup</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
98
99<span class="preprocessor">#if</span> <span class="identifier">BOOST_PP_VARIADICS</span>
100
101<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">cat</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
102<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">arithmetic</span><span class="special">/</span><span class="identifier">inc</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
103<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">comparison</span><span class="special">/</span><span class="identifier">equal</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
104<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">control</span><span class="special">/</span><span class="identifier">expr_iif</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
105<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">control</span><span class="special">/</span><span class="identifier">iif</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
106<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">control</span><span class="special">/</span><span class="keyword">while</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
107<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">tuple</span><span class="special">/</span><span class="identifier">elem</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
108<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">tuple</span><span class="special">/</span><span class="keyword">enum</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
109<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">facilities</span><span class="special">/</span><span class="identifier">expand</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
110<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">tuple</span><span class="special">/</span><span class="identifier">replace</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
111<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">tuple</span><span class="special">/</span><span class="identifier">size</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
112<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">variadic</span><span class="special">/</span><span class="identifier">to_tuple</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
113<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">variadic</span><span class="special">/</span><span class="identifier">size</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
114<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">equal</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
115<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">identity</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
116<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">is_empty</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
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">&lt;</span><span class="keyword">class</span> <span class="identifier">X</span><span class="special">,</span><span class="keyword">int</span> <span class="identifier">Y</span><span class="special">&gt;</span> <span class="keyword">class</span> <span class="identifier">MyTemplate</span> <span class="special">{</span> <span class="special">...</span> <span class="identifier">code</span> <span class="special">};</span>
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 &lt;boost/tti/detail/dtemplate_params.hpp&gt; 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">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">arithmetic</span><span class="special">/</span><span class="identifier">add</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
822<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">array</span><span class="special">/</span><span class="keyword">enum</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
823<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">array</span><span class="special">/</span><span class="identifier">size</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
824<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">control</span><span class="special">/</span><span class="identifier">expr_iif</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
825<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">control</span><span class="special">/</span><span class="identifier">iif</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
826<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">list</span><span class="special">/</span><span class="keyword">enum</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
827<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">list</span><span class="special">/</span><span class="identifier">size</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
828<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">seq</span><span class="special">/</span><span class="keyword">enum</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
829<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">seq</span><span class="special">/</span><span class="identifier">size</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
830<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">tuple</span><span class="special">/</span><span class="keyword">enum</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
831<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">tuple</span><span class="special">/</span><span class="identifier">size</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
832<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">identity</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
833<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">is_array</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
834<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">is_list</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
835<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">is_seq</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
836<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">is_tuple</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
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">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">arithmetic</span><span class="special">/</span><span class="identifier">add</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
923<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">array</span><span class="special">/</span><span class="keyword">enum</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
924<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">array</span><span class="special">/</span><span class="identifier">size</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
925<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">list</span><span class="special">/</span><span class="keyword">enum</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
926<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">list</span><span class="special">/</span><span class="identifier">size</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
927<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">seq</span><span class="special">/</span><span class="keyword">enum</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
928<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">seq</span><span class="special">/</span><span class="identifier">size</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
929<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">tuple</span><span class="special">/</span><span class="keyword">enum</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
930<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">tuple</span><span class="special">/</span><span class="identifier">size</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
931<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">get_type</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
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