123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219 |
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
- <title>Why and how to use</title>
- <link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
- <meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
- <link rel="home" href="../index.html" title="Chapter 1. The Variadic Macro Data Library 1.9">
- <link rel="up" href="../index.html" title="Chapter 1. The Variadic Macro Data Library 1.9">
- <link rel="prev" href="vmd_naming.html" title="Naming conventions">
- <link rel="next" href="vmd_vmacros.html" title="Using variadic macros">
- </head>
- <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
- <table cellpadding="2" width="100%"><tr>
- <td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
- <td align="center"><a href="../../../../../index.html">Home</a></td>
- <td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
- <td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
- <td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
- <td align="center"><a href="../../../../../more/index.htm">More</a></td>
- </tr></table>
- <hr>
- <div class="spirit-nav">
- <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>
- </div>
- <div class="section">
- <div class="titlepage"><div><div><h2 class="title" style="clear: both">
- <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>
- </h2></div></div></div>
- <p>
- The VMD library provides the ability to create a macro which takes different
- types of parameters and can therefore generate different output depending on
- the parameter types as well as their values.
- </p>
- <p>
- This is equivalent to the way that overloaded functions provide the ability
- for a singularly named function to provide different functionality depending
- on the parameter types.
- </p>
- <p>
- In the case of macros, where more than one macro of the same name but different
- macro expansion is not allowed, a single macro name can create different expansions.
- </p>
- <p>
- As a simple example:
- </p>
- <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_seq</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
- <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>
- <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>
- <span class="identifier">BOOST_PP_IIF</span> <span class="special">\</span>
- <span class="special">(</span> <span class="special">\</span>
- <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>
- <span class="identifier">Seq</span><span class="special">,</span> <span class="special">\</span>
- <span class="identifier">BOOST_PP_IIF</span> <span class="special">\</span>
- <span class="special">(</span> <span class="special">\</span>
- <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>
- <span class="identifier">Tuple</span><span class="special">,</span> <span class="special">\</span>
- <span class="identifier">Unknown</span> <span class="special">\</span>
- <span class="special">)</span> <span class="special">\</span>
- <span class="special">)</span>
- </pre>
- <p>
- If the param passed is a seq the output of the macro is 'Seq'. If the param
- passed is a tuple the output of the macro is 'Tuple'. Otherwise the output
- of the macro is 'Unknown'.
- </p>
- <p>
- Obviously much more complicated cases can be created in which the types and
- values of various parameters are parsed in order to produce variable macro
- output depending on the input. Using variadic macros, macros with variable
- numbers and types of arguments give the macro programmer even greater freedom
- to design macros with flexibility.
- </p>
- <p>
- Another feature of the VMD library is the ability to parse identifiers. A system
- of registering identifiers which VMD can recognize has been created. Once an
- identifier is registered VMD can recognize it as part of macro input as an
- identifier and return the identifier. Furthermore VMD can compare identifiers
- for equality or inequality once an identifier has been pre-detected using VMD's
- system for pre-detecting identifiers.
- </p>
- <p>
- As another simple example:
- </p>
- <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_identifier</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
- <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>
- <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>
- <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>
- <span class="identifier">BOOST_PP_IIF</span> <span class="special">\</span>
- <span class="special">(</span> <span class="special">\</span>
- <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>
- <span class="identifier">AMACRO1_IDENTIFIER</span><span class="special">,</span> <span class="special">\</span>
- <span class="identifier">AMACRO1_NO_IDENTIFIER</span> <span class="special">\</span>
- <span class="special">)</span> <span class="special">\</span>
- <span class="special">(</span><span class="identifier">param</span><span class="special">)</span>
- <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>
- <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>
- <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>
- <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>
- </pre>
- <p>
- Here we use VMD's identifier registration system to determine and handle a
- particular identifier we may be expecting as a macro parameter. If the input
- to 'AMACRO1' is 'NAME' the output is 'Identifier is a NAME'. If the input to
- 'AMACRO1' is 'ADDRESS' the output is 'Identifier is an ADDRESS'. Otherwise
- the output is 'Parameter is not an identifier'.
- </p>
- <p>
- Identifier pre-detection makes things clearer, allowing us to detect within
- VMD whether macro input matches a particular identifier. Using the same setup
- as our previous example, but with identifier pre-detection:
- </p>
- <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_identifier</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
- <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>
- <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_DETECT_NAME_NAME</span>
- <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>
- <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_DETECT_ADDRESS_ADDRESS</span>
- <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>
- <span class="identifier">BOOST_PP_IIF</span> <span class="special">\</span>
- <span class="special">(</span> <span class="special">\</span>
- <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>
- <span class="identifier">AMACRO2_NAME</span><span class="special">,</span> <span class="special">\</span>
- <span class="identifier">BOOST_PP_IIF</span> <span class="special">\</span>
- <span class="special">(</span> <span class="special">\</span>
- <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>
- <span class="identifier">AMACRO2_ADDRESS</span><span class="special">,</span> <span class="special">\</span>
- <span class="identifier">AMACRO2_NO_IDENTIFIER</span> <span class="special">\</span>
- <span class="special">)</span> <span class="special">\</span>
- <span class="special">)</span> <span class="special">\</span>
- <span class="special">(</span><span class="identifier">param</span><span class="special">)</span>
- <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>
- <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>
- <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>
- </pre>
- <p>
- If the input to 'AMACRO2' is 'NAME' the output is 'Identifier is a NAME'. If
- the input to 'AMACRO2' is 'ADDRESS' the output is 'Identifier is an ADDRESS'.
- Otherwise the output is 'Parameter is not a NAME or ADDRESS identifier'.
- </p>
- <p>
- The VMD library also has 2 different subtypes of identifiers which can always
- be recognized. The first are numbers, equivalent to the number in Boost PP,
- numeric values with a range of 0-256. The second are v-types, which are identifiers
- starting with BOOST_VMD_TYPE_ followed by a name for the type of data. As an
- example, the v-type of a Boost PP tuple is BOOST_VMD_TYPE_TUPLE and the v-type
- of a v-type itself is BOOST_VMD_TYPE_TYPE. All data types have their own v-type
- identifier; types are recognized by the VMD macros and may be passed as input
- data just like any other of the types of data VMD recognizes.
- </p>
- <p>
- The VMD identifier system even has a way, to be explained later, for the end-user
- to create his own subtype identifiers.
- </p>
- <p>
- Another reason to use VMD is that VMD understands 'sequences' of the VMD data
- types. You can have a sequence of data types and VMD can convert the sequence
- to any of the Boost PP data types, or access any individual data type in a
- sequence.
- </p>
- <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>
- <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="preprocessor">#define</span> <span class="identifier">BOOST_VMD_REGISTER_NAME</span> <span class="special">(</span><span class="identifier">NAME</span><span class="special">)</span>
- <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>
- <span class="identifier">BOOST_VMD_TO_TUPLE</span><span class="special">(</span><span class="identifier">ASEQUENCE</span><span class="special">)</span>
- <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>
- </pre>
- <p>
- Our first expansion returns the tuple:
- </p>
- <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>
- </pre>
- <p>
- Our second expansion returns the sequence element:
- </p>
- <pre class="programlisting"><span class="number">147</span>
- </pre>
- <p>
- Sequences give the macro programmer the ability to accept input data from the
- user which may more closely mimic C++ constructs.
- </p>
- <p>
- Another reason to use VMD is that VMD understands data types. Besides specifically
- asking if a particular input is a particular data type, you can use the macro
- BOOST_VMD_GET_TYPE to retrieve the type of any VMD data.
- </p>
- <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>
- <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>
- <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>
- </pre>
- <p>
- etc.
- </p>
- <p>
- There is still much more of VMD functionality but hopefully this brief introduction
- of what VMD can do will interest you so that you will read on to understand
- VMD's functionality for the macro programmer.
- </p>
- </div>
- <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
- <td align="left"></td>
- <td align="right"><div class="copyright-footer">Copyright © 2010-2017 Tropic Software
- East Inc</div></td>
- </tr></table>
- <hr>
- <div class="spirit-nav">
- <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>
- </div>
- </body>
- </html>
|