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