]>
Commit | Line | Data |
---|---|---|
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 |