]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/preprocessor/doc/topics/variadic_macros.html
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / 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 <u style="font-weight: bold;"> Using a Tuple Instead of an Array<br>
140 </u>
141 <div>An array as a preprocessor data type is a two-element tuple where the
142 first element is the array size and the second element is a tuple which
143 constitutes the array data. Because a tuple knows its own size when the
144 compiler supports variadic macros, there is no reason to use the array preprocessor
145 data type as opposed to the tuple preprocessor data type; the tuple data
146 type now has all of the functionality which the array data type has and is
147 syntactically easier to use. With variadic macro support, which is now
148 officially part of the latest C++ standard, the preprocessor array data
149 type is essentially obsolete for conforming C++ compilers. Only if your
150 compiler does not support variadic macros is the preprocessor array data
151 type still useful.</div>
152 <u style="font-weight: bold;">Using Variadic Data</u>
153 <div>Variadic data exists in the
154 form of comma-separated preprocessor tokens. This is the case whether
155 the variadic data comes from the __VA_ARGS__ of a variadic macro, from
156 the conversion of a library's data type to variadic data, or the
157 manual construction of comma-separated preprocessing tokens by the
158 programmer writing a macro.<br>
159 <br>
160 The easiest way to work with
161 variadic data internally is to convert it to a library data type.
162 Library data types, whether an <i>array</i>, <i>list</i>,
163 <i>sequence</i>,
164 or <i>tuple</i>, have a rich set of functionality for
165 manipulating
166 data whereas
167 variadic data functionality in the library only allows one to access
168 the variadic data as a whole or to access a single token of the
169 variadic data at a time.<br>
170 <br>
171 The user of the library still may
172 choose to pass variadic data back into internal macros rather than
173 convert it to other library data types. There is no problem passing
174 variadic data as a whole to variadic macros as the last parameter of
175 the macro. However: <br>
176 <br>
177 <span style="font-weight: bold;">Attempting to pass
178 variadic data as a
179 whole directly into a non-variadic macro is not guaranteed to work and
180 may fail.<br>
181 </span><br>
182 This occurs because of a preprocessor weakness in a number
183 of compilers, currently most notably Visual C++. Even passing variadic
184 data as arguments to a non-variadic macro, when it is not represented
185 in
186 the form of  __VA_ARGS__, may fail with certain compilers.<br>
187 <br>
188 What follows are very simple examples, showing how variadic data can be
189 passed to a non-variadic macro.<br>
190 <br>
191 First an example of what NOT to do.<br>
192 </div>
193 <h4>Example<u> - Passing variadic data as a whole to a
194 non-variadic
195 macro. DO NOT DO.</u></h4>
196 <div class="code">
197 <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
198 style="font-weight: bold;"><span style="font-family: monospace;"></span></span>int xx = MACRO_ARG_2(VAR_MACRO(2,3));</pre>
199 </div>
200 <div> There are two ways to pass variadic data to a non-variadic
201 macro.
202 The
203 first of these is to pass the individual tokens of the variadic data
204 separately to the non-variadic macro using the BOOST_PP_VARIADIC_ELEM
205 macro in the library.<br>
206 </div>
207 <h4>Example<u> - Passing individual variadic data tokens to
208 a
209 non-variadic macro.<br>
210 </u></h4>
211 <div class="code">
212 <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>
213 </div>
214 <div>The second way is to use a macro in the library called
215 BOOST_PP_OVERLOAD.
216 This macro allows one to "overload" a variadic macro to non-variadic
217 macros of different numbers of parameters, using a common prefix.
218 </div>
219 <h4>Example<u> - Passing variadic data as a whole to
220 BOOST_PP_OVERLOAD
221 and on to a non-variadic macro.<br>
222 </u></h4>
223 <div class="code">
224 <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>
225 </div>
226 <br>
227 <div>Although these techniques will work when passing variadic
228 data to
229 non-variadic macros, it is much better and less problematical to
230 work internally with the existing library data types and to only use
231 variadic
232 macros as an interface for end-users when there is a need to have a
233 macro which takes a
234 variable number of parameters.<br>
235 </div>
236 <b>See</b> <b>Also</b><br>
237 <ul>
238 <li><a href="../ref/variadics.html">BOOST_PP_VARIADICS</a></li>
239 <li><a href="../headers/tuple.html">Tuple Macros</a><br>
240 </li>
241 <li><a href="../headers/variadic.html">Variadic
242 Macros<br>
243 </a></li>
244 <li><a href="../ref/array_enum.html">BOOST_PP_ARRAY_ENUM</a></li>
245 <li><a href="../ref/list_enum_r.html">BOOST_PP_LIST_ENUM</a></li>
246 <li><a href="../ref/seq_enum.html">BOOST_PP_SEQ_ENUM</a></li>
247 <li><a href="../ref/tuple_enum.html">BOOST_PP_TUPLE_ENUM</a></li>
248 <li><a href="../ref/overload.html">BOOST_PP_OVERLOAD</a></li>
249 </ul>
250 <hr size="1">
251 <div style="margin-left: 0px;"> <i>© Copyright
252 Edward Diener
253 2011,2013,2016</i> </div>
254 <div style="margin-left: 0px;">
255 <p><small>Distributed under the Boost Software License,
256 Version 1.0.
257 (See accompanying file <a href="../../../../LICENSE_1_0.txt">LICENSE_1_0.txt</a>
258 or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</small></p>
259 </div>
260
261
262 </body></html>