1<html> 2<head> 3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 4<title>Generic macros for working with data types</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_specific/vmd_identifying.html" title="Identifying data types"> 10<link rel="next" href="vmd_generic/vmd_convert_sequence.html" title="Getting the type of data"> 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_specific/vmd_identifying.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="vmd_generic/vmd_convert_sequence.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_generic"></a><a class="link" href="vmd_generic.html" title="Generic macros for working with data types">Generic macros for working 28 with data types</a> 29</h2></div></div></div> 30<div class="toc"><dl class="toc"> 31<dt><span class="section"><a href="vmd_generic.html#variadic_macro_data.vmd_generic.vmd_sequence">Parsing 32 sequences</a></span></dt> 33<dd><dl> 34<dt><span class="section"><a href="vmd_generic.html#variadic_macro_data.vmd_generic.vmd_sequence.vmd_sequence_convert">Converting 35 sequences</a></span></dt> 36<dt><span class="section"><a href="vmd_generic.html#variadic_macro_data.vmd_generic.vmd_sequence.vmd_sequence_access">Accessing 37 a sequence element</a></span></dt> 38</dl></dd> 39<dt><span class="section"><a href="vmd_generic/vmd_convert_sequence.html">Getting 40 the type of data</a></span></dt> 41<dt><span class="section"><a href="vmd_generic/vmd_assert.html">Testing for 42 equality and inequality</a></span></dt> 43</dl></div> 44<p> 45 Besides the specific macros for working with data types VMD has a number of 46 generic macros for parsing sequences. 47 </p> 48<div class="section"> 49<div class="titlepage"><div><div><h3 class="title"> 50<a name="variadic_macro_data.vmd_generic.vmd_sequence"></a><a class="link" href="vmd_generic.html#variadic_macro_data.vmd_generic.vmd_sequence" title="Parsing sequences">Parsing 51 sequences</a> 52</h3></div></div></div> 53<div class="toc"><dl class="toc"> 54<dt><span class="section"><a href="vmd_generic.html#variadic_macro_data.vmd_generic.vmd_sequence.vmd_sequence_convert">Converting 55 sequences</a></span></dt> 56<dt><span class="section"><a href="vmd_generic.html#variadic_macro_data.vmd_generic.vmd_sequence.vmd_sequence_access">Accessing 57 a sequence element</a></span></dt> 58</dl></div> 59<p> 60 In the normal use of Boost PP data is passed as arguments to a macro in discrete 61 units so that each parameter expects a single data type. A typical macro 62 might be: 63 </p> 64<pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">AMACRO</span><span class="special">(</span><span class="identifier">anumber</span><span class="special">,</span><span class="identifier">atuple</span><span class="special">,</span><span class="identifier">anidentifier</span><span class="special">)</span> <span class="identifier">someoutput</span> 65</pre> 66<p> 67 where the 'atuple', having the form of ( data1, data2, data3 ), itself may 68 contain different data types of elements. 69 </p> 70<p> 71 This is the standard macro design and internally it is the easiest way to 72 pass macro data back and forth. The Boost PP library has a rich set of functionality 73 to deal with all of its high-level data types, and variadic data, with its 74 own simpler functionality, also offers another alternative to representing 75 data. 76 </p> 77<p> 78 Occasionally designers of macros, especially for the use of others programmers 79 within a particular library, have expressed the need for a macro parameter 80 to allow a more C/C++ like syntax where a single parameter might mimic a 81 C++ function-call or a C-like type modification syntax, or some other more 82 complicated construct. Something along the lines of: 83 </p> 84<pre class="programlisting"><span class="identifier">areturn</span> <span class="identifier">afunction</span> <span class="special">(</span> <span class="identifier">aparameter1</span><span class="special">,</span> <span class="identifier">aparameter2</span><span class="special">,</span> <span class="identifier">aparameter3</span> <span class="special">)</span> 85</pre> 86<p> 87 or 88 </p> 89<pre class="programlisting"><span class="special">(</span> <span class="identifier">type</span> <span class="special">)</span> <span class="identifier">data</span> 90</pre> 91<p> 92 etc. etc. 93 </p> 94<p> 95 In other words, from a syntactical level when designing possible macro input, 96 is it possible to design parameter data to look more like C/C++ when macros 97 are used in a library and still do a certain amount of preprocessor metaprogramming 98 with such mixed token input ? 99 </p> 100<p> 101 VMD has functionality which allows more than one type of preprocessing token, 102 excluding an 'empty' token which always refers to some entire input, to be 103 part of a single parameter of input data. These preprocessing tokens as a 104 single parameter are syntactically a consecutive series of data. The single 105 limitation of this consecutive series of data is that each top-level part 106 of the data of this series is of some VMD data type. What this means is that 107 if some input consists of a series of data types it is possible to extract 108 the data for each data type in that series. 109 </p> 110<p> 111 In practicality what this means is that, given the examples just above, if 112 'areturn', 'afunction', and 'data' are identifiers it would be possible to 113 parse either of the two inputs above so that one could identify the different 114 data types involved and do preprocessor metaprogramming based on those results. 115 </p> 116<h5> 117<a name="variadic_macro_data.vmd_generic.vmd_sequence.h0"></a> 118 <span class="phrase"><a name="variadic_macro_data.vmd_generic.vmd_sequence.sequence_definition"></a></span><a class="link" href="vmd_generic.html#variadic_macro_data.vmd_generic.vmd_sequence.sequence_definition">Sequence 119 definition</a> 120 </h5> 121<p> 122 I will be calling such input data, which consists of all top-level data types 123 in a series, by the term of a 'sequence'. Each separate data type in the 124 sequence is called an 'element'. In this definition of a 'sequence' we can 125 have 0 or more elements, so that a sequence is a general name for any VMD 126 input. A sequence is therefore any input VMD can parse, whether it is emptiness, 127 a single element, or more than one element in a series. Therefore when we 128 speak of VMD macros parsing input data we are really speaking of VMD macros 129 parsing a sequence. A sequence can therefore also be part of a Boost PP composite 130 data type, or variadic data, and VMD can still parse such an embedded sequence 131 if asked to do so. 132 </p> 133<h5> 134<a name="variadic_macro_data.vmd_generic.vmd_sequence.h1"></a> 135 <span class="phrase"><a name="variadic_macro_data.vmd_generic.vmd_sequence.sequence_parsing"></a></span><a class="link" href="vmd_generic.html#variadic_macro_data.vmd_generic.vmd_sequence.sequence_parsing">Sequence 136 parsing</a> 137 </h5> 138<p> 139 Parsing a sequence means that VMD can step through each element of a sequence 140 sequentially, determine the type and data of each element, then move on to 141 the next element. Parsing is sequential and can only be done in a forward 142 direction, but it can be done any number of times. In C++ iterator terms 143 parsing of a sequence is a forward iterator. 144 </p> 145<p> 146 Working with a sequence is equivalent to using VMD macros 'generically'. 147 </p> 148<p> 149 Before I give an explanation of how to use a sequence using VMD generic functionality 150 I would like to make two points: 151 </p> 152<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> 153<li class="listitem"> 154 The possibility of working with a sequence which contains more than one 155 data type can be easily abused. In general keeping things simple is usually 156 better than making things overly complicated when it comes to the syntactical 157 side of things in a computer language. A macro parameter syntactical 158 possibility has to be understandable to be used. 159 </li> 160<li class="listitem"> 161 Using VMD to parse the individual data types of a sequence takes more 162 preprocessing time than functionality offered with Boost PP data types, 163 because it is based on forward access through each top-level type of 164 the sequence. 165 </li> 166</ul></div> 167<p> 168 The one constraint in a sequence is that the top-level must consist of VMD 169 data types, in other words preprocessor tokens which VMD understands. By 170 top-level it is meant that a Boost PP composite data may have elements which 171 VMD cannot parse but as long as the input consists of the composite data 172 types and not the inner unparsable elements, VMD can parse the input. Therefore 173 if preprocessor data is one of the examples above, you will be successful 174 in using VMD. However if your preprocessor data takes the form of: 175 </p> 176<pre class="programlisting"><span class="special">&</span><span class="identifier">name</span> <span class="identifier">identifier</span> <span class="special">(</span> <span class="identifier">param</span> <span class="special">)</span> 177</pre> 178<p> 179 or 180 </p> 181<pre class="programlisting"><span class="identifier">identifier</span> <span class="string">"string literal"</span> 182</pre> 183<p> 184 or 185 </p> 186<pre class="programlisting"><span class="identifier">identifier</span> <span class="special">+</span> <span class="identifier">number</span> 187</pre> 188<p> 189 or 190 </p> 191<pre class="programlisting"><span class="identifier">identifier</span> <span class="special">+=</span> <span class="number">4.3</span> 192</pre> 193<p> 194 etc. etc. 195 </p> 196<p> 197 you will not be able to parse the data using VMD since '&', "string 198 literal", '+', '+=', and "4.3" are preprocessor tokens which 199 are not VMD top-level data types and therefore VMD cannot handle them at 200 the parsing level. You can still of course pass such data as preprocessing 201 input to macros but you cannot use VMD to recognize the parts of such data. 202 </p> 203<p> 204 This is similar to the fact that VMD cannot tell you what type preprocessor 205 data is as a whole, using any of the VMD identifying macros already discussed, 206 if the type is not one that VMD can handle. 207 </p> 208<p> 209 On the other hand you can still use VMD to parse such tokens in the input 210 if you use Boost PP data types as top-level data types to do so. Such as: 211 </p> 212<pre class="programlisting"><span class="special">(</span> <span class="special">&</span><span class="identifier">name</span> <span class="special">)</span> <span class="identifier">identifier</span> <span class="special">(</span> <span class="identifier">param</span> <span class="special">)</span> 213</pre> 214<p> 215 or 216 </p> 217<pre class="programlisting"><span class="identifier">identifier</span> <span class="special">(</span> <span class="string">"string literal"</span> <span class="special">)</span> 218</pre> 219<p> 220 or 221 </p> 222<pre class="programlisting"><span class="identifier">identifier</span> <span class="special">(</span> <span class="special">+</span> <span class="special">)</span> <span class="identifier">number</span> 223</pre> 224<p> 225 or 226 </p> 227<pre class="programlisting"><span class="identifier">identifier</span> <span class="special">(</span> <span class="special">+=</span> <span class="special">)</span> <span class="number">4</span> <span class="special">(</span> <span class="special">.</span> <span class="special">)</span> <span class="number">3</span> 228</pre> 229<p> 230 The succeeding topics explain the VMD functionality for parsing a sequence 231 for each individual VMD data type in that sequence. 232 </p> 233<h5> 234<a name="variadic_macro_data.vmd_generic.vmd_sequence.h2"></a> 235 <span class="phrase"><a name="variadic_macro_data.vmd_generic.vmd_sequence.sequence_types"></a></span><a class="link" href="vmd_generic.html#variadic_macro_data.vmd_generic.vmd_sequence.sequence_types">Sequence 236 types</a> 237 </h5> 238<p> 239 A VMD sequence can be seen as one of either three general types: 240 </p> 241<div class="orderedlist"><ol class="orderedlist" type="1"> 242<li class="listitem"> 243 An empty sequence 244 </li> 245<li class="listitem"> 246 A single element sequence 247 </li> 248<li class="listitem"> 249 A multi-element sequence 250 </li> 251</ol></div> 252<p> 253 An empty sequence is merely input that is empty, what VMD calls "emptiness". 254 Use the previously explained BOOST_VMD_IS_EMPTY macro to test for an empty 255 sequence. 256 </p> 257<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">is_empty</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 258 259<span class="preprocessor">#define</span> <span class="identifier">AN_EMPTY_SEQUENCE</span> 260 261<span class="identifier">BOOST_VMD_IS_EMPTY</span><span class="special">(</span><span class="identifier">AN_EMPTY_SEQUENCE</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="number">1</span> 262</pre> 263<p> 264 The type of an empty sequence is BOOST_VMD_TYPE_EMPTY. 265 </p> 266<p> 267 A single element sequence is a single VMD data type. This is what we have 268 been previously discussing as data which VMD can parse in this documentation 269 with our identifying macros. You can use the BOOST_VMD_IS_UNARY macro to 270 test for a single element sequence. 271 </p> 272<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">is_unary</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 273 274<span class="preprocessor">#define</span> <span class="identifier">A_SINGLE_ELEMENT_SEQUENCE</span> <span class="special">(</span><span class="number">1</span><span class="special">,</span><span class="number">2</span><span class="special">)</span> 275 276<span class="identifier">BOOST_VMD_IS_UNARY</span><span class="special">(</span><span class="identifier">A_SINGLE_ELEMENT_SEQUENCE</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="number">1</span> 277</pre> 278<p> 279 The type of a single element sequence is the type of the individual data 280 type. In our example above the type of A_SINGLE_ELEMENT_SEQUENCE is BOOST_VMD_TYPE_TUPLE. 281 </p> 282<p> 283 A multi-element sequence consists of more than one data type. This is the 284 "new" type which VMD can parse. You can use the BOOST_VMD_IS_MULTI 285 macro to test for a multi-element sequence. 286 </p> 287<pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">A_MULTI_ELEMENT_SEQUENCE</span> <span class="special">(</span><span class="number">1</span><span class="special">,</span><span class="number">2</span><span class="special">)</span> <span class="special">(</span><span class="number">1</span><span class="special">)(</span><span class="number">2</span><span class="special">)</span> <span class="number">45</span> 288</pre> 289<p> 290 The A_MULTI_ELEMENT_SEQUENCE consists of a tuple followed by a seq followed 291 by a number. 292 </p> 293<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">is_multi</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 294 295<span class="identifier">BOOST_VMD_IS_MULTI</span><span class="special">(</span><span class="identifier">A_MULTI_ELEMENT_SEQUENCE</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="number">1</span> 296</pre> 297<p> 298 The type of a multi-element sequence is always BOOST_VMD_TYPE_SEQUENCE. 299 </p> 300<p> 301 The type of a sequence can be obtained generically with the BOOST_VMD_GET_TYPE 302 macro. We will be explaining this further in the documentation. 303 </p> 304<h5> 305<a name="variadic_macro_data.vmd_generic.vmd_sequence.h3"></a> 306 <span class="phrase"><a name="variadic_macro_data.vmd_generic.vmd_sequence.sequence_size"></a></span><a class="link" href="vmd_generic.html#variadic_macro_data.vmd_generic.vmd_sequence.sequence_size">Sequence 307 size</a> 308 </h5> 309<p> 310 The size of any sequence can be accessed using the BOOST_VMD_SIZE macro. 311 For an empty sequence the size is always 0. For a single element sequence 312 the size is always 1. For a multi-element sequence the size is the number 313 of individual top-level data types in the sequence. 314 </p> 315<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">size</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 316 317<span class="identifier">BOOST_VMD_SIZE</span><span class="special">(</span><span class="identifier">AN_EMPTY_SEQUENCE</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="number">0</span> 318<span class="identifier">BOOST_VMD_SIZE</span><span class="special">(</span><span class="identifier">A_SINGLE_ELEMENT_SEQUENCE</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="number">1</span> 319<span class="identifier">BOOST_VMD_SIZE</span><span class="special">(</span><span class="identifier">A_MULTI_ELEMENT_SEQUENCE</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="number">3</span> 320</pre> 321<h5> 322<a name="variadic_macro_data.vmd_generic.vmd_sequence.h4"></a> 323 <span class="phrase"><a name="variadic_macro_data.vmd_generic.vmd_sequence.distinguishing_consecutive_seqs_"></a></span><a class="link" href="vmd_generic.html#variadic_macro_data.vmd_generic.vmd_sequence.distinguishing_consecutive_seqs_">Distinguishing 324 consecutive seqs and tuples in a sequence</a> 325 </h5> 326<p> 327 As has previously been mentioned a single element tuple is also a one element 328 seq, so parsing a sequence which has seqs and tuples in them might be a problem 329 as far as identify each element of the sequence. In a multi-element sequence 330 if the data consists of a mixture of seqs and tuples consecutively we need 331 to distinguish how VMD parses the data. The rule is that VMD always parses 332 a single element tuple as a tuple unless it is followed by one or more single 333 element tuples, in which case it is a seq. Here are some examples showing 334 how the rule is applied. 335 </p> 336<pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">ST_DATA</span> <span class="special">(</span><span class="identifier">somedata</span><span class="special">)(</span><span class="identifier">element1</span><span class="special">,</span><span class="identifier">element2</span><span class="special">)</span> 337</pre> 338<p> 339 VMD parses the above data as 2 consecutive tuples. The first tuple is the 340 single element tuple '(somedata)' and the second tuple is the multi element 341 tuple '(element1,element2)'. 342 </p> 343<pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">ST_DATA</span> <span class="special">(</span><span class="identifier">element1</span><span class="special">,</span><span class="identifier">element2</span><span class="special">)(</span><span class="identifier">somedata</span><span class="special">)</span> 344</pre> 345<p> 346 VMD parses the above data as 2 consecutive tuples. The first tuple is the 347 multi element tuple '(element1,element2)' and the second tuple is the single 348 element tuple '(somedata)'. 349 </p> 350<pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">ST_DATA</span> <span class="special">(</span><span class="identifier">somedata</span><span class="special">)(</span><span class="identifier">some_other_data</span><span class="special">)(</span><span class="identifier">element1</span><span class="special">,</span><span class="identifier">element2</span><span class="special">)</span> 351</pre> 352<p> 353 VMD parses the above data as a seq followed by a tuple. The seq is '(somedata)(some_other_data)' 354 and the tuple is '(element1,element2)'. 355 </p> 356<h5> 357<a name="variadic_macro_data.vmd_generic.vmd_sequence.h5"></a> 358 <span class="phrase"><a name="variadic_macro_data.vmd_generic.vmd_sequence.using_vmd_to_parse_sequence_inpu"></a></span><a class="link" href="vmd_generic.html#variadic_macro_data.vmd_generic.vmd_sequence.using_vmd_to_parse_sequence_inpu">Using 359 VMD to parse sequence input</a> 360 </h5> 361<p> 362 For a VMD sequence two ways of parsing into individual data types are offered 363 by the VMD library: 364 </p> 365<div class="orderedlist"><ol class="orderedlist" type="1"> 366<li class="listitem"> 367 The sequence can be converted to any of the Boost PP data types, or to 368 variadic data, where each individual data type in the sequence becomes 369 a separate element of the particular composite data type chosen. The 370 conversion to a particular Boost PP data type or variadic data is slow, 371 because it is based on forward access through each top-level type of 372 the sequence, but afterwards accessing any individual element is as fast 373 as accessing any element in the Boost PP data type or among variadic 374 data. 375 </li> 376<li class="listitem"> 377 The sequence can be accessed directly through its individual elements. 378 This is slower than accessing an element of a Boost PP data type or variadic 379 data but offers conceptual access to the original sequence as a series 380 of elements. 381 </li> 382</ol></div> 383<p> 384 These two techniques will be discussed in succeeding topics. 385 </p> 386<div class="section"> 387<div class="titlepage"><div><div><h4 class="title"> 388<a name="variadic_macro_data.vmd_generic.vmd_sequence.vmd_sequence_convert"></a><a class="link" href="vmd_generic.html#variadic_macro_data.vmd_generic.vmd_sequence.vmd_sequence_convert" title="Converting sequences">Converting 389 sequences</a> 390</h4></div></div></div> 391<p> 392 The easiest way to work with a sequence is to convert it to a Boost PP 393 data type. Likewise you can also convert a sequence to variadic data even 394 though the Boost PP data types have much greater functionality than variadic 395 data in Boost PP. 396 </p> 397<p> 398 To convert a sequence to a Boost PP data type or variadic data the macros 399 to be used are: 400 </p> 401<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> 402<li class="listitem"> 403 BOOST_VMD_TO_ARRAY(sequence) to convert the sequence to an array 404 </li> 405<li class="listitem"> 406 BOOST_VMD_TO_LIST(sequence) to convert the sequence to a list 407 </li> 408<li class="listitem"> 409 BOOST_VMD_TO_SEQ(sequence) to convert the sequence to a seq 410 </li> 411<li class="listitem"> 412 BOOST_VMD_TO_TUPLE(sequence) to convert the sequence to a tuple 413 </li> 414<li class="listitem"> 415 BOOST_VMD_ENUM(sequence) to convert the sequence to variadic data 416 </li> 417</ul></div> 418<p> 419 After the conversion the elements of a sequence become the elements of 420 the corresponding composite data type. 421 </p> 422<p> 423 Once the elements of the sequence have been converted to the elements of 424 the composite data type the full power of that composite data type can 425 be used to process each element. Furthermore the programmer can use VMD 426 to discover the type of an individual element for further processing. 427 </p> 428<p> 429 For single element sequences the result is always a single element composite 430 data type. For multi-element sequences the result is always a composite 431 data type of more than one element. 432 </p> 433<p> 434 For a sequence that is empty the result is emptiness when converting to 435 a seq, tuple, or variadic data; the result is an empty array or list when 436 converting to each of those composite data types respectively. 437 </p> 438<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="keyword">enum</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 439<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">to_array</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 440<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">to_list</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 441<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">to_seq</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 442<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">to_tuple</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 443 444<span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_REGISTER_ANID</span> <span class="special">(</span><span class="identifier">ANID</span><span class="special">)</span> 445 446<span class="preprocessor">#define</span> <span class="identifier">SEQUENCE_EMPTY</span> 447<span class="preprocessor">#define</span> <span class="identifier">SEQUENCE_SINGLE</span> <span class="number">35</span> 448<span class="preprocessor">#define</span> <span class="identifier">SEQUENCE_SINGLE_2</span> <span class="identifier">ANID</span> 449<span class="preprocessor">#define</span> <span class="identifier">SEQUENCE_MULTI</span> <span class="special">(</span><span class="number">0</span><span class="special">,</span><span class="number">1</span><span class="special">)</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="number">4</span><span class="special">)</span> 450<span class="preprocessor">#define</span> <span class="identifier">SEQUENCE_MULTI_2</span> <span class="identifier">BOOST_VMD_TYPE_SEQ</span> <span class="special">(</span><span class="number">2</span><span class="special">,(</span><span class="number">5</span><span class="special">,</span><span class="number">6</span><span class="special">))</span> 451 452<span class="identifier">BOOST_VMD_TO_ARRAY</span><span class="special">(</span><span class="identifier">SEQUENCE_EMPTY</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="identifier">an</span> <span class="identifier">empty</span> <span class="identifier">array</span> <span class="char">'(0,())'</span> 453<span class="identifier">BOOST_VMD_TO_LIST</span><span class="special">(</span><span class="identifier">SEQUENCE_SINGLE</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="identifier">a</span> <span class="identifier">one</span><span class="special">-</span><span class="identifier">element</span> <span class="identifier">list</span> <span class="char">'(35,BOOST_PP_NIL)'</span> 454<span class="identifier">BOOST_VMD_TO_SEQ</span><span class="special">(</span><span class="identifier">SEQUENCE_SINGLE_2</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="identifier">a</span> <span class="identifier">one</span><span class="special">-</span><span class="identifier">element</span> <span class="identifier">seq</span> <span class="char">'(ANID)'</span> 455<span class="identifier">BOOST_VMD_TO_TUPLE</span><span class="special">(</span><span class="identifier">SEQUENCE_MULTI</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="identifier">a</span> <span class="identifier">multi</span><span class="special">-</span><span class="identifier">element</span> <span class="identifier">tuple</span> <span class="char">'((0,1),(2)(3)(4))'</span> 456<span class="identifier">BOOST_VMD_ENUM</span><span class="special">(</span><span class="identifier">SEQUENCE_MULTI_2</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="identifier">multi</span><span class="special">-</span><span class="identifier">element</span> <span class="identifier">variadic</span> <span class="identifier">data</span> <span class="char">'BOOST_VMD_TYPE_SEQ,(2,(5,6))'</span> 457</pre> 458<h6> 459<a name="variadic_macro_data.vmd_generic.vmd_sequence.vmd_sequence_convert.h0"></a> 460 <span class="phrase"><a name="variadic_macro_data.vmd_generic.vmd_sequence.vmd_sequence_convert.usage"></a></span><a class="link" href="vmd_generic.html#variadic_macro_data.vmd_generic.vmd_sequence.vmd_sequence_convert.usage">Usage</a> 461 </h6> 462<p> 463 You can use the general header file: 464 </p> 465<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 466</pre> 467<p> 468 or you can use individual header files for each of these macros. The individual 469 header files are: 470 </p> 471<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">to_array</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> <span class="comment">// for the BOOST_VMD_TO_ARRAY macro</span> 472<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">to_list</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> <span class="comment">// for the BOOST_VMD_TO_LIST macro</span> 473<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">to_seq</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> <span class="comment">// for the BOOST_VMD_TO_SEQ macro</span> 474<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">to_tuple</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> <span class="comment">// for the BOOST_VMD_TO_TUPLE macro.</span> 475<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="keyword">enum</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> <span class="comment">// for the BOOST_VMD_ENUM macro.</span> 476</pre> 477</div> 478<div class="section"> 479<div class="titlepage"><div><div><h4 class="title"> 480<a name="variadic_macro_data.vmd_generic.vmd_sequence.vmd_sequence_access"></a><a class="link" href="vmd_generic.html#variadic_macro_data.vmd_generic.vmd_sequence.vmd_sequence_access" title="Accessing a sequence element">Accessing 481 a sequence element</a> 482</h4></div></div></div> 483<p> 484 It is possible to access an individual element of a sequence. The macro 485 to do this is called BOOST_VMD_ELEM. The macro takes two required parameters. 486 The required parameters are the element number to access and the sequence, 487 in that order. The element number is a 0-based number and its maximum value 488 should be one less than the size of the sequence. 489 </p> 490<p> 491 The BOOST_VMD_ELEM macro returns the actual sequence element. If the first 492 required parameter is greater or equal to the size of the sequence the 493 macro returns emptiness. Because of this using BOOST_VMD_ELEM on an empty 494 sequence, whose size is 0, always returns emptiness. 495 </p> 496<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">elem</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 497 498<span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_REGISTER_ANAME</span> <span class="special">(</span><span class="identifier">ANAME</span><span class="special">)</span> 499<span class="preprocessor">#define</span> <span class="identifier">A_SEQUENCE</span> <span class="special">(</span><span class="number">1</span><span class="special">,</span><span class="number">2</span><span class="special">,</span><span class="number">3</span><span class="special">)</span> <span class="number">46</span> <span class="special">(</span><span class="identifier">list_data1</span><span class="special">,(</span><span class="identifier">list_data2</span><span class="special">,</span><span class="identifier">BOOST_PP_NIL</span><span class="special">))</span> <span class="identifier">BOOST_VMD_TYPE_SEQ</span> <span class="identifier">ANAME</span> 500<span class="preprocessor">#define</span> <span class="identifier">AN_EMPTY_SEQUENCE</span> 501 502<span class="identifier">BOOST_VMD_ELEM</span><span class="special">(</span><span class="number">0</span><span class="special">,</span><span class="identifier">A_SEQUENCE</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="special">(</span><span class="number">1</span><span class="special">,</span><span class="number">2</span><span class="special">,</span><span class="number">3</span><span class="special">)</span> 503<span class="identifier">BOOST_VMD_ELEM</span><span class="special">(</span><span class="number">1</span><span class="special">,</span><span class="identifier">A_SEQUENCE</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="number">46</span> 504<span class="identifier">BOOST_VMD_ELEM</span><span class="special">(</span><span class="number">2</span><span class="special">,</span><span class="identifier">A_SEQUENCE</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="special">(</span><span class="identifier">list_data1</span><span class="special">,(</span><span class="identifier">list_data2</span><span class="special">,</span><span class="identifier">BOOST_PP_NIL</span><span class="special">))</span> 505<span class="identifier">BOOST_VMD_ELEM</span><span class="special">(</span><span class="number">3</span><span class="special">,</span><span class="identifier">A_SEQUENCE</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="identifier">BOOST_VMD_TYPE_SEQ</span> 506<span class="identifier">BOOST_VMD_ELEM</span><span class="special">(</span><span class="number">4</span><span class="special">,</span><span class="identifier">A_SEQUENCE</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="identifier">ANAME</span> 507 508<span class="identifier">BOOST_VMD_ELEM</span><span class="special">(</span><span class="number">5</span><span class="special">,</span><span class="identifier">A_SEQUENCE</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="identifier">emptiness</span> 509<span class="identifier">BOOST_VMD_ELEM</span><span class="special">(</span><span class="number">0</span><span class="special">,</span><span class="identifier">AN_EMPTY_SEQUENCE</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="identifier">emptiness</span> 510</pre> 511<p> 512 Accessing an element of a sequence directly is slower than accessing an 513 element of a Boost PP data type or even variadic data, since each access 514 has to directly cycle through each element of the sequence to get to the 515 one being accessed. The process of sequentially parsing each element again 516 each time is slower than accessing a Boost PP data type element. 517 </p> 518<h6> 519<a name="variadic_macro_data.vmd_generic.vmd_sequence.vmd_sequence_access.h0"></a> 520 <span class="phrase"><a name="variadic_macro_data.vmd_generic.vmd_sequence.vmd_sequence_access.usage"></a></span><a class="link" href="vmd_generic.html#variadic_macro_data.vmd_generic.vmd_sequence.vmd_sequence_access.usage">Usage</a> 521 </h6> 522<p> 523 You can use the general header file: 524 </p> 525<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 526</pre> 527<p> 528 or you can use the individual header file: 529 </p> 530<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">elem</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 531</pre> 532</div> 533</div> 534</div> 535<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> 536<td align="left"></td> 537<td align="right"><div class="copyright-footer">Copyright © 2010-2017 Tropic Software 538 East Inc</div></td> 539</tr></table> 540<hr> 541<div class="spirit-nav"> 542<a accesskey="p" href="vmd_specific/vmd_identifying.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="vmd_generic/vmd_convert_sequence.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a> 543</div> 544</body> 545</html> 546