996 lines
92 KiB
HTML
996 lines
92 KiB
HTML
<html>
|
||
<head>
|
||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||
<title>Examples using VMD functionality</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.10">
|
||
<link rel="up" href="../index.html" title="Chapter 1. The Variadic Macro Data Library 1.10">
|
||
<link rel="prev" href="vmd_conv.html" title="Version 1.7 to 1.8 conversion">
|
||
<link rel="next" href="../variadic_macro_data_reference.html" title="Variadic Macro Data Reference">
|
||
</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_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>
|
||
</div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||
<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>
|
||
</h2></div></div></div>
|
||
<p>
|
||
Examples of library use are always highly personal. Any given library employing
|
||
macro programming can decide what macro facilities are needed based on the
|
||
library itself and then decide if functionality in a macro library like VMD
|
||
makes macro programming in that library easier. To that end the examples presented
|
||
here are highly arbitrary and are just efforts to illustrate possible use of
|
||
functionality of VMD features without worrying too much if those examples have
|
||
any practical beneficial use in real programming situations. In these examples
|
||
I have endeavored, therefore, to present macro programming "snippets"
|
||
using VMD functionality rather than complete solutions to a given practical
|
||
problem.
|
||
</p>
|
||
<h4>
|
||
<a name="variadic_macro_data.vmd_examples.h0"></a>
|
||
<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
|
||
macro</a>
|
||
</h4>
|
||
<p>
|
||
In C++ there is a 'switch' statement which we can emulate in macro programming
|
||
using VMD. For the macro emulation we will have as parameters to our macro:
|
||
</p>
|
||
<div class="orderedlist"><ol class="orderedlist" type="1">
|
||
<li class="listitem">
|
||
A value, which can be any data type VMD can parse.
|
||
</li>
|
||
<li class="listitem">
|
||
A tuple of calling values. These will be used when calling the matching
|
||
macro.
|
||
</li>
|
||
<li class="listitem">
|
||
Variadic parameters, each of which are tuples. Each tuple consists of two
|
||
elements, the name of a value to match and the name of a macro to call.
|
||
For the 'default' case the tuple is a single element which is the name
|
||
of a macro to call. These are our equivalents to the C++ switch 'case'
|
||
statements.
|
||
</li>
|
||
</ol></div>
|
||
<p>
|
||
The macro looks like:
|
||
</p>
|
||
<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>
|
||
</pre>
|
||
<p>
|
||
We have to be careful not to parse the name of our macro to call in any way
|
||
since this is a failing condition for BOOST_VMD_IS_EMPTY and subsequently for
|
||
any parsing of input data we might want to do. Instead we will just extract
|
||
the calling macro name and just call it, passing the calling values.
|
||
</p>
|
||
<p>
|
||
Our processing is:
|
||
</p>
|
||
<div class="orderedlist"><ol class="orderedlist" type="1">
|
||
<li class="listitem">
|
||
Convert our variadic parameters to a tuple since access to tuple elements
|
||
is easier.
|
||
</li>
|
||
<li class="listitem">
|
||
Use a BOOST_PP_WHILE loop to find the matching value and extract the calling
|
||
macro from it. We will use BOOST_VMD_EQUAL to find the matching value.
|
||
</li>
|
||
<li class="listitem">
|
||
Call the calling macro with the calling values when we return from our
|
||
BOOST_PP_WHILE loop.
|
||
</li>
|
||
</ol></div>
|
||
<p>
|
||
Here is our code:
|
||
</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">detail</span><span class="special">/</span><span class="identifier">setup</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
|
||
<span class="preprocessor">#if</span> <span class="identifier">BOOST_PP_VARIADICS</span>
|
||
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">cat</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">arithmetic</span><span class="special">/</span><span class="identifier">inc</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">comparison</span><span class="special">/</span><span class="identifier">equal</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">control</span><span class="special">/</span><span class="identifier">expr_iif</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<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>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">control</span><span class="special">/</span><span class="keyword">while</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">tuple</span><span class="special">/</span><span class="identifier">elem</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">tuple</span><span class="special">/</span><span class="keyword">enum</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">facilities</span><span class="special">/</span><span class="identifier">expand</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">tuple</span><span class="special">/</span><span class="identifier">replace</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">tuple</span><span class="special">/</span><span class="identifier">size</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">variadic</span><span class="special">/</span><span class="identifier">to_tuple</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">variadic</span><span class="special">/</span><span class="identifier">size</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">equal</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">identity</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<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>
|
||
|
||
<span class="comment">/*
|
||
|
||
State index into state values
|
||
|
||
*/</span>
|
||
|
||
<span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_SWITCH_STATE_ELEM_INDEX</span> <span class="number">2</span>
|
||
<span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_SWITCH_STATE_ELEM_DEFAULT</span> <span class="number">4</span>
|
||
<span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_SWITCH_STATE_ELEM_RESULT</span> <span class="number">5</span>
|
||
|
||
<span class="comment">/*
|
||
|
||
Retrieve the state value, never changes
|
||
|
||
*/</span>
|
||
|
||
<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>
|
||
<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>
|
||
<span class="comment">/**/</span>
|
||
|
||
<span class="comment">/*
|
||
|
||
Retrieve the state tuple of values, never changes
|
||
|
||
*/</span>
|
||
|
||
<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>
|
||
<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>
|
||
<span class="comment">/**/</span>
|
||
|
||
<span class="comment">/*
|
||
|
||
Retrieve the state index
|
||
|
||
*/</span>
|
||
|
||
<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>
|
||
<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>
|
||
<span class="comment">/**/</span>
|
||
|
||
<span class="comment">/*
|
||
|
||
Retrieve the state tuple of values size, never changes
|
||
|
||
*/</span>
|
||
|
||
<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>
|
||
<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>
|
||
<span class="comment">/**/</span>
|
||
|
||
<span class="comment">/*
|
||
|
||
Retrieve the state default tuple
|
||
|
||
*/</span>
|
||
|
||
<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>
|
||
<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>
|
||
<span class="comment">/**/</span>
|
||
|
||
<span class="comment">/*
|
||
|
||
Retrieve the state result tuple
|
||
|
||
*/</span>
|
||
|
||
<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>
|
||
<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>
|
||
<span class="comment">/**/</span>
|
||
|
||
<span class="comment">/*
|
||
|
||
Retrieve the current value tuple
|
||
|
||
*/</span>
|
||
|
||
<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>
|
||
<span class="identifier">BOOST_PP_TUPLE_ELEM</span> <span class="special">\</span>
|
||
<span class="special">(</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>
|
||
<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>
|
||
<span class="special">)</span> <span class="special">\</span>
|
||
<span class="comment">/**/</span>
|
||
|
||
<span class="comment">/*
|
||
|
||
Expands to the state
|
||
|
||
value = value to compare against
|
||
tuple = choices as a tuple of values
|
||
size = size of tuple of values
|
||
|
||
None of these ever change in the WHILE state
|
||
|
||
*/</span>
|
||
|
||
<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>
|
||
<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>
|
||
<span class="comment">/**/</span>
|
||
|
||
<span class="comment">/*
|
||
|
||
Expands to the WHILE state
|
||
|
||
The state to our WHILE consists of a tuple of elements:
|
||
|
||
1: value to compare against
|
||
2: tuple of values. Each value is a value/macro pair or if the default just a macro
|
||
3: index into the values
|
||
4: tuple for default macro. 0 means no default macro, 1 means default macro and then second value is the default macro.
|
||
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.
|
||
|
||
*/</span>
|
||
|
||
<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>
|
||
<span class="identifier">BOOST_VMD_SWITCH_STATE_EXPAND</span> <span class="special">\</span>
|
||
<span class="special">(</span> <span class="special">\</span>
|
||
<span class="identifier">value</span><span class="special">,</span> <span class="special">\</span>
|
||
<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>
|
||
<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>
|
||
<span class="special">)</span> <span class="special">\</span>
|
||
<span class="comment">/**/</span>
|
||
|
||
<span class="comment">/*
|
||
|
||
Sets the state upon a successful match.
|
||
|
||
macro = is the matching macro found
|
||
|
||
*/</span>
|
||
|
||
<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>
|
||
<span class="identifier">BOOST_PP_TUPLE_REPLACE_D</span> <span class="special">\</span>
|
||
<span class="special">(</span> <span class="special">\</span>
|
||
<span class="identifier">d</span><span class="special">,</span> <span class="special">\</span>
|
||
<span class="identifier">state</span><span class="special">,</span> <span class="special">\</span>
|
||
<span class="identifier">BOOST_VMD_SWITCH_STATE_ELEM_RESULT</span><span class="special">,</span> <span class="special">\</span>
|
||
<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>
|
||
<span class="special">)</span> <span class="special">\</span>
|
||
<span class="comment">/**/</span>
|
||
|
||
<span class="comment">/*
|
||
|
||
Sets the state upon final failure to find a match.
|
||
|
||
def = default tuple macro, ignored
|
||
|
||
*/</span>
|
||
|
||
<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>
|
||
<span class="identifier">BOOST_PP_TUPLE_REPLACE_D</span> <span class="special">\</span>
|
||
<span class="special">(</span> <span class="special">\</span>
|
||
<span class="identifier">d</span><span class="special">,</span> <span class="special">\</span>
|
||
<span class="identifier">state</span><span class="special">,</span> <span class="special">\</span>
|
||
<span class="identifier">BOOST_VMD_SWITCH_STATE_ELEM_RESULT</span><span class="special">,</span> <span class="special">\</span>
|
||
<span class="special">(</span><span class="number">0</span><span class="special">,)</span> <span class="special">\</span>
|
||
<span class="special">)</span> <span class="special">\</span>
|
||
<span class="comment">/**/</span>
|
||
|
||
<span class="comment">/*
|
||
|
||
Increments the state index into the tuple values
|
||
|
||
*/</span>
|
||
|
||
<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>
|
||
<span class="identifier">BOOST_PP_TUPLE_REPLACE_D</span> <span class="special">\</span>
|
||
<span class="special">(</span> <span class="special">\</span>
|
||
<span class="identifier">d</span><span class="special">,</span> <span class="special">\</span>
|
||
<span class="identifier">state</span><span class="special">,</span> <span class="special">\</span>
|
||
<span class="identifier">BOOST_VMD_SWITCH_STATE_ELEM_INDEX</span><span class="special">,</span> <span class="special">\</span>
|
||
<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>
|
||
<span class="special">)</span> <span class="special">\</span>
|
||
<span class="comment">/**/</span>
|
||
|
||
<span class="comment">/*
|
||
|
||
Choose our current value's macro as our successful match
|
||
|
||
tuple = current tuple to test
|
||
|
||
*/</span>
|
||
|
||
<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>
|
||
<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>
|
||
<span class="comment">/**/</span>
|
||
|
||
<span class="comment">/*
|
||
|
||
Update our state index
|
||
|
||
tuple = current tuple to test, ignored
|
||
|
||
*/</span>
|
||
|
||
<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>
|
||
<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>
|
||
<span class="comment">/**/</span>
|
||
|
||
<span class="comment">/*
|
||
|
||
Test our current value against our value to compare against
|
||
|
||
tuple = current tuple to test
|
||
|
||
*/</span>
|
||
|
||
<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>
|
||
<span class="identifier">BOOST_PP_IIF</span> <span class="special">\</span>
|
||
<span class="special">(</span> <span class="special">\</span>
|
||
<span class="identifier">BOOST_VMD_EQUAL_D</span> <span class="special">\</span>
|
||
<span class="special">(</span> <span class="special">\</span>
|
||
<span class="identifier">d</span><span class="special">,</span> <span class="special">\</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>
|
||
<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>
|
||
<span class="special">),</span> <span class="special">\</span>
|
||
<span class="identifier">BOOST_VMD_SWITCH_OP_TEST_CURRENT_VALUE_MATCH</span><span class="special">,</span> <span class="special">\</span>
|
||
<span class="identifier">BOOST_VMD_SWITCH_OP_TEST_CURRENT_VALUE_UPDATE_INDEX</span> <span class="special">\</span>
|
||
<span class="special">)</span> <span class="special">\</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>
|
||
<span class="comment">/**/</span>
|
||
|
||
<span class="comment">/*
|
||
|
||
Set our default macro and update the index in our WHILE state
|
||
|
||
tuple = current tuple to test
|
||
|
||
*/</span>
|
||
|
||
<span class="preprocessor">#if</span> <span class="identifier">BOOST_VMD_MSVC</span>
|
||
|
||
<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>
|
||
<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>
|
||
<span class="comment">/**/</span>
|
||
|
||
<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>
|
||
<span class="identifier">BOOST_VMD_SWITCH_OP_UPDATE_INDEX</span> <span class="special">\</span>
|
||
<span class="special">(</span> <span class="special">\</span>
|
||
<span class="identifier">d</span><span class="special">,</span> <span class="special">\</span>
|
||
<span class="identifier">BOOST_PP_TUPLE_REPLACE_D</span> <span class="special">\</span>
|
||
<span class="special">(</span> <span class="special">\</span>
|
||
<span class="identifier">d</span><span class="special">,</span> <span class="special">\</span>
|
||
<span class="identifier">state</span><span class="special">,</span> <span class="special">\</span>
|
||
<span class="identifier">BOOST_VMD_SWITCH_STATE_ELEM_DEFAULT</span><span class="special">,</span> <span class="special">\</span>
|
||
<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>
|
||
<span class="special">)</span> <span class="special">\</span>
|
||
<span class="special">)</span> <span class="special">\</span>
|
||
<span class="comment">/**/</span>
|
||
|
||
<span class="preprocessor">#else</span>
|
||
|
||
<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>
|
||
<span class="identifier">BOOST_VMD_SWITCH_OP_UPDATE_INDEX</span> <span class="special">\</span>
|
||
<span class="special">(</span> <span class="special">\</span>
|
||
<span class="identifier">d</span><span class="special">,</span> <span class="special">\</span>
|
||
<span class="identifier">BOOST_PP_TUPLE_REPLACE_D</span> <span class="special">\</span>
|
||
<span class="special">(</span> <span class="special">\</span>
|
||
<span class="identifier">d</span><span class="special">,</span> <span class="special">\</span>
|
||
<span class="identifier">state</span><span class="special">,</span> <span class="special">\</span>
|
||
<span class="identifier">BOOST_VMD_SWITCH_STATE_ELEM_DEFAULT</span><span class="special">,</span> <span class="special">\</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>
|
||
<span class="special">)</span> <span class="special">\</span>
|
||
<span class="special">)</span> <span class="special">\</span>
|
||
<span class="comment">/**/</span>
|
||
|
||
<span class="preprocessor">#endif</span>
|
||
|
||
<span class="comment">/*
|
||
|
||
If our current value is a default macro, just set the default macro,
|
||
else test our current value.
|
||
|
||
tuple = current tuple to test
|
||
|
||
*/</span>
|
||
|
||
<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>
|
||
<span class="identifier">BOOST_PP_IIF</span> <span class="special">\</span>
|
||
<span class="special">(</span> <span class="special">\</span>
|
||
<span class="identifier">BOOST_PP_EQUAL_D</span> <span class="special">\</span>
|
||
<span class="special">(</span> <span class="special">\</span>
|
||
<span class="identifier">d</span><span class="special">,</span> <span class="special">\</span>
|
||
<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>
|
||
<span class="number">1</span> <span class="special">\</span>
|
||
<span class="special">),</span> <span class="special">\</span>
|
||
<span class="identifier">BOOST_VMD_SWITCH_OP_TEST_CURRENT_CREATE_DEFAULT</span><span class="special">,</span> <span class="special">\</span>
|
||
<span class="identifier">BOOST_VMD_SWITCH_OP_TEST_CURRENT_VALUE</span> <span class="special">\</span>
|
||
<span class="special">)</span> <span class="special">\</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>
|
||
<span class="comment">/**/</span>
|
||
|
||
<span class="comment">/*
|
||
|
||
Test the current value in our tuple of values
|
||
|
||
*/</span>
|
||
|
||
<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>
|
||
<span class="identifier">BOOST_VMD_SWITCH_OP_TEST_CURRENT_TUPLE</span> <span class="special">\</span>
|
||
<span class="special">(</span> <span class="special">\</span>
|
||
<span class="identifier">d</span><span class="special">,</span> <span class="special">\</span>
|
||
<span class="identifier">state</span><span class="special">,</span> <span class="special">\</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>
|
||
<span class="special">)</span> <span class="special">\</span>
|
||
<span class="comment">/**/</span>
|
||
|
||
<span class="comment">/*
|
||
|
||
Choose the default macro as our successful match
|
||
|
||
def = default tuple consisting of just the default macro name
|
||
|
||
*/</span>
|
||
|
||
<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>
|
||
<span class="identifier">BOOST_VMD_SWITCH_OP_SUCCESS</span> <span class="special">\</span>
|
||
<span class="special">(</span> <span class="special">\</span>
|
||
<span class="identifier">d</span><span class="special">,</span> <span class="special">\</span>
|
||
<span class="identifier">state</span><span class="special">,</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">def</span><span class="special">)</span> <span class="special">\</span>
|
||
<span class="special">)</span> <span class="special">\</span>
|
||
<span class="comment">/**/</span>
|
||
|
||
<span class="comment">/*
|
||
|
||
If the default macro exists, choose it else indicate no macro was found
|
||
|
||
def = default tuple consisting of just the default macro name
|
||
|
||
*/</span>
|
||
|
||
<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>
|
||
<span class="identifier">BOOST_PP_IIF</span> <span class="special">\</span>
|
||
<span class="special">(</span> <span class="special">\</span>
|
||
<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>
|
||
<span class="identifier">BOOST_VMD_SWITCH_OP_DEFAULT_RET_CHOSEN</span><span class="special">,</span> <span class="special">\</span>
|
||
<span class="identifier">BOOST_VMD_SWITCH_OP_FAILURE</span> <span class="special">\</span>
|
||
<span class="special">)</span> <span class="special">\</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>
|
||
<span class="comment">/**/</span>
|
||
|
||
<span class="comment">/*
|
||
|
||
Try to choose the default macro if it exists
|
||
|
||
*/</span>
|
||
|
||
<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>
|
||
<span class="identifier">BOOST_VMD_SWITCH_OP_DEFAULT_RET</span> <span class="special">\</span>
|
||
<span class="special">(</span> <span class="special">\</span>
|
||
<span class="identifier">d</span><span class="special">,</span> <span class="special">\</span>
|
||
<span class="identifier">state</span><span class="special">,</span> <span class="special">\</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>
|
||
<span class="special">)</span> <span class="special">\</span>
|
||
<span class="comment">/**/</span>
|
||
|
||
<span class="comment">/*
|
||
|
||
WHILE loop operation
|
||
|
||
Check for the next value match or try to choose the default if all matches have been checked
|
||
|
||
*/</span>
|
||
|
||
<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>
|
||
<span class="identifier">BOOST_PP_IIF</span> <span class="special">\</span>
|
||
<span class="special">(</span> <span class="special">\</span>
|
||
<span class="identifier">BOOST_PP_EQUAL_D</span> <span class="special">\</span>
|
||
<span class="special">(</span> <span class="special">\</span>
|
||
<span class="identifier">d</span><span class="special">,</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>
|
||
<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>
|
||
<span class="special">),</span> <span class="special">\</span>
|
||
<span class="identifier">BOOST_VMD_SWITCH_OP_DEFAULT</span><span class="special">,</span> <span class="special">\</span>
|
||
<span class="identifier">BOOST_VMD_SWITCH_OP_TEST_CURRENT</span> <span class="special">\</span>
|
||
<span class="special">)</span> <span class="special">\</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>
|
||
<span class="comment">/**/</span>
|
||
|
||
<span class="comment">/*
|
||
|
||
WHILE loop predicate
|
||
|
||
Continue the WHILE loop if a result has not yet been specified
|
||
|
||
*/</span>
|
||
|
||
<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>
|
||
<span class="identifier">BOOST_VMD_IS_EMPTY</span> <span class="special">\</span>
|
||
<span class="special">(</span> <span class="special">\</span>
|
||
<span class="identifier">BOOST_PP_TUPLE_ELEM</span> <span class="special">\</span>
|
||
<span class="special">(</span> <span class="special">\</span>
|
||
<span class="number">0</span><span class="special">,</span> <span class="special">\</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>
|
||
<span class="special">)</span> <span class="special">\</span>
|
||
<span class="special">)</span> <span class="special">\</span>
|
||
<span class="comment">/**/</span>
|
||
|
||
<span class="comment">/*
|
||
|
||
Invokes the function-like macro
|
||
|
||
macro = function-like macro name
|
||
tparams = tuple of macro parameters
|
||
|
||
*/</span>
|
||
|
||
<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>
|
||
<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>
|
||
<span class="comment">/**/</span>
|
||
|
||
<span class="comment">/*
|
||
|
||
Processes our WHILE loop result
|
||
|
||
callp = tuple of parameters for the called macro
|
||
result = tuple. The first tuple element is 0
|
||
if no macro has been found or 1 if a macro
|
||
has been found. If 1 the second element is
|
||
the name of a function-like macro
|
||
|
||
*/</span>
|
||
|
||
<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>
|
||
<span class="identifier">BOOST_PP_EXPR_IIF</span> <span class="special">\</span>
|
||
<span class="special">(</span> <span class="special">\</span>
|
||
<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>
|
||
<span class="identifier">BOOST_VMD_SWITCH_PROCESS_INVOKE_MACRO</span> <span class="special">\</span>
|
||
<span class="special">(</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">result</span><span class="special">),</span> <span class="special">\</span>
|
||
<span class="identifier">callp</span> <span class="special">\</span>
|
||
<span class="special">)</span> <span class="special">\</span>
|
||
<span class="special">)</span> <span class="special">\</span>
|
||
<span class="comment">/**/</span>
|
||
|
||
<span class="comment">/*
|
||
|
||
Use BOOST_VMD_SWITCH_IDENTITY to pass a fixed value instead
|
||
of a function-like macro as the second element of
|
||
any tuple of the variadic parameters, or as the default
|
||
value, to BOOST_VMD_SWITCH.
|
||
|
||
*/</span>
|
||
|
||
<span class="preprocessor">#if</span> <span class="identifier">BOOST_VMD_MSVC</span>
|
||
<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>
|
||
<span class="preprocessor">#else</span>
|
||
<span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_SWITCH_IDENTITY</span> <span class="identifier">BOOST_VMD_IDENTITY</span>
|
||
<span class="preprocessor">#endif</span>
|
||
|
||
<span class="comment">/*
|
||
|
||
Switch macro
|
||
|
||
Parameters are:
|
||
|
||
value = value to compare against. May be any VMD data value.
|
||
callp = tuple of parameters for the called macro
|
||
variadic parameters = each parameter must be a tuple.
|
||
Each tuple consists of a two-element tuple. The first element is
|
||
a value, which may be any VMD data value, and the second element
|
||
is the name of a function-like macro to be called if the value
|
||
is equal to the value to compare against. For a default value
|
||
the tuple is a single-element tuple which contains the name of
|
||
a function-like macro to be called if no other value matches.
|
||
|
||
*/</span>
|
||
|
||
<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>
|
||
<span class="identifier">BOOST_VMD_SWITCH_PROCESS</span> <span class="special">\</span>
|
||
<span class="special">(</span> <span class="special">\</span>
|
||
<span class="identifier">callp</span><span class="special">,</span> <span class="special">\</span>
|
||
<span class="identifier">BOOST_VMD_SWITCH_STATE_GET_RESULT</span> <span class="special">\</span>
|
||
<span class="special">(</span> <span class="special">\</span>
|
||
<span class="identifier">BOOST_PP_WHILE</span> <span class="special">\</span>
|
||
<span class="special">(</span> <span class="special">\</span>
|
||
<span class="identifier">BOOST_VMD_SWITCH_PRED</span><span class="special">,</span> <span class="special">\</span>
|
||
<span class="identifier">BOOST_VMD_SWITCH_OP</span><span class="special">,</span> <span class="special">\</span>
|
||
<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>
|
||
<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="comment">/**/</span>
|
||
|
||
<span class="preprocessor">#endif</span> <span class="comment">/* BOOST_PP_VARIADICS */</span>
|
||
</pre>
|
||
<p>
|
||
The code is fairly involved but it is commented so that it can be understood.
|
||
There are a few workarounds for a VC++ default preprocessor problem, which
|
||
I discovered, having to do with passing the name of a function-like macro in
|
||
a tuple.
|
||
</p>
|
||
<p>
|
||
The BOOST_VMD_SWITCH macro can be used with either macros to call or with fixed
|
||
values to return. When specifying macros to call the macro name is the second
|
||
element of the corresponding value-macro tuple, or in the 'default' case it
|
||
is just the macro name itself. When specifying fixed values to return the macro
|
||
'name' is BOOST_VMD_SWITCH_IDENTITY(fixed_value), whether as the second element
|
||
of the corresponding value-macro tuple or as the macro 'name' of the 'default'
|
||
case. In the variadic parameters the user can mix macro names and fixed values
|
||
as he likes.
|
||
</p>
|
||
<p>
|
||
Some simple examples:
|
||
</p>
|
||
<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>
|
||
<span class="identifier">test1_</span> <span class="special">##</span> <span class="identifier">number</span>
|
||
<span class="comment">/**/</span>
|
||
|
||
<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>
|
||
<span class="identifier">test2_</span> <span class="special">##</span> <span class="identifier">number</span>
|
||
<span class="comment">/**/</span>
|
||
|
||
<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>
|
||
<span class="identifier">test3_</span> <span class="special">##</span> <span class="identifier">number</span>
|
||
<span class="comment">/**/</span>
|
||
|
||
<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>
|
||
<span class="identifier">test_default_</span> <span class="special">##</span> <span class="identifier">number</span>
|
||
<span class="comment">/**/</span>
|
||
</pre>
|
||
<p>
|
||
We will use these simple macros in our calls to BOOST_VMD_SWITCH.
|
||
</p>
|
||
<pre class="programlisting"><span class="identifier">BOOST_VMD_SWITCH</span><span class="special">(</span><span class="number">1</span><span class="special">,</span>
|
||
<span class="special">(</span><span class="number">7</span><span class="special">),</span>
|
||
<span class="special">(</span><span class="identifier">BOOST_VMD_SWITCH_TEST_DEFAULT</span><span class="special">),</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>
|
||
<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>
|
||
<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>
|
||
<span class="special">)</span>
|
||
</pre>
|
||
<p>
|
||
Here our macro will return 'test1_7'.
|
||
</p>
|
||
<p>
|
||
Notice that 'cases' can be in any order.
|
||
</p>
|
||
<pre class="programlisting"><span class="identifier">BOOST_VMD_SWITCH</span><span class="special">(</span><span class="number">4</span><span class="special">,</span>
|
||
<span class="special">(</span><span class="number">7</span><span class="special">),</span>
|
||
<span class="special">(</span><span class="identifier">BOOST_VMD_SWITCH_TEST_DEFAULT</span><span class="special">),</span>
|
||
<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>
|
||
<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>
|
||
<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>
|
||
<span class="special">)</span>
|
||
</pre>
|
||
<p>
|
||
Here are macro uses the default case and returns 'test_default_7'.
|
||
</p>
|
||
<pre class="programlisting"><span class="identifier">BOOST_VMD_SWITCH</span><span class="special">(</span><span class="number">143</span><span class="special">,</span>
|
||
<span class="special">(</span><span class="number">7</span><span class="special">),</span>
|
||
<span class="special">(</span><span class="identifier">BOOST_VMD_SWITCH_TEST_DEFAULT</span><span class="special">),</span>
|
||
<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>
|
||
<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>
|
||
<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>
|
||
<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>
|
||
<span class="special">)</span>
|
||
</pre>
|
||
<p>
|
||
This shows how the matching case can be a fixed_value as the macro 'name'.
|
||
</p>
|
||
<pre class="programlisting"><span class="identifier">BOOST_VMD_SWITCH</span><span class="special">(</span><span class="number">155</span><span class="special">,</span>
|
||
<span class="special">(</span><span class="number">7</span><span class="special">),</span>
|
||
<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>
|
||
<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>
|
||
<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>
|
||
<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>
|
||
<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>
|
||
<span class="special">)</span>
|
||
</pre>
|
||
<p>
|
||
This shows how the default value can be a fixed_value as the macro 'name'.
|
||
</p>
|
||
<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>
|
||
<span class="special">(</span><span class="number">7</span><span class="special">),</span>
|
||
<span class="special">(</span><span class="identifier">BOOST_VMD_SWITCH_TEST_DEFAULT</span><span class="special">),</span>
|
||
<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>
|
||
<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>
|
||
<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>
|
||
<span class="special">)</span>
|
||
</pre>
|
||
<p>
|
||
This shows that the 'value' and each 'case' matching values can be different
|
||
data types just as long as the types are one which VMD can parse.
|
||
</p>
|
||
<p>
|
||
There is more that can be done with the BOOST_VMD_SWITCH code but as it is
|
||
I believe it could be useful for programmers writing macro code. For instance
|
||
there is no checking that more than one 'case' value is the same. We could
|
||
generate a BOOST_VMD_ASSERT if that were the situation. There is no concept
|
||
of falling through to the next 'case' as their is when 'break' is not used
|
||
at the bottom of a particular C++ 'case' statement. Nonetheless the example
|
||
gives the macro programmer an idea of what can be done using the BOOST_VMD_EQUAL
|
||
macro in treating data types generically, using BOOST_VMD_IS_EMPTY to test
|
||
for emptiness and using BOOST_VMD_IDENTITY to generate a fixed value when a
|
||
macro call is made.
|
||
</p>
|
||
<h4>
|
||
<a name="variadic_macro_data.vmd_examples.h1"></a>
|
||
<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
|
||
inner template</a>
|
||
</h4>
|
||
<p>
|
||
As a more practical example, just to show the possible use of VMD functionality
|
||
in current Boost code, I will briefly illustrate a change that could be made
|
||
to the TTI library when using VMD functionality.
|
||
</p>
|
||
<p>
|
||
The Boost TTI library, of which the current developer of VMD is also the developer,
|
||
specifies a way to introspect an inner class template of a class. The introspection
|
||
can occur for an inner class template of specific template parameters.
|
||
</p>
|
||
<p>
|
||
In the library a macro is used to generate the metafunction which allows the
|
||
introspection to work. The macro used is called BOOST_TTI_TEMPLATE. The macro
|
||
has both a variadic version and a non-variadic version.
|
||
</p>
|
||
<p>
|
||
In the non-variadic version the macro always takes two parameters for introspecting
|
||
for specific template parameters. The first parameter is the name of the template
|
||
and the second parameter is an array of the specific template parameters (
|
||
with or without the parameter names themselves ). So for a class template of
|
||
the form:
|
||
</p>
|
||
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">X</span><span class="special">,</span><span class="keyword">int</span> <span class="identifier">Y</span><span class="special">></span> <span class="keyword">class</span> <span class="identifier">MyTemplate</span> <span class="special">{</span> <span class="special">...</span> <span class="identifier">code</span> <span class="special">};</span>
|
||
</pre>
|
||
<p>
|
||
the non-variadic macro would be:
|
||
</p>
|
||
<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>
|
||
</pre>
|
||
<p>
|
||
I chose a Boost PP array rather than a Boost PP seq or a Boost PP list as I
|
||
felt the notation for specifying the template parameters was closer with the
|
||
array than with the others. Choosing a Boost PP tuple was not an option since
|
||
for non-variadic macros there is no way to automatically know the tuple size,
|
||
so an array was preferred.
|
||
</p>
|
||
<p>
|
||
For the variadic version variadic parameters are used so the notation would
|
||
be:
|
||
</p>
|
||
<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>
|
||
</pre>
|
||
<p>
|
||
since this is the most natural notation.
|
||
</p>
|
||
<p>
|
||
But for compatibility with the non-variadic version the end-user with variadic
|
||
macro support could also choose the Boost PP array form above.
|
||
</p>
|
||
<p>
|
||
Using VMD the variadic version could support any of the other Boost PP composite
|
||
types for the specific template parameters, even though I feel that the variadic
|
||
parameters form is easiest to use. In this scenario a user could specify:
|
||
</p>
|
||
<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>
|
||
</pre>
|
||
<p>
|
||
or
|
||
</p>
|
||
<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>
|
||
</pre>
|
||
<p>
|
||
or
|
||
</p>
|
||
<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>
|
||
</pre>
|
||
<p>
|
||
The only change needed would be in the code which takes the second parameter
|
||
and converts it to the final form used internally ( a Boost PP array ). This
|
||
occurs in the macro BOOST_TTI_DETAIL_TRAIT_CALL_HAS_TEMPLATE_CHECK_PARAMS in
|
||
the <boost/tti/detail/dtemplate_params.hpp> file. The code has two situations,
|
||
one for VC++8 or below and one for all other compilers. For our example we
|
||
will concentrate just on the one for all other compilers. You do not need to
|
||
know what the code does internally to complete the creation of the appropriate
|
||
metafunction to follow this example. The macro code in question looks like
|
||
this:
|
||
</p>
|
||
<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>
|
||
<span class="identifier">BOOST_TTI_DETAIL_HAS_MEMBER_WITH_TEMPLATE_SFINAE</span> <span class="special">\</span>
|
||
<span class="special">(</span> <span class="special">\</span>
|
||
<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>
|
||
<span class="special">)</span> <span class="special">\</span>
|
||
<span class="comment">/**/</span>
|
||
</pre>
|
||
<p>
|
||
In this code we are taking the name of the metafunction ( trait ), the name
|
||
of the template ( name ), and our specific template parameters ( tpArray )
|
||
and passing the information in the form of a Boost PP array to another macro,
|
||
which will eventually create the metafunction which the end-user uses to test
|
||
if such a class template exists within some enclosing class. Even if tpArray
|
||
were a list, seq, or tuple we still want to pass the information internally
|
||
to BOOST_TTI_DETAIL_HAS_MEMBER_WITH_TEMPLATE_SFINAE in the form you can see
|
||
above, which is a Boost PP array. We don't need or want to change that internal
|
||
representation.
|
||
</p>
|
||
<p>
|
||
The current code, used by both the non-variadic and variadic version of the
|
||
BOOST_TTI_TEMPLATE template, assumes the 'tpArray' parameter is a Boost PP
|
||
array. But if it could be a tuple, seq, or list in the variadic version the
|
||
code could become, with the appropriate Boost PP and VMD header files:
|
||
</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">preprocessor</span><span class="special">/</span><span class="identifier">arithmetic</span><span class="special">/</span><span class="identifier">add</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">array</span><span class="special">/</span><span class="keyword">enum</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">array</span><span class="special">/</span><span class="identifier">size</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">control</span><span class="special">/</span><span class="identifier">expr_iif</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<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>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">list</span><span class="special">/</span><span class="keyword">enum</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">list</span><span class="special">/</span><span class="identifier">size</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">seq</span><span class="special">/</span><span class="keyword">enum</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">seq</span><span class="special">/</span><span class="identifier">size</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">tuple</span><span class="special">/</span><span class="keyword">enum</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">tuple</span><span class="special">/</span><span class="identifier">size</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">identity</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">is_array</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">is_list</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<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">#if</span> <span class="identifier">BOOST_PP_VARIADICS</span>
|
||
|
||
<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>
|
||
<span class="identifier">BOOST_TTI_DETAIL_HAS_MEMBER_WITH_TEMPLATE_SFINAE</span> <span class="special">\</span>
|
||
<span class="special">(</span> <span class="special">\</span>
|
||
<span class="identifier">BOOST_TTI_DETAIL_TRAIT_CALL_HAS_TEMPLATE_CHECK_PARAMS_TYPE_CONCAT</span> <span class="special">\</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="identifier">tpArray</span><span class="special">,</span> <span class="special">\</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>
|
||
<span class="special">)</span> <span class="special">\</span>
|
||
<span class="special">)</span> <span class="special">\</span>
|
||
<span class="comment">/**/</span>
|
||
|
||
<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>
|
||
<span class="identifier">BOOST_VMD_IDENTITY_RESULT</span> <span class="special">\</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_ARRAY</span><span class="special">(</span><span class="identifier">tpArray</span><span class="special">),</span> <span class="special">\</span>
|
||
<span class="identifier">BOOST_VMD_IDENTITY</span><span class="special">(</span><span class="identifier">ARRAY</span><span class="special">),</span> <span class="special">\</span>
|
||
<span class="identifier">BOOST_TTI_DETAIL_TRAIT_CALL_HAS_TEMPLATE_CHECK_PARAMS_TYPE_LIST</span> <span class="special">\</span>
|
||
<span class="special">)</span> <span class="special">\</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>
|
||
<span class="comment">/**/</span>
|
||
|
||
<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>
|
||
<span class="identifier">BOOST_VMD_IDENTITY_RESULT</span> <span class="special">\</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_LIST</span><span class="special">(</span><span class="identifier">tpArray</span><span class="special">),</span> <span class="special">\</span>
|
||
<span class="identifier">BOOST_VMD_IDENTITY</span><span class="special">(</span><span class="identifier">LIST</span><span class="special">),</span> <span class="special">\</span>
|
||
<span class="identifier">BOOST_TTI_DETAIL_TRAIT_CALL_HAS_TEMPLATE_CHECK_PARAMS_TYPE_SEQ</span> <span class="special">\</span>
|
||
<span class="special">)</span> <span class="special">\</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>
|
||
<span class="comment">/**/</span>
|
||
|
||
<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>
|
||
<span class="identifier">BOOST_VMD_IDENTITY_RESULT</span> <span class="special">\</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">tpArray</span><span class="special">),</span> <span class="special">\</span>
|
||
<span class="identifier">BOOST_VMD_IDENTITY</span><span class="special">(</span><span class="identifier">SEQ</span><span class="special">),</span> <span class="special">\</span>
|
||
<span class="identifier">BOOST_TTI_DETAIL_TRAIT_CALL_HAS_TEMPLATE_CHECK_PARAMS_TYPE_TUPLE</span> <span class="special">\</span>
|
||
<span class="special">)</span> <span class="special">\</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>
|
||
<span class="comment">/**/</span>
|
||
|
||
<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>
|
||
<span class="identifier">BOOST_VMD_IDENTITY_RESULT</span> <span class="special">\</span>
|
||
<span class="special">(</span> <span class="special">\</span>
|
||
<span class="identifier">BOOST_PP_EXPR_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">tpArray</span><span class="special">),</span> <span class="special">\</span>
|
||
<span class="identifier">BOOST_VMD_IDENTITY</span><span class="special">(</span><span class="identifier">TUPLE</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="comment">/**/</span>
|
||
|
||
<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>
|
||
<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>
|
||
<span class="comment">/**/</span>
|
||
|
||
<span class="preprocessor">#else</span>
|
||
|
||
<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>
|
||
<span class="identifier">BOOST_TTI_DETAIL_HAS_MEMBER_WITH_TEMPLATE_SFINAE</span> <span class="special">\</span>
|
||
<span class="special">(</span> <span class="special">\</span>
|
||
<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>
|
||
<span class="special">)</span> <span class="special">\</span>
|
||
<span class="comment">/**/</span>
|
||
|
||
<span class="preprocessor">#endif</span>
|
||
</pre>
|
||
<p>
|
||
This of course gets more elaborate, but could be shortened considerably if
|
||
we chose to use BOOST_VMD_GET_TYPE and the invented BOOST_VMD_SWITCH of our
|
||
first example. We will assume in this second version of the code above that
|
||
our BOOST_VMD_SWITCH macro has been #included from somewhere.
|
||
</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">preprocessor</span><span class="special">/</span><span class="identifier">arithmetic</span><span class="special">/</span><span class="identifier">add</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">array</span><span class="special">/</span><span class="keyword">enum</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">array</span><span class="special">/</span><span class="identifier">size</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">list</span><span class="special">/</span><span class="keyword">enum</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">list</span><span class="special">/</span><span class="identifier">size</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">seq</span><span class="special">/</span><span class="keyword">enum</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">seq</span><span class="special">/</span><span class="identifier">size</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">tuple</span><span class="special">/</span><span class="keyword">enum</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">preprocessor</span><span class="special">/</span><span class="identifier">tuple</span><span class="special">/</span><span class="identifier">size</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<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="preprocessor">#if</span> <span class="identifier">BOOST_PP_VARIADICS</span>
|
||
|
||
<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>
|
||
<span class="identifier">BOOST_TTI_DETAIL_HAS_MEMBER_WITH_TEMPLATE_SFINAE</span> <span class="special">\</span>
|
||
<span class="special">(</span> <span class="special">\</span>
|
||
<span class="identifier">BOOST_TTI_DETAIL_TRAIT_CALL_HAS_TEMPLATE_CHECK_PARAMS_TYPE_CONCAT</span> <span class="special">\</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="identifier">tpArray</span><span class="special">,</span> <span class="special">\</span>
|
||
<span class="identifier">BOOST_VMD_SWITCH</span> <span class="special">\</span>
|
||
<span class="special">(</span> <span class="special">\</span>
|
||
<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>
|
||
<span class="special">(</span><span class="number">1</span><span class="special">),</span> <span class="special">\</span>
|
||
<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>
|
||
<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>
|
||
<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>
|
||
<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>
|
||
<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="comment">/**/</span>
|
||
|
||
<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>
|
||
<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>
|
||
<span class="comment">/**/</span>
|
||
|
||
<span class="preprocessor">#else</span>
|
||
|
||
<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>
|
||
<span class="identifier">BOOST_TTI_DETAIL_HAS_MEMBER_WITH_TEMPLATE_SFINAE</span> <span class="special">\</span>
|
||
<span class="special">(</span> <span class="special">\</span>
|
||
<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>
|
||
<span class="special">)</span> <span class="special">\</span>
|
||
<span class="comment">/**/</span>
|
||
|
||
<span class="preprocessor">#endif</span>
|
||
</pre>
|
||
<p>
|
||
This is shorter and easier to understand. The '(1)' passed as the calling values
|
||
to BOOST_VMD_SWITCH could just as well be '()' but VC8 has trouble with empty
|
||
parentheses so I avoid it here.
|
||
</p>
|
||
<p>
|
||
In the case of the TTI, is such a change worth it to give more flexibility
|
||
to the end-user ? In reality, because the variadic version of passing the specific
|
||
template parameters as variadic data is syntactically easier to use than any
|
||
of the Boost PP composite forms, I am actually happy enough with that use not
|
||
to pursue the sort of functionality I presented in this example. But the example
|
||
nonetheless shows the power of the VMD functionality for creating macros which
|
||
add flexibility when the macro programmer feels he needs it for his library.
|
||
</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_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>
|
||
</div>
|
||
</body>
|
||
</html>
|