1<html> 2<head> 3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 4<title>Useful variadic macros not in Boost PP</title> 5<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css"> 6<meta name="generator" content="DocBook XSL Stylesheets V1.79.1"> 7<link rel="home" href="../index.html" title="Chapter 1. The Variadic Macro Data Library 1.9"> 8<link rel="up" href="../index.html" title="Chapter 1. The Variadic Macro Data Library 1.9"> 9<link rel="prev" href="vmd_identifier_subtype.html" title="Identifier subtypes"> 10<link rel="next" href="vmd_useful/vmd_identity.html" title="Generating emptiness and identity"> 11</head> 12<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> 13<table cellpadding="2" width="100%"><tr> 14<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td> 15<td align="center"><a href="../../../../../index.html">Home</a></td> 16<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td> 17<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> 18<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> 19<td align="center"><a href="../../../../../more/index.htm">More</a></td> 20</tr></table> 21<hr> 22<div class="spirit-nav"> 23<a accesskey="p" href="vmd_identifier_subtype.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="vmd_useful/vmd_identity.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a> 24</div> 25<div class="section"> 26<div class="titlepage"><div><div><h2 class="title" style="clear: both"> 27<a name="variadic_macro_data.vmd_useful"></a><a class="link" href="vmd_useful.html" title="Useful variadic macros not in Boost PP">Useful variadic macros 28 not in Boost PP</a> 29</h2></div></div></div> 30<div class="toc"><dl class="toc"> 31<dt><span class="section"><a href="vmd_useful.html#variadic_macro_data.vmd_useful.vmd_assert">Asserting 32 and data types</a></span></dt> 33<dt><span class="section"><a href="vmd_useful/vmd_identity.html">Generating 34 emptiness and identity</a></span></dt> 35<dt><span class="section"><a href="vmd_useful/vmd_empty_ppdata.html">Functionality 36 for "empty" seqs and tuples</a></span></dt> 37</dl></div> 38<p> 39 Previous sections of this documentation have explained how VMD can be used 40 to parse VMD data types, as well as recognize emptiness. 41 </p> 42<p> 43 Another area of functionality of VMD involves useful variadic macros, based 44 on the previous functionality, which expands on similar macros already in Boost 45 PP. These variadic macros can be divided into sections illustrating these areas 46 of behavior: 47 </p> 48<div class="orderedlist"><ol class="orderedlist" type="1"> 49<li class="listitem"> 50 Expanded assertion macros 51 </li> 52<li class="listitem"> 53 Expanded identity functionality 54 </li> 55<li class="listitem"> 56 Expanded seq and tuple functionality for "empty" seqs and tuples 57 </li> 58</ol></div> 59<p> 60 Sub-sections for each of these now follow in the documentation. 61 </p> 62<div class="section"> 63<div class="titlepage"><div><div><h3 class="title"> 64<a name="variadic_macro_data.vmd_useful.vmd_assert"></a><a class="link" href="vmd_useful.html#variadic_macro_data.vmd_useful.vmd_assert" title="Asserting and data types">Asserting 65 and data types</a> 66</h3></div></div></div> 67<p> 68 The VMD macros for identifying data types work best when the macro logic 69 can take different paths depending on the type of data being passed for a 70 macro parameter. But occasionally the preprocessor metaprogrammer wants to 71 simply verify that the macro parameter data is of the correct data type, 72 else a preprocessing error should be generated to notify the programmer invoking 73 the macro that the data passed is the incorrect type. 74 </p> 75<h5> 76<a name="variadic_macro_data.vmd_useful.vmd_assert.h0"></a> 77 <span class="phrase"><a name="variadic_macro_data.vmd_useful.vmd_assert.using_boost_vmd_assert"></a></span><a class="link" href="vmd_useful.html#variadic_macro_data.vmd_useful.vmd_assert.using_boost_vmd_assert">Using 78 BOOST_VMD_ASSERT</a> 79 </h5> 80<p> 81 The Boost PP library has a macro which produces a preprocessing error when 82 the condition passed to it is 0. This macro is called BOOST_PP_ASSERT. The 83 macro produces a preprocessor error by forcing a call to an internal macro 84 with the wrong number of arguments. According to the C++ standard this should 85 always cause an immediate preprocessing error for conforming compilers. 86 </p> 87<p> 88 Unfortunately VC++ will only produce a warning when the wrong number of arguments 89 are passed to a macro. Therefore the BOOST_PP_ASSERT macro does not produce 90 a preprocessing error using VC++. Amazingly enough there appears to be no 91 other way in which VC++ can be forced to issue a preprocessing error by invoking 92 a macro ( if you find one please tell me about it ). However one can create 93 invalid C++ as the output from a macro invocation which causes VC++ to produce 94 a compiler error when the VC++ compiler later encounters the construct. 95 </p> 96<p> 97 This is what the macro BOOST_VMD_ASSERT does. It takes the same conditional 98 argument as BOOST_PP_ASSERT and it calls BOOST_PP_ASSERT when not used with 99 VC++, otherwise if the condition is 0 it generates a compiler error by generating 100 invalid C++ when used with VC++. The compiler error is generated by producing 101 invalid C++ whose form is: 102 </p> 103<pre class="programlisting"><span class="keyword">typedef</span> <span class="keyword">char</span> <span class="identifier">BOOST_VMD_ASSERT_ERROR</span><span class="special">[-</span><span class="number">1</span><span class="special">];</span> 104</pre> 105<p> 106 By passing a second optional argument, whose form is a preprocessing identifier, 107 to BOOST_VMD_ASSERT you can generate the invalid C++ for VC++, if the first 108 argument is 0, of the form: 109 </p> 110<pre class="programlisting"><span class="keyword">typedef</span> <span class="keyword">char</span> <span class="identifier">optional_argument</span><span class="special">[-</span><span class="number">1</span><span class="special">];</span> 111</pre> 112<p> 113 instead. This may give a little more clarity, if desired, to the C++ error 114 generated. 115 </p> 116<p> 117 If the first conditional argument is not 0, BOOST_VMD_ASSERT produces no 118 output. 119 </p> 120<h5> 121<a name="variadic_macro_data.vmd_useful.vmd_assert.h1"></a> 122 <span class="phrase"><a name="variadic_macro_data.vmd_useful.vmd_assert.boost_vmd_assert_usage"></a></span><a class="link" href="vmd_useful.html#variadic_macro_data.vmd_useful.vmd_assert.boost_vmd_assert_usage">BOOST_VMD_ASSERT 123 Usage</a> 124 </h5> 125<p> 126 To use the BOOST_VMD_ASSERT macro either include the general header: 127 </p> 128<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 129</pre> 130<p> 131 or include the specific header: 132 </p> 133<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">assert</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 134</pre> 135<h5> 136<a name="variadic_macro_data.vmd_useful.vmd_assert.h2"></a> 137 <span class="phrase"><a name="variadic_macro_data.vmd_useful.vmd_assert.assertions_for_data_types"></a></span><a class="link" href="vmd_useful.html#variadic_macro_data.vmd_useful.vmd_assert.assertions_for_data_types">Assertions 138 for data types </a> 139 </h5> 140<p> 141 The data types have their own assertion macros. These are largely just shortcuts 142 for passing the result of the identifying macros to BOOST_VMD_ASSERT. These 143 assertion macros are: 144 </p> 145<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> 146<li class="listitem"> 147 emptiness, BOOST_VMD_ASSERT_IS_EMPTY 148 </li> 149<li class="listitem"> 150 identifier, BOOST_VMD_ASSERT_IS_IDENTIFIER 151 </li> 152<li class="listitem"> 153 number, BOOST_VMD_ASSERT_IS_NUMBER 154 </li> 155<li class="listitem"> 156 array, BOOST_VMD_ASSERT_IS_ARRAY 157 </li> 158<li class="listitem"> 159 list, BOOST_VMD_ASSERT_IS_LIST 160 </li> 161<li class="listitem"> 162 seq, BOOST_VMD_ASSERT_IS_SEQ 163 </li> 164<li class="listitem"> 165 tuple, BOOST_VMD_ASSERT_IS_TUPLE 166 </li> 167<li class="listitem"> 168 type, BOOST_VMD_ASSERT_IS_TYPE 169 </li> 170</ul></div> 171<p> 172 Each of these macros take as parameters the exact same argument as their 173 corresponding identifying macros. But instead of returning non-zero or 0, 174 each of these macros produce a compiler error if the type of the input is 175 not correct. 176 </p> 177<p> 178 Each of these macros only check for its assertion when the macro BOOST_VMD_ASSERT_DATA 179 is set to 1. By default BOOST_VMD_ASSERT_DATA is only set to 1 in compiler 180 debug mode. The programmer can manually set BOOST_VMD_ASSERT_DATA to 1 prior 181 to using one the data types assert macros if he wishes. 182 </p> 183<h5> 184<a name="variadic_macro_data.vmd_useful.vmd_assert.h3"></a> 185 <span class="phrase"><a name="variadic_macro_data.vmd_useful.vmd_assert.boost_vmd_assert_usage0"></a></span><a class="link" href="vmd_useful.html#variadic_macro_data.vmd_useful.vmd_assert.boost_vmd_assert_usage0">BOOST_VMD_ASSERT_... 186 Usage</a> 187 </h5> 188<p> 189 To use the individual BOOST_VMD_ASSERT_... macros either include the general 190 header: 191 </p> 192<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 193</pre> 194<p> 195 or include the specific header: 196 </p> 197<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">assert_is_empty</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> <span class="comment">// BOOST_VMD_ASSERT_IS_EMPTY</span> 198<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">assert_is_identifier</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> <span class="comment">// BOOST_VMD_ASSERT_IS_IDENTIFIER</span> 199<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">assert_is_number</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> <span class="comment">// BOOST_VMD_ASSERT_IS_NUMBER</span> 200<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">assert_is_array</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> <span class="comment">// BOOST_VMD_ASSERT_IS_ARRAY</span> 201<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">assert_is_list</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> <span class="comment">// BOOST_VMD_ASSERT_IS_LIST</span> 202<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">assert_is_seq</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> <span class="comment">// BOOST_VMD_ASSERT_IS_SEQ</span> 203<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">assert_is_tuple</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> <span class="comment">// BOOST_VMD_ASSERT_IS_TUPLE</span> 204<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">assert_is_type</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> <span class="comment">// BOOST_VMD_ASSERT_IS_TYPE</span> 205</pre> 206<h5> 207<a name="variadic_macro_data.vmd_useful.vmd_assert.h4"></a> 208 <span class="phrase"><a name="variadic_macro_data.vmd_useful.vmd_assert.assertions_and_vc"></a></span><a class="link" href="vmd_useful.html#variadic_macro_data.vmd_useful.vmd_assert.assertions_and_vc">Assertions 209 and VC++ </a> 210 </h5> 211<p> 212 The VC++ compiler has a quirk when dealing with BOOST_VMD_ASSERT and the 213 data type assert macros. If you invoke one of the assert macros within another 214 macro which would normally generate output preprocessor tokens, it is necessary 215 when using VC++ to concatenate the result of the assert macro to whatever 216 other preprocessor data is being generated, even if the assert macro does 217 not generate an error. 218 </p> 219<p> 220 As a simple example let us suppose we have a macro expecting a tuple and 221 generating 1 if the tuple has more than 2 elements, otherwise it generates 222 0. Ordinarily we could write: 223 </p> 224<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">comparison</span><span class="special">/</span><span class="identifier">greater</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 225<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> 226<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> 227<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">assert_is_tuple</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 228 229<span class="preprocessor">#define</span> <span class="identifier">AMACRO</span><span class="special">(</span><span class="identifier">atuple</span><span class="special">)</span> <span class="special">\</span> 230 <span class="identifier">BOOST_VMD_ASSERT_IS_TUPLE</span><span class="special">(</span><span class="identifier">atuple</span><span class="special">)</span> <span class="special">\</span> 231 <span class="identifier">BOOST_PP_IIF</span><span class="special">(</span><span class="identifier">BOOST_PP_GREATER</span><span class="special">(</span><span class="identifier">BOOST_PP_TUPLE_SIZE</span><span class="special">(</span><span class="identifier">atuple</span><span class="special">),</span> <span class="number">2</span><span class="special">),</span><span class="number">1</span><span class="special">,</span><span class="number">0</span><span class="special">)</span> 232</pre> 233<p> 234 but for VC++ we must write 235 </p> 236<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">cat</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 237<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">greater</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 238<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> 239<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> 240<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">assert_is_tuple</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 241 242<span class="preprocessor">#define</span> <span class="identifier">AMACRO</span><span class="special">(</span><span class="identifier">atuple</span><span class="special">)</span> <span class="special">\</span> 243 <span class="identifier">BOOST_PP_CAT</span> <span class="special">\</span> 244 <span class="special">(</span> <span class="special">\</span> 245 <span class="identifier">BOOST_VMD_ASSERT_IS_TUPLE</span><span class="special">(</span><span class="identifier">atuple</span><span class="special">),</span> <span class="special">\</span> 246 <span class="identifier">BOOST_PP_IIF</span><span class="special">(</span><span class="identifier">BOOST_PP_GREATER</span><span class="special">(</span><span class="identifier">BOOST_PP_TUPLE_SIZE</span><span class="special">(</span><span class="identifier">atuple</span><span class="special">),</span> <span class="number">2</span><span class="special">),</span><span class="number">1</span><span class="special">,</span><span class="number">0</span><span class="special">)</span> <span class="special">\</span> 247 <span class="special">)</span> 248</pre> 249<p> 250 VC++ does not work correctly in the first instance, erroneously getting confused 251 as far as compiler output is concerned. But by using BOOST_PP_CAT in the 252 second condition VC++ will work correctly with VMD assertions. 253 </p> 254</div> 255</div> 256<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> 257<td align="left"></td> 258<td align="right"><div class="copyright-footer">Copyright © 2010-2017 Tropic Software 259 East Inc</div></td> 260</tr></table> 261<hr> 262<div class="spirit-nav"> 263<a accesskey="p" href="vmd_identifier_subtype.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="vmd_useful/vmd_identity.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a> 264</div> 265</body> 266</html> 267