Imported Upstream version 1.72.0
[platform/upstream/boost.git] / libs / preprocessor / doc / topics / variadic_macros.html
1 <html>
2   <head>
3     <meta  content="text/html; charset=windows-1252"  http-equiv="content-type">
4     <title>variadic_macros.html</title>
5     <link  rel="stylesheet"  type="text/css"  href="../styles.css">
6     <style>
7     u { font-weight: normal; text-decoration: none; }
8     </style>
9   </head>
10   <body>
11     <h4>Variadic Macros</h4>
12     <div> Variadic macros are supported by a number of compilers. They are
13       macros of the form: </div>
14     <div  class="code">
15       <pre>#define SOME_MACRO(ZeroOrMoreParameters,...) macro expansion possible specifying __VA_ARGS__</pre>
16     </div>
17     <div> The '...' in the parameter list represents the variadic data when the
18       macro is invoked and the __VA_ARGS__ in the expansion represents the
19       variadic data in the expansion of the macro. Variadic data is of the form
20       of 1 or more preprocessor tokens separated by commas.<br>
21       <br>
22       The '...' must be the last parameter in the macro definition and there may
23       be 0 or more non-variadic parameters preceding it.<br>
24       <br>
25       In the expansion of the macro __VA_ARGS__ may be specified 0 or more times
26       to represent the variadic data. The variadic data in the expansion is a
27       comma separated list of preprocessor tokens representing the variadic data
28       which the invoker of the macro enters as the last arguments to the macro.<br>
29     </div>
30     <h4>Example<u> - Creating and invoking a variadic macro.</u></h4>
31     <div  class="code">
32       <pre>#define INITIALIZE_INT_ARRAY(array_name,...) \ <br> static int array_name[] = { __VA_ARGS__ }; \ <br> /**/<br><br> INITIALIZE_INT_ARRAY(myname,45,789,33510,9346,2)</pre>
33     </div>
34     <u> <span  style="font-weight: bold;">Preprocessor
35         Library Support<br>
36       </span></u>
37     <div>The library offers support for variadic macros for those
38       compilers
39       which support the feature. The library can automatically detect whether
40       a compiler supports variadic macros and sets the macro
41       BOOST_PP_VARIADICS accordingly to 1 if the compiler supports variadic
42       macros or 0 if the compiler does not support variadic macros.<br>
43       <br>
44       The end-user can #define BOOST_PP_VARIADICS to 1 or 0 himself in a
45       translation unit, before including any preprocessor header files, to
46       prevent the library from attempting to detect whether the compiler
47       supports variadic macros. This has the effect of manually turning on or
48       off variadic macro support in the library. Of course if one manually
49       turns on variadic macro support in the library, and one's compiler does
50       not support variadic macros, functionality in the library which uses
51       variadic macros will fail with error messages from the compiler.<br>
52       <br>
53       When BOOST_PP_VARIADICS is 1, the library offers some extended
54       functionality
55       by using variadic macros, and also offers extended support for working
56       with variadic data.<br><br>
57       <a  name="vmvcquirk"></a>Visual C++ has a 
58       few quirks related to variadic macros which require the end-user to code
59       slightly differently. When BOOST_PP_VARIADICS is 1 and Visual C++ is the
60       compiler BOOST_PP_VARIADICS_MSVC is 1, else when BOOST_PP_VARIADICS is 1
61       and Visual C++ is not the compiler BOOST_PP_VARIADICS_MSVC is 0. When
62       BOOST_PP_VARIADICS is 0 then BOOST_PP_VARIADICS_MSVC is not defined.
63       In this way the end-user, when using variadic macros, can test for the
64       presence of Visual C++ as the compiler and code accordingly.<br>
65       <br>
66       Support for working with variadic
67       data is largely centered on being able to convert variadic data to
68       other library data types, since the
69       functionality for working with those Boost preprocessor library data
70       types is much greater than that for working with variadic data directly.<br>
71     </div>
72     <a  name="VNotation"></a>
73     <h4>Notation For Variadic Macros<br>
74     </h4>
75     <div>In the documentation, headers which have variadic macros,
76       and
77       variadic macros themselves, have a notation of '(v)' appended to them.
78       For the variadic macros themselves this signifies that
79       BOOST_PP_VARIADICS must be 1 for those variadic macros to be usable.
80       For variadic macros which have a non-variadic equivalent, the
81       non-variadic equivalent will be used if BOOST_PP_VARIADICS is set to 0.
82     </div>
83     <h4>Extended Functionality Using Variadic Macros<br>
84     </h4>
85     <div>Some macros in the library offer extended
86       functionality through the use of variadic macros.<br>
87       <br>
88       The variadic macro version offers the same functionality
89       as the non-variadic version, but because of the ability of the variadic
90       parameters to encompass a variable number of arguments, it also offers
91       an enhanced syntax using the same macro name.<br>
92       <br>
93       The macros in the library which offer this enhanced functionality are
94       all
95       centered on <i>tuple</i> manipulation. With variadic
96       macros it is
97       possible to
98       manipulate tuples without having to know the size of the tuple. So
99       while the invoker can still specify the size when using tuple macro
100       functionality, there are variadic versions of each of the tuple macros,
101       with the exact same name as the non-variadic macro, where the size need
102       not be specified.<br>
103     </div>
104     <h4>Extended Support For Variadic Data</h4>
105     <div>The library offers extended support for working with
106       variadic data
107       which goes beyond the functionality offered by the C++ specification
108       for variadic macros. It does this through preprocessor programming and
109       by using some of the other functionality in the library itself. Header
110       and macro names
111       in the library which offer extended support for working with variadic
112       data, and need the compiler to support variadic macros, are marked with
113       a (v)<sup> </sup>to indicate a variadic macro.<br>
114       <br>
115       The form of the functionality which the library offers is centered on
116       two macros which work with variadic data itself, and a set of macros
117       which convert between variadic data and other library data
118       types.<br>
119       <br>
120       The two macros are BOOST_PP_VARIADIC_ELEM and BOOST_PP_VARIADIC_SIZE,
121       which respectively return a particular token of variadic data and the
122       number of tokens of variadic data.<br>
123       <br>
124       The macros for converting variadic data to the library's data types are
125       BOOST_PP_VARIADIC_TO_ARRAY, BOOST_PP_VARIADIC_TO_LIST,
126       BOOST_PP_VARIADIC_TO_SEQ, and BOOST_PP_VARIADIC_TO_TUPLE.<br>
127       <br>
128       All of these macros need compiler support for variadic data and only
129       exist if BOOST_PP_VARIADICS is 1. <br>
130       <br>
131       The remaining four macros, which convert from a library data type
132       to comma-separated preprocessor tokens, which is the form of
133       variadic data, do not need compiler support for variadic
134       macros. These functions are BOOST_PP_ARRAY_ENUM, BOOST_PP_LIST_ENUM,
135       BOOST_PP_SEQ_ENUM, and BOOST_PP_TUPLE_ENUM. However if one wishes to
136       use this variadic data reliably as arguments to other macros, one needs
137       variadic macro support.<br>
138     </div>
139     <h4>C++20 Support For Variadic Macros</h4>
140     <div>
141       In the C++20 specification there is a new construct which can be
142       used in the expansion of a variadic macro, called __VA_OPT__. This
143       construct when used in the expansion of a variadic macro is followed
144       by an opening paranthesis ('('), preprocessor data, and a closing
145       parenthesis ('}'). When the variadic data passed by the invocation
146       of a variadic macro is empty, this new construct expands to nothing.
147       When the variadic data passed by the invocation of a variadic macro
148       is not empty, this new construct expands to the preprocessor data
149       between its opening and closing parentheses.
150       <br><br>
151       This library offers support for this new C++20 construct by automatically
152       detecting whether this new construct is supported by the compiler's
153       preprocessor when using the library. The library macro which detects
154       support for the __VA_OPT__ construct is called BOOST_PP_VARIADIC_HAS_OPT.
155       This is a function-like macro which takes no parameters and returns
156       1 if the compiler is working in C++20 mode and supports the __VA_OPT__
157       construct, while otherwise it returns 0.
158       <br>
159     </div>
160     <u  style="font-weight: bold;"> Using a Tuple Instead of an Array<br>
161     </u>
162     <div>An array as a preprocessor data type is a two-element tuple where the
163       first element is the array size and the second element is a tuple which
164       constitutes the array data. Because a tuple knows its own size when the
165       compiler supports variadic macros, there is no reason to use the array preprocessor
166       data type as opposed to the tuple preprocessor data type; the tuple data
167       type now has all of the functionality which the array data type has and is
168       syntactically easier to use. With variadic macro support, which is now
169       officially part of the latest C++ standard, the preprocessor array data
170       type is essentially obsolete for conforming C++ compilers. Only if your
171       compiler does not support variadic macros is the preprocessor array data
172       type still useful.</div>
173     <u  style="font-weight: bold;">Using Variadic Data</u>
174     <div>Variadic data exists in the
175       form of comma-separated preprocessor tokens. This is the case whether
176       the variadic data comes from the __VA_ARGS__ of a variadic macro, from
177       the conversion of a library's data type to variadic data, or the
178       manual construction of comma-separated preprocessing tokens by the
179       programmer writing a macro.<br>
180       <br>
181       The easiest way to work with
182       variadic data internally is to convert it to a library data type.
183       Library data types, whether an <i>array</i>, <i>list</i>,
184       <i>sequence</i>,
185       or <i>tuple</i>, have a rich set of functionality for
186       manipulating
187       data whereas
188       variadic data functionality in the library only allows one to access
189       the variadic data as a whole or to access a single token of the
190       variadic data at a time.<br>
191       <br>
192       The user of the library still may
193       choose to pass variadic data back into internal macros rather than
194       convert it to other library data types. There is no problem passing
195       variadic data as a whole to variadic macros as the last parameter of
196       the macro. However: <br>
197       <br>
198       <span  style="font-weight: bold;">Attempting to pass
199         variadic data as a
200         whole directly into a non-variadic macro is not guaranteed to work and
201         may fail.<br>
202       </span><br>
203       This occurs because of a preprocessor weakness in a number
204       of compilers, currently most notably Visual C++. Even passing variadic
205       data as arguments to a non-variadic macro, when it is not represented
206       in
207       the form of  __VA_ARGS__, may fail with certain compilers.<br>
208       <br>
209       What follows are very simple examples, showing how variadic data can be
210       passed to a non-variadic macro.<br>
211       <br>
212       First an example of what NOT to do.<br>
213     </div>
214     <h4>Example<u> - Passing variadic data as a whole to a
215         non-variadic
216         macro. DO NOT DO.</u></h4>
217     <div  class="code">
218       <pre>#define MACRO_ARG_2(x,y) BOOST_PP_ADD(x,y)<br>#define VAR_MACRO(...) __VA_ARGS__<br><br>/* The following should not be done and is not guaranteed to work with compilers. */<br><br><span
219  style="font-weight: bold;"><span  style="font-family: monospace;"></span></span>int xx = MACRO_ARG_2(VAR_MACRO(2,3));</pre>
220     </div>
221     <div> There are two ways to pass variadic data to a non-variadic
222       macro.
223       The
224       first of these is to pass the individual tokens of the variadic data
225       separately to the non-variadic macro using the BOOST_PP_VARIADIC_ELEM
226       macro in the library.<br>
227     </div>
228     <h4>Example<u> - Passing individual variadic data tokens to
229         a
230         non-variadic macro.<br>
231       </u></h4>
232     <div  class="code">
233       <pre>#define MACRO_ARG_2(x,y) BOOST_PP_ADD(x,y)<br>#define VAR_MACRO(...) __VA_ARGS__<br><br>/* The following will work correctly */<br><br>int xx = MACRO_ARG_2<br> (<br> BOOST_PP_VARIADIC_ELEM(0,VAR_MACRO(2,3)),<br> BOOST_PP_VARIADIC_ELEM(1,VAR_MACRO(2,3))<br> );</pre>
234     </div>
235     <div>The second way is to use a macro in the library called
236       BOOST_PP_OVERLOAD.
237       This macro allows one to "overload" a variadic macro to non-variadic
238       macros of different numbers of parameters, using a common prefix.
239     </div>
240     <h4>Example<u> - Passing variadic data as a whole to
241         BOOST_PP_OVERLOAD
242         and on to a non-variadic macro.<br>
243       </u></h4>
244     <div  class="code">
245       <pre>#define MACRO_ARG_2(x,y) BOOST_PP_ADD(x,y)<br>#define VAR_MACRO(...) __VA_ARGS__<br><br>/* The following will work correctly */<br><br>int xx = BOOST_PP_OVERLOAD(MACRO_ARG_,VAR_MACRO(2,3))(VAR_MACRO(2,3));<br><br>/* For Visual C++ it is necessary to do this */<br><br>int xx = <br>BOOST_PP_CAT(BOOST_PP_OVERLOAD(MACRO_ARG_,VAR_MACRO(2,3))(VAR_MACRO(2,3)),BOOST_PP_EMPTY());</pre>
246     </div>
247     <br>
248     <div>Although these techniques will work when passing variadic
249       data to
250       non-variadic macros, it is much better and less problematical to
251       work internally with the existing library data types and to only use
252       variadic
253       macros as an interface for end-users when there is a need to have a
254       macro which takes a
255       variable number of parameters.<br>
256     </div>
257     <b>See</b> <b>Also</b><br>
258     <ul>
259       <li><a  href="../ref/variadics.html">BOOST_PP_VARIADICS</a></li>
260       <li><a  href="../headers/tuple.html">Tuple Macros</a><br>
261       </li>
262       <li><a  href="../headers/variadic.html">Variadic
263           Macros<br>
264         </a></li>
265       <li><a  href="../ref/array_enum.html">BOOST_PP_ARRAY_ENUM</a></li>
266       <li><a  href="../ref/list_enum_r.html">BOOST_PP_LIST_ENUM</a></li>
267       <li><a  href="../ref/seq_enum.html">BOOST_PP_SEQ_ENUM</a></li>
268       <li><a  href="../ref/tuple_enum.html">BOOST_PP_TUPLE_ENUM</a></li>
269       <li><a  href="../ref/overload.html">BOOST_PP_OVERLOAD</a></li>
270     </ul>
271     <hr  size="1">
272     <div  style="margin-left: 0px;"> <i>© Copyright
273         Edward Diener
274         2011,2013,2016</i> </div>
275     <div  style="margin-left: 0px;">
276       <p><small>Distributed under the Boost Software License,
277           Version 1.0.
278           (See accompanying file <a  href="../../../../LICENSE_1_0.txt">LICENSE_1_0.txt</a>
279           or copy at <a  href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</small></p>
280     </div>
281   </body>
282 </html>