Imported Upstream version 1.72.0
[platform/upstream/boost.git] / libs / vmd / doc / vmd_empty.qbk
1 [/ 
2   (C) Copyright Edward Diener 2011-2015
3   Distributed under the Boost Software License, Version 1.0.
4   (See accompanying file LICENSE_1_0.txt or copy at
5   http://www.boost.org/LICENSE_1_0.txt).
6 ]
7
8 [section:vmd_test_empty Emptiness]
9
10 [heading Passing empty arguments]
11
12 It is possible to pass an empty argument to a macro.
13 The official terminology for this in the C++ standard is an argument 
14 "consisting of no preprocessing tokens".
15
16 Let us consider a number of cases without worrying too much
17 what the macro output represents.
18
19 Consider these two function-like macros:
20  
21  #define SMACRO() someoutput
22  #define EMACRO(x) otheroutput x
23  
24 The first macro takes no parameters so invoking it must always be done by
25  
26  SMACRO()
27  
28 and passing any arguments to it would be invalid.
29
30 The second macro takes a single parameter. it can be evoked as
31
32  EMACRO(somedata)
33  
34 but it also can be invoked as
35
36  EMACRO()
37  
38 In the second invocation of EMACRO we are passing an empty argument to the macro.
39 Similarly for any macro having 1 or more parameters, an empty argument
40 can be validly passed for any of the parameters, as in
41
42  #define MMACRO(x,y,z) x y z
43  
44  MMACRO(1,,2)
45  
46 An empty argument is an argument even if we are passing nothing.
47
48 Because an empty argument can be passed for a given parameter of
49 a macro does not mean one should do so. Any given macro will specify what each
50 argument to a macro should represent, and it is has normally been very rare to encounter 
51 a macro which specifies that an empty argument can logically be passed for a given
52 argument. But from the perspective of standard C++ it is perfectly valid to
53 pass an empty argument for a macro parameter.
54
55 The notion of passing empty arguments can be extended to passing empty data which
56 "consists of no preprocessing tokens" in slightly more complicated situations.
57 It is possible to pass empty data as an argument to a variadic macro in the form of 
58 variadic macro data, as in
59
60  #define VMACRO(x,...) x __VA_ARGS__
61  
62 invoked as
63
64  VMACRO(somedata,)
65  
66 Here one passes empty data as the variadic macro data and it is perfectly valid C++.
67 Please notice that this different from
68
69  VMACRO(somedata)
70  
71 which is not valid C++, prior to C++20, since something must be passed for the variadic argument.
72 In C++20 the above invocation is valid and is exactly the same as in our previous example of
73 'VMACRO(somedata,)' where one passes empty data as the variadic macro data. Similarly one could
74 invoke the macro as
75
76  VMACRO(somedata,vdata1,,vdata3)
77  
78 where one is passing variadic macro data but an element in the variadic macro data is empty.
79
80 Furthermore if we are invoking a macro which expects a Boost PP data type, such as
81 a tuple, we could also validly pass empty data for all or part of the data in a tuple,
82 as in
83
84  #define TMACRO(x,atuple) x atuple
85  
86  TMACRO(somedata,())
87  
88 In this case we are passing a 1 element tuple
89 where the single element itself is empty.
90  
91 or
92
93  TMACRO(somedata,(telem1,,telem2,teleem3))
94  
95 In this case we are passing a 4 element tuple where
96 the second element is empty.
97  
98 Again either invocation is valid C++ but it is not necessarily what the
99 designed of the macro has desired, even if in both cases the macro designer
100 has specified that the second parameter must be a tuple for the macro
101 to work properly.
102  
103 [heading Returning emptiness]
104
105 Similar to passing empty arguments in various ways to a macro,
106 the data which a macro returns ( or 'generates' may be a better term )
107 could be empty, in various ways. Again I am not necessarily promoting
108 this idea as a common occurrence of macro design but merely pointing it 
109 out as valid C++ preprocessing.
110
111  #define RMACRO(x,y,z)
112  
113  RMACRO(data1,data2,data3)
114  
115 It is perfectly valid C++ to return "nothing" from a macro invocation.
116 In fact a number of macros in Boost PP do that based on the preprocessor
117 metaprogramming logic of the macro, and are documented as such.
118
119 Similarly one could return nothing as part or all of a Boost PP
120 data type or even as part of variadic macro data.
121
122  #define TRETMACRO(x,y,z) ()
123  #define TRETMACRO1(x,y,z) (x,,y,,z)
124  #define VRETMACRO(x,y,z) x,,y,,z
125
126 Here again we are returning something but in terms of a Boost PP
127 tuple or in terms of variadic data, we have elements which are empty.
128
129 [heading Emptiness in preprocessor metaprogramming]
130
131 In the examples given above where "emptiness" in one form of another
132 is passed as arguments to a macro or returned from a macro, the examples
133 I have given were created as simplified as possible to illustrate my points.
134 In actual preprocessor metaprogramming, using Boost PP, where complicated logic 
135 is used to generate macro output based on the arguments to a macro, it might be
136 useful to allow and work with empty data if one were able to test for the fact 
137 that data was indeed empty.
138
139 [heading Testing for empty data]
140
141 Currently Boost PP has an undocumented macro for testing whether 
142 a parameter is empty of not, written without the use of variadic 
143 macros. The macro is called BOOST_PP_IS_EMPTY. The macro is by its nature flawed,
144 since there is no generalized way of determining whether or not a 
145 parameter is empty using the C++ preprocessor prior to C++20. But the macro will 
146 work given input limited in various ways or if the input is actually empty.
147
148 Paul Mensonides, the developer of Boost PP and the BOOST_PP_IS_EMPTY macro 
149 in that library, also wrote a better macro using variadic 
150 macros, for determining whether or not a parameter is empty or not, which
151 he published on the Internet in response to a discussion about emptiness.
152 This macro is also not perfect, since there is no perfect solution prior to C++20, 
153 but will work correctly with almost all input. I have adapted his code
154 for VMD and developed my own very slightly different code.
155
156 The macro is called [macroref BOOST_VMD_IS_EMPTY] and will return 1 if its input 
157 is empty or 0 if its input is not empty. The macro
158 is a variadic macro which make take any input
159 [footnote For VC++ 8 the input is not variadic data but a single parameter].
160
161 [heading Macro Flaw with a standard C++ compiler]
162
163 The one situation prior to C++20 where the macro does not work properly is if
164 its input resolves to a function-like macro name or a sequence of preprocessor tokens ending with 
165 a function-like macro name and the function-like macro takes two or more parameters.
166
167 Here is a simple example:
168
169  #include <boost/vmd/is_empty.hpp>
170  
171  #define FMACRO(x,y) any_output
172  
173  BOOST_VMD_IS_EMPTY(FMACRO)
174  BOOST_VMD_IS_EMPTY(some_input FMACRO)
175  
176 In the first case the name of a function-like macro is being passed to
177 BOOST_VMD_IS_EMPTY while in the second case a sequence of preprocessing tokens is being
178 passed to BOOST_VMD_IS_EMPTY ending with the name of a function-like macro.
179 The function-like macro also has two ( or more ) parameters. In both the 
180 cases above a compiler error will result from the use of BOOST_VMD_IS_EMPTY.
181
182 Please note that these two problematical cases are not the same as passing
183 an invocation of a function-like macro name to BOOST_VMD_IS_EMPTY, as in
184
185  #include <boost/vmd/is_empty.hpp>
186  
187  BOOST_VMD_IS_EMPTY(FMACRO(arg1,arg2))
188  BOOST_VMD_IS_EMPTY(someinput FMACRO(arg1,arg2))
189  
190 which always works correctly, unless of course a particular function-like macro
191 invocation resolves to either of our two previous situations.
192
193 Another situation where the macro may not work properly is if the previously mentioned
194 function-like macro takes a single parameter but creates an error when the argument
195 passed is empty. An example of this would be:
196
197  #define FMACRO(x) BOOST_PP_CAT(+,x C);
198  
199 When nothing is passed to FMACRO undefined behavior will occur since attempting to concatenate
200 '+' to ' C' is UB in C++ preprocessor terms.
201
202 So for a standard conforming compiler, prior to C++20, we have essentially two corner cases where
203 the BOOST_VMD_IS_EMPTY does not work and, when it does not work it, produces a
204 compiler error rather than an incorrect result. Essentially what is desired for maximum 
205 safety is that we never pass input ending with the name of a function-like macro name when
206 testing for emptiness.
207
208 [heading Macro Flaw with Visual C++]
209
210 The VC++ preprocessor is not a standard C++ conforming preprocessor in at least two 
211 relevant situations to our discussion of emptiness. These situations combine to create 
212 a single corner case which causes the BOOST_VMD_IS_EMPTY macro to not work properly 
213 using VC++ when the input resolves to a function-like macro name.
214
215 The first situation, related to our discussion of emptiness, where the VC++ preprocessor
216 is not a standard C++ conforming preprocessor is that if a macro taking 'n' number of parameters is invoked 
217 with 0 to 'n-1' parameters, the compiler does not give an error, but only a warning.
218
219  #define FMACRO(x,y) x + y
220  
221  FMACRO(1)
222  
223 should give a compiler error, as it does when using a C++ standard-conforming  
224 compiler, but when invoked using VC++ it only gives a warning
225 and VC++ continues macro substitution with 'y' as a placemarker preprocessing token.
226 This non-standard conforming action actually eliminates the case where BOOST_VMD_IS_EMPTY
227 does not work properly with a standard C++ conforming compiler. But of course it has the
228 potential of producing incorrect output in other macro processing situations unrelated
229 to the BOOST_VMD_IS_EMPTY invocation, where a compiler error should occur.
230
231 A second general situation, related to our discussion of emptiness, where the VC++ preprocessor
232 is not a standard C++ conforming preprocessor is that the expansion of a macro works incorrectly 
233 when the expanded macro is a function-like macro name followed by a function-like macro invocation, 
234 in which case the macro re-expansion is erroneously done more than once. This latter case can be 
235 seen by this example:
236
237  #define FMACRO1(parameter) FMACRO3 parameter()
238  #define FMACRO2() ()
239  #define FMACRO3() 1
240  
241  FMACRO1(FMACRO2)
242  
243  should expand to:
244  
245  FMACRO3()
246  
247  but in VC++ it expands to:
248  
249  1
250
251 where after initially expanding the macro to:
252
253  FMACRO3 FMACRO2()
254  
255 VC++ erroneously rescans the sequence of preprocessing tokens more than once rather than 
256 rescan just one more time for more macro names.
257
258 What these two particular preprocessor flaws in the VC++ compiler mean is that although
259 BOOST_VMD_IS_EMPTY does not fail with a compiler error in the same case as with 
260 a standard C++ conforming compiler given previously, it fails by giving
261 the wrong result in another situation. 
262
263 The failing situation is:
264
265 when the input to BOOST_VMD_IS_EMPTY resolves to only a function-like macro 
266 name, and the function-like macro, when passed a single empty argument, expands to 
267 a Boost PP tuple, BOOST_VMD_IS_EMPTY will erroneously return 1 when using the Visual C++ 
268 compiler rather than either give a preprocessing error or return 0.
269
270 Here is an example of the failure:
271
272  #include <boost/vmd/is_empty.hpp>
273  
274  #define FMACRO4() ( any_number_of_tuple_elements )
275  #define FMACRO5(param) ( any_number_of_tuple_elements )
276  #define FMACRO6(param1,param2) ( any_number_of_tuple_elements )
277  
278  BOOST_VMD_IS_EMPTY(FMACRO4) // erroneously returns 1, instead of 0
279  BOOST_VMD_IS_EMPTY(FMACRO5) // erroneously returns 1, instead of 0
280  BOOST_VMD_IS_EMPTY(FMACRO6) // erroneously returns 1, instead of generating a preprocessing error
281  
282 As with a standard C++ conforming compiler prior to C++20, we have a rare corner case where
283 the BOOST_VMD_IS_EMPTY will not work properly, but unfortunately in this very
284 similar but even rarer corner case with VC++, we will silently get an incorrect result
285 rather than a compiler error.
286
287 I want to reiterate that for all compilers prior to C++20 there is no perfect solution
288 in C++ to the detection of emptiness even for a C++ compiler whose preprocessor is completely
289 conformant, which VC++ obviously is not.
290
291 [heading Testing emptiness in C++20 mode]
292
293 A few compilers can currently operate in C++20 mode, by which I mean that you
294 can pass a compiler flag when compiling with such a compiler which enforces the
295 upcoming C++20 standard. One of the features of the C++20 standard is the
296 addition of a preprocessor construct called __VA_OPT__. Because of the
297 specification of how the __VA_OPT__ construct works in C++20, it is now possible
298 to have the BOOST_VMD_IS_EMPTY macro work perfectly to test for emptiness without
299 any of the flaws that exist in the macro for levels of the C++ standard before
300 C++20. But the macro will only do a 100% reliable test for emptiness when the
301 compiler is compiling in C++20 mode. For all levels of the C++ standard before
302 C++20, such as C++98, C++03, C++11, C++14, and C++17, the testing for emptiness
303 has the corner cases which prevent it from wroking perfectly which have already
304 been discussed.
305
306 Furthermore in C++20 mode it is possible that a compiler still does not yet
307 support the __VA_OPT__ construct, even though it is part of the C++20 standard.
308 Luckily it is possible to test whether or not a compiler supports the __VA_OPT__
309 construct in C++20 mode, and the macro implementation of BOOST_VMD_IS_EMPTY
310 does that before using the construct to provide a perfectly reliable
311 implementation for testing emptiness.
312
313 The result of all this is that when a compiler is compiling source using
314 the C++20 standard, and supports the C++20 __VA_OPT__ preprocessor construct,
315 the implementation provides a completely reliable way of testing for emptiness
316 using the BOOST_VMD_IS_EMPTY macro. Otherwise the BOOST_VMD_IS_EMPTY macro
317 has the corner cases previously discussed which make the macro less than
318 100% reliable in testing for emptiness. The good news of course is that
319 more compilers will be implementaing the C++20 standard and more C++
320 programmers will be using the C++20 standard to compile their code.
321
322 The programmer may know whether the compiler is being used in C++20 mode
323 from the command line parameters he passes to the compiler, and the programmer
324 may know whether the compiler in C++20 mode supports the __VA_OPT__ construct
325 of C++20 from the compiler's documentation. But from the preprocessor programming
326 perspective it would be good to find out using a macro whether or not C++20 mode
327 with the __VA_OPT__ construct is being used so that the BOOST_VMD_IS_EMPTY
328 macro can be considered completely reliable in testing for emptiness. Such a macro
329 does already exist in the Boost Preprocessor library, and it is called BOOST_PP_VARIADIC_HAS_OPT.
330 You can read the documentation for this macro in the Boost Preprocessor library
331 documentation, but I will give a quick rundown of how this works here. The macro
332 is a function-like macro taking no parameters and returns 1 if the compiler
333 is in C++20 mode and __VA_OPT__ is supported, otherwise returns 0. The header
334 file needed to invoke the macro as BOOST_PP_VARIADIC_HAS_OPT() is included as:
335
336  #include <boost/preprocessor/variadic/has_opt.hpp>
337  
338 The programmer does not have to be compiling in C++20 mode to invoke the
339 BOOST_PP_VARIADIC_HAS_OPT macro. When the programmer is not in C++20 mode invoking
340 the macro always returns 0. When the programmer is in C++20 mode invoking
341 the macro returns 1 when the __VA_OPT__ construct is supported and returns 0
342 when the __VA_OPT__ construct is not supported. It does this latter step through
343 clever preprocessor programming.
344
345 [heading Macro Flaw conclusion]
346
347 With all of the above mentioned, the cases where BOOST_VMD_IS_EMPTY will work 
348 incorrectly are very small, even with the erroneous VC++ preprocessor, 
349 and I consider the macro worthwhile to use since it works correctly with the vast 
350 majority of possible preprocessor input, and always works correctly in C++20
351 mode with __VA_OPT__ preprocessor support.
352
353 The case where it will not work, with both a C++ standard conforming preprocessor or
354 with Visual C++, occurs when the name of a function-like macro is part of the input
355 to BOOST_VMD_IS_EMPTY. Obviously the macro should be used by the preprocessor 
356 metaprogrammer when the possible input to it is constrained to eliminate the erroneous
357 case.
358
359 Furthermore, since emptiness can correctly be tested for in nearly every situation, the
360 BOOST_VMD_IS_EMPTY macro can be used internally when the preprocessor metaprogrammer wants to return data
361 from a macro and all or part of that data could be empty.
362
363 Therefore I believe the BOOST_VMD_IS_EMPTY macro is quite useful, despite the corner case flaws
364 which makes it imperfect. Consequently I believe that the preprocessor metaprogrammer
365 can use the concept of empty preprocessor data in the design of his own macros.
366
367 [heading Using the macro]
368
369 The macro BOOST_VMD_IS_EMPTY is used internally throughout VMD and macro programmers 
370 may find this macro useful in their own programming efforts despite the slight flaw 
371 in the way that it works in pre C++20 mode.
372
373 You can use the general header file:
374
375  #include <boost/vmd/vmd.hpp>
376  
377 or you can use the individual header file:
378
379  #include <boost/vmd/is_empty.hpp>
380  
381 for the BOOST_VMD_IS_EMPTY macro.
382
383 [endsect]