Imported Upstream version 1.72.0
[platform/upstream/boost.git] / libs / vmd / doc / html / variadic_macro_data / vmd_specific.html
1 <html>
2 <head>
3 <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
4 <title>Specific macros for working with data types</title>
5 <link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
6 <meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
7 <link rel="home" href="../index.html" title="Chapter&#160;1.&#160;The Variadic Macro Data Library 1.9">
8 <link rel="up" href="../index.html" title="Chapter&#160;1.&#160;The Variadic Macro Data Library 1.9">
9 <link rel="prev" href="vmd_data_types.html" title="Data types">
10 <link rel="next" href="vmd_specific/vmd_constraints.html" title="Macro constraints">
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_data_types.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_specific/vmd_constraints.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_specific"></a><a class="link" href="vmd_specific.html" title="Specific macros for working with data types">Specific macros for working
28     with data types</a>
29 </h2></div></div></div>
30 <div class="toc"><dl class="toc">
31 <dt><span class="section"><a href="vmd_specific.html#variadic_macro_data.vmd_specific.vmd_test_empty">Emptiness</a></span></dt>
32 <dt><span class="section"><a href="vmd_specific/vmd_constraints.html">Macro
33       constraints</a></span></dt>
34 <dt><span class="section"><a href="vmd_specific/vmd_identifier.html">Identifiers</a></span></dt>
35 <dt><span class="section"><a href="vmd_specific/vmd_number.html">Numbers</a></span></dt>
36 <dt><span class="section"><a href="vmd_specific/vmd_type.html">Types</a></span></dt>
37 <dt><span class="section"><a href="vmd_specific/vmd_pp_data_types.html">VMD
38       and Boost PP data types</a></span></dt>
39 <dt><span class="section"><a href="vmd_specific/vmd_identifying.html">Identifying
40       data types</a></span></dt>
41 </dl></div>
42 <p>
43       VMD has a number of specific macros for parsing data types. Each of these macros
44       asks if some input is a particular VMD data type.
45     </p>
46 <div class="section">
47 <div class="titlepage"><div><div><h3 class="title">
48 <a name="variadic_macro_data.vmd_specific.vmd_test_empty"></a><a class="link" href="vmd_specific.html#variadic_macro_data.vmd_specific.vmd_test_empty" title="Emptiness">Emptiness</a>
49 </h3></div></div></div>
50 <h5>
51 <a name="variadic_macro_data.vmd_specific.vmd_test_empty.h0"></a>
52         <span class="phrase"><a name="variadic_macro_data.vmd_specific.vmd_test_empty.passing_empty_arguments"></a></span><a class="link" href="vmd_specific.html#variadic_macro_data.vmd_specific.vmd_test_empty.passing_empty_arguments">Passing
53         empty arguments</a>
54       </h5>
55 <p>
56         It is possible to pass an empty argument to a macro. The official terminology
57         for this in the C++ standard is an argument "consisting of no preprocessing
58         tokens".
59       </p>
60 <p>
61         Let us consider a number of cases without worrying too much what the macro
62         output represents.
63       </p>
64 <p>
65         Consider these two function-like macros:
66       </p>
67 <pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">SMACRO</span><span class="special">()</span> <span class="identifier">someoutput</span>
68 <span class="preprocessor">#define</span> <span class="identifier">EMACRO</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span> <span class="identifier">otheroutput</span> <span class="identifier">x</span>
69 </pre>
70 <p>
71         The first macro takes no parameters so invoking it must always be done by
72       </p>
73 <pre class="programlisting"><span class="identifier">SMACRO</span><span class="special">()</span>
74 </pre>
75 <p>
76         and passing any arguments to it would be invalid.
77       </p>
78 <p>
79         The second macro takes a single parameter. it can be evoked as
80       </p>
81 <pre class="programlisting"><span class="identifier">EMACRO</span><span class="special">(</span><span class="identifier">somedata</span><span class="special">)</span>
82 </pre>
83 <p>
84         but it also can be invoked as
85       </p>
86 <pre class="programlisting"><span class="identifier">EMACRO</span><span class="special">()</span>
87 </pre>
88 <p>
89         In the second invocation of EMACRO we are passing an empty argument to the
90         macro. Similarly for any macro having 1 or more parameters, an empty argument
91         can be validly passed for any of the parameters, as in
92       </p>
93 <pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">MMACRO</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span><span class="identifier">y</span><span class="special">,</span><span class="identifier">z</span><span class="special">)</span> <span class="identifier">x</span> <span class="identifier">y</span> <span class="identifier">z</span>
94
95 <span class="identifier">MMACRO</span><span class="special">(</span><span class="number">1</span><span class="special">,,</span><span class="number">2</span><span class="special">)</span>
96 </pre>
97 <p>
98         An empty argument is an argument even if we are passing nothing.
99       </p>
100 <p>
101         Because an empty argument can be passed for a given parameter of a macro
102         does not mean one should do so. Any given macro will specify what each argument
103         to a macro should represent, and it is has normally been very rare to encounter
104         a macro which specifies that an empty argument can logically be passed for
105         a given argument. But from the perspective of standard C++ it is perfectly
106         valid to pass an empty argument for a macro parameter.
107       </p>
108 <p>
109         The notion of passing empty arguments can be extended to passing empty data
110         which "consists of no preprocessing tokens" in slightly more complicated
111         situations. It is possible to pass empty data as an argument to a variadic
112         macro in the form of variadic macro data, as in
113       </p>
114 <pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">VMACRO</span><span class="special">(</span><span class="identifier">x</span><span class="special">,...)</span> <span class="identifier">x</span> <span class="identifier">__VA_ARGS__</span>
115 </pre>
116 <p>
117         invoked as
118       </p>
119 <pre class="programlisting"><span class="identifier">VMACRO</span><span class="special">(</span><span class="identifier">somedata</span><span class="special">,)</span>
120 </pre>
121 <p>
122         Here one passes empty data as the variadic macro data and it is perfectly
123         valid C++. Please notice that this different from
124       </p>
125 <pre class="programlisting"><span class="identifier">VMACRO</span><span class="special">(</span><span class="identifier">somedata</span><span class="special">)</span>
126 </pre>
127 <p>
128         which is not valid C++, prior to C++20, since something must be passed for
129         the variadic argument. In C++20 the above invocation is valid and is exactly
130         the same as in our previous example of 'VMACRO(somedata,)' where one passes
131         empty data as the variadic macro data. Similarly one could invoke the macro
132         as
133       </p>
134 <pre class="programlisting"><span class="identifier">VMACRO</span><span class="special">(</span><span class="identifier">somedata</span><span class="special">,</span><span class="identifier">vdata1</span><span class="special">,,</span><span class="identifier">vdata3</span><span class="special">)</span>
135 </pre>
136 <p>
137         where one is passing variadic macro data but an element in the variadic macro
138         data is empty.
139       </p>
140 <p>
141         Furthermore if we are invoking a macro which expects a Boost PP data type,
142         such as a tuple, we could also validly pass empty data for all or part of
143         the data in a tuple, as in
144       </p>
145 <pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">TMACRO</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span><span class="identifier">atuple</span><span class="special">)</span> <span class="identifier">x</span> <span class="identifier">atuple</span>
146
147 <span class="identifier">TMACRO</span><span class="special">(</span><span class="identifier">somedata</span><span class="special">,())</span>
148 </pre>
149 <p>
150         In this case we are passing a 1 element tuple where the single element itself
151         is empty.
152       </p>
153 <p>
154         or
155       </p>
156 <pre class="programlisting"><span class="identifier">TMACRO</span><span class="special">(</span><span class="identifier">somedata</span><span class="special">,(</span><span class="identifier">telem1</span><span class="special">,,</span><span class="identifier">telem2</span><span class="special">,</span><span class="identifier">teleem3</span><span class="special">))</span>
157 </pre>
158 <p>
159         In this case we are passing a 4 element tuple where the second element is
160         empty.
161       </p>
162 <p>
163         Again either invocation is valid C++ but it is not necessarily what the designed
164         of the macro has desired, even if in both cases the macro designer has specified
165         that the second parameter must be a tuple for the macro to work properly.
166       </p>
167 <h5>
168 <a name="variadic_macro_data.vmd_specific.vmd_test_empty.h1"></a>
169         <span class="phrase"><a name="variadic_macro_data.vmd_specific.vmd_test_empty.returning_emptiness"></a></span><a class="link" href="vmd_specific.html#variadic_macro_data.vmd_specific.vmd_test_empty.returning_emptiness">Returning
170         emptiness</a>
171       </h5>
172 <p>
173         Similar to passing empty arguments in various ways to a macro, the data which
174         a macro returns ( or 'generates' may be a better term ) could be empty, in
175         various ways. Again I am not necessarily promoting this idea as a common
176         occurrence of macro design but merely pointing it out as valid C++ preprocessing.
177       </p>
178 <pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">RMACRO</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span><span class="identifier">y</span><span class="special">,</span><span class="identifier">z</span><span class="special">)</span>
179
180 <span class="identifier">RMACRO</span><span class="special">(</span><span class="identifier">data1</span><span class="special">,</span><span class="identifier">data2</span><span class="special">,</span><span class="identifier">data3</span><span class="special">)</span>
181 </pre>
182 <p>
183         It is perfectly valid C++ to return "nothing" from a macro invocation.
184         In fact a number of macros in Boost PP do that based on the preprocessor
185         metaprogramming logic of the macro, and are documented as such.
186       </p>
187 <p>
188         Similarly one could return nothing as part or all of a Boost PP data type
189         or even as part of variadic macro data.
190       </p>
191 <pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">TRETMACRO</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span><span class="identifier">y</span><span class="special">,</span><span class="identifier">z</span><span class="special">)</span> <span class="special">()</span>
192 <span class="preprocessor">#define</span> <span class="identifier">TRETMACRO1</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span><span class="identifier">y</span><span class="special">,</span><span class="identifier">z</span><span class="special">)</span> <span class="special">(</span><span class="identifier">x</span><span class="special">,,</span><span class="identifier">y</span><span class="special">,,</span><span class="identifier">z</span><span class="special">)</span>
193 <span class="preprocessor">#define</span> <span class="identifier">VRETMACRO</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span><span class="identifier">y</span><span class="special">,</span><span class="identifier">z</span><span class="special">)</span> <span class="identifier">x</span><span class="special">,,</span><span class="identifier">y</span><span class="special">,,</span><span class="identifier">z</span>
194 </pre>
195 <p>
196         Here again we are returning something but in terms of a Boost PP tuple or
197         in terms of variadic data, we have elements which are empty.
198       </p>
199 <h5>
200 <a name="variadic_macro_data.vmd_specific.vmd_test_empty.h2"></a>
201         <span class="phrase"><a name="variadic_macro_data.vmd_specific.vmd_test_empty.emptiness_in_preprocessor_metapr"></a></span><a class="link" href="vmd_specific.html#variadic_macro_data.vmd_specific.vmd_test_empty.emptiness_in_preprocessor_metapr">Emptiness
202         in preprocessor metaprogramming</a>
203       </h5>
204 <p>
205         In the examples given above where "emptiness" in one form of another
206         is passed as arguments to a macro or returned from a macro, the examples
207         I have given were created as simplified as possible to illustrate my points.
208         In actual preprocessor metaprogramming, using Boost PP, where complicated
209         logic is used to generate macro output based on the arguments to a macro,
210         it might be useful to allow and work with empty data if one were able to
211         test for the fact that data was indeed empty.
212       </p>
213 <h5>
214 <a name="variadic_macro_data.vmd_specific.vmd_test_empty.h3"></a>
215         <span class="phrase"><a name="variadic_macro_data.vmd_specific.vmd_test_empty.testing_for_empty_data"></a></span><a class="link" href="vmd_specific.html#variadic_macro_data.vmd_specific.vmd_test_empty.testing_for_empty_data">Testing
216         for empty data</a>
217       </h5>
218 <p>
219         Currently Boost PP has an undocumented macro for testing whether a parameter
220         is empty of not, written without the use of variadic macros. The macro is
221         called BOOST_PP_IS_EMPTY. The macro is by its nature flawed, since there
222         is no generalized way of determining whether or not a parameter is empty
223         using the C++ preprocessor prior to C++20. But the macro will work given
224         input limited in various ways or if the input is actually empty.
225       </p>
226 <p>
227         Paul Mensonides, the developer of Boost PP and the BOOST_PP_IS_EMPTY macro
228         in that library, also wrote a better macro using variadic macros, for determining
229         whether or not a parameter is empty or not, which he published on the Internet
230         in response to a discussion about emptiness. This macro is also not perfect,
231         since there is no perfect solution prior to C++20, but will work correctly
232         with almost all input. I have adapted his code for VMD and developed my own
233         very slightly different code.
234       </p>
235 <p>
236         The macro is called <code class="computeroutput"><a class="link" href="../BOOST_VMD_IS_EMPTY.html" title="Macro BOOST_VMD_IS_EMPTY">BOOST_VMD_IS_EMPTY</a></code>
237         and will return 1 if its input is empty or 0 if its input is not empty. The
238         macro is a variadic macro which make take any input <a href="#ftn.variadic_macro_data.vmd_specific.vmd_test_empty.f0" class="footnote" name="variadic_macro_data.vmd_specific.vmd_test_empty.f0"><sup class="footnote">[1]</sup></a>.
239       </p>
240 <h5>
241 <a name="variadic_macro_data.vmd_specific.vmd_test_empty.h4"></a>
242         <span class="phrase"><a name="variadic_macro_data.vmd_specific.vmd_test_empty.macro_flaw_with_a_standard_c_com"></a></span><a class="link" href="vmd_specific.html#variadic_macro_data.vmd_specific.vmd_test_empty.macro_flaw_with_a_standard_c_com">Macro
243         Flaw with a standard C++ compiler</a>
244       </h5>
245 <p>
246         The one situation prior to C++20 where the macro does not work properly is
247         if its input resolves to a function-like macro name or a sequence of preprocessor
248         tokens ending with a function-like macro name and the function-like macro
249         takes two or more parameters.
250       </p>
251 <p>
252         Here is a simple example:
253       </p>
254 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</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">&gt;</span>
255
256 <span class="preprocessor">#define</span> <span class="identifier">FMACRO</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span><span class="identifier">y</span><span class="special">)</span> <span class="identifier">any_output</span>
257
258 <span class="identifier">BOOST_VMD_IS_EMPTY</span><span class="special">(</span><span class="identifier">FMACRO</span><span class="special">)</span>
259 <span class="identifier">BOOST_VMD_IS_EMPTY</span><span class="special">(</span><span class="identifier">some_input</span> <span class="identifier">FMACRO</span><span class="special">)</span>
260 </pre>
261 <p>
262         In the first case the name of a function-like macro is being passed to BOOST_VMD_IS_EMPTY
263         while in the second case a sequence of preprocessing tokens is being passed
264         to BOOST_VMD_IS_EMPTY ending with the name of a function-like macro. The
265         function-like macro also has two ( or more ) parameters. In both the cases
266         above a compiler error will result from the use of BOOST_VMD_IS_EMPTY.
267       </p>
268 <p>
269         Please note that these two problematical cases are not the same as passing
270         an invocation of a function-like macro name to BOOST_VMD_IS_EMPTY, as in
271       </p>
272 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</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">&gt;</span>
273
274 <span class="identifier">BOOST_VMD_IS_EMPTY</span><span class="special">(</span><span class="identifier">FMACRO</span><span class="special">(</span><span class="identifier">arg1</span><span class="special">,</span><span class="identifier">arg2</span><span class="special">))</span>
275 <span class="identifier">BOOST_VMD_IS_EMPTY</span><span class="special">(</span><span class="identifier">someinput</span> <span class="identifier">FMACRO</span><span class="special">(</span><span class="identifier">arg1</span><span class="special">,</span><span class="identifier">arg2</span><span class="special">))</span>
276 </pre>
277 <p>
278         which always works correctly, unless of course a particular function-like
279         macro invocation resolves to either of our two previous situations.
280       </p>
281 <p>
282         Another situation where the macro may not work properly is if the previously
283         mentioned function-like macro takes a single parameter but creates an error
284         when the argument passed is empty. An example of this would be:
285       </p>
286 <pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">FMACRO</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span> <span class="identifier">BOOST_PP_CAT</span><span class="special">(+,</span><span class="identifier">x</span> <span class="identifier">C</span><span class="special">);</span>
287 </pre>
288 <p>
289         When nothing is passed to FMACRO undefined behavior will occur since attempting
290         to concatenate '+' to ' C' is UB in C++ preprocessor terms.
291       </p>
292 <p>
293         So for a standard conforming compiler, prior to C++20, we have essentially
294         two corner cases where the BOOST_VMD_IS_EMPTY does not work and, when it
295         does not work it, produces a compiler error rather than an incorrect result.
296         Essentially what is desired for maximum safety is that we never pass input
297         ending with the name of a function-like macro name when testing for emptiness.
298       </p>
299 <h5>
300 <a name="variadic_macro_data.vmd_specific.vmd_test_empty.h5"></a>
301         <span class="phrase"><a name="variadic_macro_data.vmd_specific.vmd_test_empty.macro_flaw_with_visual_c"></a></span><a class="link" href="vmd_specific.html#variadic_macro_data.vmd_specific.vmd_test_empty.macro_flaw_with_visual_c">Macro
302         Flaw with Visual C++</a>
303       </h5>
304 <p>
305         The VC++ preprocessor is not a standard C++ conforming preprocessor in at
306         least two relevant situations to our discussion of emptiness. These situations
307         combine to create a single corner case which causes the BOOST_VMD_IS_EMPTY
308         macro to not work properly using VC++ when the input resolves to a function-like
309         macro name.
310       </p>
311 <p>
312         The first situation, related to our discussion of emptiness, where the VC++
313         preprocessor is not a standard C++ conforming preprocessor is that if a macro
314         taking 'n' number of parameters is invoked with 0 to 'n-1' parameters, the
315         compiler does not give an error, but only a warning.
316       </p>
317 <pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">FMACRO</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span><span class="identifier">y</span><span class="special">)</span> <span class="identifier">x</span> <span class="special">+</span> <span class="identifier">y</span>
318
319 <span class="identifier">FMACRO</span><span class="special">(</span><span class="number">1</span><span class="special">)</span>
320 </pre>
321 <p>
322         should give a compiler error, as it does when using a C++ standard-conforming
323         compiler, but when invoked using VC++ it only gives a warning and VC++ continues
324         macro substitution with 'y' as a placemarker preprocessing token. This non-standard
325         conforming action actually eliminates the case where BOOST_VMD_IS_EMPTY does
326         not work properly with a standard C++ conforming compiler. But of course
327         it has the potential of producing incorrect output in other macro processing
328         situations unrelated to the BOOST_VMD_IS_EMPTY invocation, where a compiler
329         error should occur.
330       </p>
331 <p>
332         A second general situation, related to our discussion of emptiness, where
333         the VC++ preprocessor is not a standard C++ conforming preprocessor is that
334         the expansion of a macro works incorrectly when the expanded macro is a function-like
335         macro name followed by a function-like macro invocation, in which case the
336         macro re-expansion is erroneously done more than once. This latter case can
337         be seen by this example:
338       </p>
339 <pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">FMACRO1</span><span class="special">(</span><span class="identifier">parameter</span><span class="special">)</span> <span class="identifier">FMACRO3</span> <span class="identifier">parameter</span><span class="special">()</span>
340 <span class="preprocessor">#define</span> <span class="identifier">FMACRO2</span><span class="special">()</span> <span class="special">()</span>
341 <span class="preprocessor">#define</span> <span class="identifier">FMACRO3</span><span class="special">()</span> <span class="number">1</span>
342
343 <span class="identifier">FMACRO1</span><span class="special">(</span><span class="identifier">FMACRO2</span><span class="special">)</span>
344
345 <span class="identifier">should</span> <span class="identifier">expand</span> <span class="identifier">to</span><span class="special">:</span>
346
347 <span class="identifier">FMACRO3</span><span class="special">()</span>
348
349 <span class="identifier">but</span> <span class="identifier">in</span> <span class="identifier">VC</span><span class="special">++</span> <span class="identifier">it</span> <span class="identifier">expands</span> <span class="identifier">to</span><span class="special">:</span>
350
351 <span class="number">1</span>
352 </pre>
353 <p>
354         where after initially expanding the macro to:
355       </p>
356 <pre class="programlisting"><span class="identifier">FMACRO3</span> <span class="identifier">FMACRO2</span><span class="special">()</span>
357 </pre>
358 <p>
359         VC++ erroneously rescans the sequence of preprocessing tokens more than once
360         rather than rescan just one more time for more macro names.
361       </p>
362 <p>
363         What these two particular preprocessor flaws in the VC++ compiler mean is
364         that although BOOST_VMD_IS_EMPTY does not fail with a compiler error in the
365         same case as with a standard C++ conforming compiler given previously, it
366         fails by giving the wrong result in another situation.
367       </p>
368 <p>
369         The failing situation is:
370       </p>
371 <p>
372         when the input to BOOST_VMD_IS_EMPTY resolves to only a function-like macro
373         name, and the function-like macro, when passed a single empty argument, expands
374         to a Boost PP tuple, BOOST_VMD_IS_EMPTY will erroneously return 1 when using
375         the Visual C++ compiler rather than either give a preprocessing error or
376         return 0.
377       </p>
378 <p>
379         Here is an example of the failure:
380       </p>
381 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</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">&gt;</span>
382
383 <span class="preprocessor">#define</span> <span class="identifier">FMACRO4</span><span class="special">()</span> <span class="special">(</span> <span class="identifier">any_number_of_tuple_elements</span> <span class="special">)</span>
384 <span class="preprocessor">#define</span> <span class="identifier">FMACRO5</span><span class="special">(</span><span class="identifier">param</span><span class="special">)</span> <span class="special">(</span> <span class="identifier">any_number_of_tuple_elements</span> <span class="special">)</span>
385 <span class="preprocessor">#define</span> <span class="identifier">FMACRO6</span><span class="special">(</span><span class="identifier">param1</span><span class="special">,</span><span class="identifier">param2</span><span class="special">)</span> <span class="special">(</span> <span class="identifier">any_number_of_tuple_elements</span> <span class="special">)</span>
386
387 <span class="identifier">BOOST_VMD_IS_EMPTY</span><span class="special">(</span><span class="identifier">FMACRO4</span><span class="special">)</span> <span class="comment">// erroneously returns 1, instead of 0</span>
388 <span class="identifier">BOOST_VMD_IS_EMPTY</span><span class="special">(</span><span class="identifier">FMACRO5</span><span class="special">)</span> <span class="comment">// erroneously returns 1, instead of 0</span>
389 <span class="identifier">BOOST_VMD_IS_EMPTY</span><span class="special">(</span><span class="identifier">FMACRO6</span><span class="special">)</span> <span class="comment">// erroneously returns 1, instead of generating a preprocessing error</span>
390 </pre>
391 <p>
392         As with a standard C++ conforming compiler prior to C++20, we have a rare
393         corner case where the BOOST_VMD_IS_EMPTY will not work properly, but unfortunately
394         in this very similar but even rarer corner case with VC++, we will silently
395         get an incorrect result rather than a compiler error.
396       </p>
397 <p>
398         I want to reiterate that for all compilers prior to C++20 there is no perfect
399         solution in C++ to the detection of emptiness even for a C++ compiler whose
400         preprocessor is completely conformant, which VC++ obviously is not.
401       </p>
402 <h5>
403 <a name="variadic_macro_data.vmd_specific.vmd_test_empty.h6"></a>
404         <span class="phrase"><a name="variadic_macro_data.vmd_specific.vmd_test_empty.testing_emptiness_in_c_20_mode"></a></span><a class="link" href="vmd_specific.html#variadic_macro_data.vmd_specific.vmd_test_empty.testing_emptiness_in_c_20_mode">Testing
405         emptiness in C++20 mode</a>
406       </h5>
407 <p>
408         A few compilers can currently operate in C++20 mode, by which I mean that
409         you can pass a compiler flag when compiling with such a compiler which enforces
410         the upcoming C++20 standard. One of the features of the C++20 standard is
411         the addition of a preprocessor construct called __VA_OPT__. Because of the
412         specification of how the __VA_OPT__ construct works in C++20, it is now possible
413         to have the BOOST_VMD_IS_EMPTY macro work perfectly to test for emptiness
414         without any of the flaws that exist in the macro for levels of the C++ standard
415         before C++20. But the macro will only do a 100% reliable test for emptiness
416         when the compiler is compiling in C++20 mode. For all levels of the C++ standard
417         before C++20, such as C++98, C++03, C++11, C++14, and C++17, the testing
418         for emptiness has the corner cases which prevent it from wroking perfectly
419         which have already been discussed.
420       </p>
421 <p>
422         Furthermore in C++20 mode it is possible that a compiler still does not yet
423         support the __VA_OPT__ construct, even though it is part of the C++20 standard.
424         Luckily it is possible to test whether or not a compiler supports the __VA_OPT__
425         construct in C++20 mode, and the macro implementation of BOOST_VMD_IS_EMPTY
426         does that before using the construct to provide a perfectly reliable implementation
427         for testing emptiness.
428       </p>
429 <p>
430         The result of all this is that when a compiler is compiling source using
431         the C++20 standard, and supports the C++20 __VA_OPT__ preprocessor construct,
432         the implementation provides a completely reliable way of testing for emptiness
433         using the BOOST_VMD_IS_EMPTY macro. Otherwise the BOOST_VMD_IS_EMPTY macro
434         has the corner cases previously discussed which make the macro less than
435         100% reliable in testing for emptiness. The good news of course is that more
436         compilers will be implementaing the C++20 standard and more C++ programmers
437         will be using the C++20 standard to compile their code.
438       </p>
439 <p>
440         The programmer may know whether the compiler is being used in C++20 mode
441         from the command line parameters he passes to the compiler, and the programmer
442         may know whether the compiler in C++20 mode supports the __VA_OPT__ construct
443         of C++20 from the compiler's documentation. But from the preprocessor programming
444         perspective it would be good to find out using a macro whether or not C++20
445         mode with the __VA_OPT__ construct is being used so that the BOOST_VMD_IS_EMPTY
446         macro can be considered completely reliable in testing for emptiness. Such
447         a macro does already exist in the Boost Preprocessor library, and it is called
448         BOOST_PP_VARIADIC_HAS_OPT. You can read the documentation for this macro
449         in the Boost Preprocessor library documentation, but I will give a quick
450         rundown of how this works here. The macro is a function-like macro taking
451         no parameters and returns 1 if the compiler is in C++20 mode and __VA_OPT__
452         is supported, otherwise returns 0. The header file needed to invoke the macro
453         as BOOST_PP_VARIADIC_HAS_OPT() is included as:
454       </p>
455 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</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">has_opt</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
456 </pre>
457 <p>
458         The programmer does not have to be compiling in C++20 mode to invoke the
459         BOOST_PP_VARIADIC_HAS_OPT macro. When the programmer is not in C++20 mode
460         invoking the macro always returns 0. When the programmer is in C++20 mode
461         invoking the macro returns 1 when the __VA_OPT__ construct is supported and
462         returns 0 when the __VA_OPT__ construct is not supported. It does this latter
463         step through clever preprocessor programming.
464       </p>
465 <h5>
466 <a name="variadic_macro_data.vmd_specific.vmd_test_empty.h7"></a>
467         <span class="phrase"><a name="variadic_macro_data.vmd_specific.vmd_test_empty.macro_flaw_conclusion"></a></span><a class="link" href="vmd_specific.html#variadic_macro_data.vmd_specific.vmd_test_empty.macro_flaw_conclusion">Macro
468         Flaw conclusion</a>
469       </h5>
470 <p>
471         With all of the above mentioned, the cases where BOOST_VMD_IS_EMPTY will
472         work incorrectly are very small, even with the erroneous VC++ preprocessor,
473         and I consider the macro worthwhile to use since it works correctly with
474         the vast majority of possible preprocessor input, and always works correctly
475         in C++20 mode with __VA_OPT__ preprocessor support.
476       </p>
477 <p>
478         The case where it will not work, with both a C++ standard conforming preprocessor
479         or with Visual C++, occurs when the name of a function-like macro is part
480         of the input to BOOST_VMD_IS_EMPTY. Obviously the macro should be used by
481         the preprocessor metaprogrammer when the possible input to it is constrained
482         to eliminate the erroneous case.
483       </p>
484 <p>
485         Furthermore, since emptiness can correctly be tested for in nearly every
486         situation, the BOOST_VMD_IS_EMPTY macro can be used internally when the preprocessor
487         metaprogrammer wants to return data from a macro and all or part of that
488         data could be empty.
489       </p>
490 <p>
491         Therefore I believe the BOOST_VMD_IS_EMPTY macro is quite useful, despite
492         the corner case flaws which makes it imperfect. Consequently I believe that
493         the preprocessor metaprogrammer can use the concept of empty preprocessor
494         data in the design of his own macros.
495       </p>
496 <h5>
497 <a name="variadic_macro_data.vmd_specific.vmd_test_empty.h8"></a>
498         <span class="phrase"><a name="variadic_macro_data.vmd_specific.vmd_test_empty.using_the_macro"></a></span><a class="link" href="vmd_specific.html#variadic_macro_data.vmd_specific.vmd_test_empty.using_the_macro">Using
499         the macro</a>
500       </h5>
501 <p>
502         The macro BOOST_VMD_IS_EMPTY is used internally throughout VMD and macro
503         programmers may find this macro useful in their own programming efforts despite
504         the slight flaw in the way that it works in pre C++20 mode.
505       </p>
506 <p>
507         You can use the general header file:
508       </p>
509 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</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">&gt;</span>
510 </pre>
511 <p>
512         or you can use the individual header file:
513       </p>
514 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</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">&gt;</span>
515 </pre>
516 <p>
517         for the BOOST_VMD_IS_EMPTY macro.
518       </p>
519 </div>
520 <div class="footnotes">
521 <br><hr style="width:100; text-align:left;margin-left: 0">
522 <div id="ftn.variadic_macro_data.vmd_specific.vmd_test_empty.f0" class="footnote"><p><a href="#variadic_macro_data.vmd_specific.vmd_test_empty.f0" class="para"><sup class="para">[1] </sup></a>
523           For VC++ 8 the input is not variadic data but a single parameter
524         </p></div>
525 </div>
526 </div>
527 <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
528 <td align="left"></td>
529 <td align="right"><div class="copyright-footer">Copyright &#169; 2010-2017 Tropic Software
530       East Inc</div></td>
531 </tr></table>
532 <hr>
533 <div class="spirit-nav">
534 <a accesskey="p" href="vmd_data_types.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_specific/vmd_constraints.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
535 </div>
536 </body>
537 </html>