Updated for VC++ quirks and overload code example.

This commit is contained in:
Edward Diener
2016-04-11 14:24:38 -04:00
parent ee73989a21
commit e70abe7b49
2 changed files with 102 additions and 84 deletions

View File

@ -1,46 +1,58 @@
<html> <html>
<head> <head>
<meta content="text/html; charset=windows-1252" http-equiv="content-type">
<title>BOOST_PP_OVERLOAD</title> <title>BOOST_PP_OVERLOAD</title>
<link rel="stylesheet" type="text/css" href="../styles.css"> <link rel="stylesheet" type="text/css" href="../styles.css">
</head> </head>
<body> <body>
<div style="margin-left: 0px;"> The <b>BOOST_PP_OVERLOAD</b> variadic macro expands to the name of a non-variadic macro having a given number of parameters.<br> <div style="margin-left: 0px;"> The <b>BOOST_PP_OVERLOAD</b> variadic
</div> macro expands to the name of a non-variadic macro having a given number of
<h4>Usage</h4> parameters.<br>
<div class="code"> <b>BOOST_PP_OVERLOAD</b>(<i>prefix</i>,...) <a href="../topics/variadic_macros.html#VNotation" target="_self"><sup>(v)</sup></a><br> </div>
</div> <h4>Usage</h4>
<h4>Arguments</h4> <div class="code"> <b>BOOST_PP_OVERLOAD</b>(<i>prefix</i>,...) <a href="../topics/variadic_macros.html#VNotation"
<dl> target="_self"><sup>(v)</sup></a><br>
<dt>prefix<br> </div>
</dt><dd> <h4>Arguments</h4>
The prefix of the non-variadic macro name. <dl>
</dd><dt>...<br> <dt>prefix<br>
</dt><dd><i> </dt>
Variadic data</i>. The number of variadic data <dd> The prefix of the non-variadic macro name. </dd>
elements, as determined by BOOST_PP_VARIADIC_SIZE, is appended to the <dt>...<br>
prefix to form the output non-variadic macro name.<br> </dt>
</dd> <dd><i> Variadic data</i>. The number of variadic data
</dl> elements, as determined by BOOST_PP_VARIADIC_SIZE, is appended to the
<h4>Remarks</h4> prefix to form the output non-variadic macro name.<br>
<div> This macro creates a macro name which depends on the number of elements of variadic data. It should be used in the form of <br> </dd>
BOOST_PP_OVERLOAD(MACRO_NAME_,__VA_ARGS__)(__VA_ARGS__) in order to </dl>
call a non-variadic macro taking a given number of variadic data <h4>Remarks</h4>
elements as non-variadic arguments. In this way one can invoke a <div> This macro creates a macro name which depends on the number of
variadic macro with a variable number of parameters which calls one of elements of variadic data. It should be used in the form of <br>
a series of non-variadic macros doing very similar things. BOOST_PP_OVERLOAD(MACRO_NAME_,__VA_ARGS__)(__VA_ARGS__) in order to
</div><b>Requirements</b> call a non-variadic macro taking a given number of variadic data
<div> <b>Header:</b> &nbsp;<a href="../headers/facilities/overload.html">&lt;boost/preprocessor/facilities/overload.hpp&gt;</a> elements as non-variadic arguments. In this way one can invoke a
variadic macro with a variable number of parameters which calls one of
a series of non-variadic macros doing very similar things.
</div>
<b>Requirements</b>
<div> <b>Header:</b> &nbsp;<a href="../headers/facilities/overload.html">&lt;boost/preprocessor/facilities/overload.hpp&gt;</a>
</div>
<h4>Sample Code</h4>
<div>
<pre>#include &lt;<a href="../headers/facilities/overload.html">boost/preprocessor/facilities/overload.hpp</a>&gt;<br>#include <<a
href="../headers/cat.html">boost/preprocessor/cat.hpp</a>><br>#include <<a href="../headers/facilities/empty.html">boost/preprocessor/facilities/empty.hpp</a>><br>#include <<a
href="../headers/arithmetic/add.html">boost/preprocessor/arithmetic/add.hpp</a>><br><br>#define MACRO_1(number) MACRO_2(number,10)<br>#define MACRO_2(number1,number2) <a
href="add.html">BOOST_PP_ADD</a>(number1,number2)<br><br>#if !BOOST_PP_VARIADICS_MSVC<br><br>#define MACRO_ADD_NUMBERS(...) <a
href="overload.html">BOOST_PP_OVERLOAD</a>(MACRO_,__VA_ARGS__)(__VA_ARGS__)<br><br>#else<br><br>// or for Visual C++<br><br>#define MACRO_ADD_NUMBERS(...) \<br> <a
href="cat.html">BOOST_PP_CAT</a>(<a href="overload.html">BOOST_PP_OVERLOAD</a>(MACRO_,__VA_ARGS__)(__VA_ARGS__),<a
href="empty.html">BOOST_PP_EMPTY</a>())<br><br>#endif<br><br>MACRO_ADD_NUMBERS(5) // output is 15<br>MACRO_ADD_NUMBERS(3,6) // output is 9</pre>
</div> </div>
<h4>Sample Code</h4> <hr size="1">
<div> <div style="margin-left: 0px;"> <i></i><i><EFBFBD> Copyright Edward Diener 2011,2013,2016</i> </div>
<pre>#include &lt;<a href="../headers/facilities/overload.html">boost/preprocessor/facilities/overload.hpp</a>&gt;<br>#include &lt;<a href="../headers/cat.html">boost/preprocessor/cat.hpp</a>&gt;<br>#include &lt;<a href="../headers/facilities/empty.html">boost/preprocessor/facilities/empty.hpp</a>&gt;<br>#include &lt;<a href="../headers/arithmetic/add.html">boost/preprocessor/arithmetic/add.hpp</a>&gt;<br><br>#define MACRO_1(number) MACRO_2(number,10)<br>#define MACRO_2(number1,number2) <a href="add.html">BOOST_PP_ADD</a>(number1,number2)<br><br>#define MACRO_ADD_NUMBERS(...) <a href="overload.html">BOOST_PP_OVERLOAD</a>(MACRO_,__VA_ARGS__)(__VA_ARGS__)<br><br>// or for Visual C++<br><br>#define MACRO_ADD_NUMBERS(...) \<br> <a href="cat.html">BOOST_PP_CAT</a>(<a href="overload.html">BOOST_PP_OVERLOAD</a>(MACRO_,__VA_ARGS__)(__VA_ARGS__),<a href="empty.html">BOOST_PP_EMPTY</a>())<br><br>MACRO_ADD_NUMBERS(5) // output is 15<br>MACRO_ADD_NUMBERS(3,6) // output is 9<br></pre> <div style="margin-left: 0px;">
</div>
<hr size="1">
<div style="margin-left: 0px;"> <i></i><i><EFBFBD> Copyright Edward Diener 2011,2013</i> </div>
<div style="margin-left: 0px;">
<p><small>Distributed under the Boost Software License, Version 1.0. <p><small>Distributed under the Boost Software License, Version 1.0.
(See accompanying file <a href="../../../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> (See accompanying file <a href="../../../../LICENSE_1_0.txt">LICENSE_1_0.txt</a>
or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</small></p> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</small></p>
</div> </div>
</body>
</html> </body></html>

View File

@ -1,40 +1,37 @@
<html> <html>
<head> <head>
<meta content="text/html; charset=windows-1252" http-equiv="content-type">
<title>variadic_macros.html</title> <title>variadic_macros.html</title>
<link rel="stylesheet" type="text/css" href="../styles.css"> <link rel="stylesheet" type="text/css" href="../styles.css">
<style> <style>
u { font-weight: normal; text-decoration: none; } u { font-weight: normal; text-decoration: none; }
</style> </style>
</head> </head>
<body> <body>
<h4>Variadic Macros</h4> <h4>Variadic Macros</h4>
<div> Variadic macros are supported by a number of compilers. <div> Variadic macros are supported by a number of compilers. They are
They are macros of the form: </div>
macros of the form: <div class="code">
</div>
<div class="code">
<pre>#define SOME_MACRO(ZeroOrMoreParameters,...) macro expansion possible specifying __VA_ARGS__</pre> <pre>#define SOME_MACRO(ZeroOrMoreParameters,...) macro expansion possible specifying __VA_ARGS__</pre>
</div> </div>
<div> The '...' in the parameter list represents the variadic <div> The '...' in the parameter list represents the variadic data when the
data when the macro is invoked and the __VA_ARGS__ in the expansion macro is invoked and the __VA_ARGS__ in the expansion represents the
represents the variadic data in the expansion of the macro. Variadic variadic data in the expansion of the macro. Variadic data is of the form
data is of the form of 1 or more preprocessor tokens separated by of 1 or more preprocessor tokens separated by commas.<br>
commas.<br>
<br> <br>
The '...' must be the last parameter in the macro definition and there The '...' must be the last parameter in the macro definition and there may
may be 0 or more non-variadic parameters preceding it.<br> be 0 or more non-variadic parameters preceding it.<br>
<br> <br>
In the expansion of the macro __VA_ARGS__ may be specified 0 or more In the expansion of the macro __VA_ARGS__ may be specified 0 or more times
times to represent the variadic data. The variadic data in the to represent the variadic data. The variadic data in the expansion is a
expansion is a comma separated list of preprocessor tokens representing comma separated list of preprocessor tokens representing the variadic data
the variadic data which the invoker of the macro enters as the last which the invoker of the macro enters as the last arguments to the macro.<br>
arguments to the macro.<br>
</div> </div>
<h4>Example<u> - Creating and invoking a variadic macro.</u></h4> <h4>Example<u> - Creating and invoking a variadic macro.</u></h4>
<div class="code"> <div class="code">
<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> <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>
</div> </div>
<u> <span style="font-weight: bold;">Preprocessor <u> <span style="font-weight: bold;">Preprocessor
Library Support<br> Library Support<br>
</span></u> </span></u>
<div>The library offers support for variadic macros for those <div>The library offers support for variadic macros for those
@ -56,7 +53,15 @@
When BOOST_PP_VARIADICS is 1, the library offers some extended When BOOST_PP_VARIADICS is 1, the library offers some extended
functionality functionality
by using variadic macros, and also offers extended support for working by using variadic macros, and also offers extended support for working
with variadic data.<br> with variadic data.<br><br>
<a name="vmvcquirk"></a>Visual C++ has a
few quirks related to variadic macros which require the end-user to code
slightly differently. When BOOST_PP_VARIADICS is 1 and Visual C++ is the
compiler BOOST_PP_VARIADICS_MSVC is 1, else when BOOST_PP_VARIADICS is 1
and Visual C++ is not the compiler BOOST_PP_VARIADICS_MSVC is 0. When
BOOST_PP_VARIADICS is 0 then BOOST_PP_VARIADICS_MSVC is not defined.
In this way the end-user, when using variadic macros, can test for the
presence of Visual C++ as the compiler and code accordingly.<br>
<br> <br>
Support for working with variadic Support for working with variadic
data is largely centered on being able to convert variadic data to data is largely centered on being able to convert variadic data to
@ -64,7 +69,7 @@
functionality for working with those Boost preprocessor library data functionality for working with those Boost preprocessor library data
types is much greater than that for working with variadic data directly.<br> types is much greater than that for working with variadic data directly.<br>
</div> </div>
<a name="VNotation"></a> <a name="VNotation"></a>
<h4>Notation For Variadic Macros<br> <h4>Notation For Variadic Macros<br>
</h4> </h4>
<div>In the documentation, headers which have variadic macros, <div>In the documentation, headers which have variadic macros,
@ -131,7 +136,7 @@
use this variadic data reliably as arguments to other macros, one needs use this variadic data reliably as arguments to other macros, one needs
variadic macro support.<br> variadic macro support.<br>
</div> </div>
<u style="font-weight: bold;"> Using a Tuple Instead of an Array<br> <u style="font-weight: bold;"> Using a Tuple Instead of an Array<br>
</u> </u>
<div>An array as a preprocessor data type is a two-element tuple where the <div>An array as a preprocessor data type is a two-element tuple where the
first element is the array size and the second element is a tuple which first element is the array size and the second element is a tuple which
@ -144,7 +149,7 @@
type is essentially obsolete for conforming C++ compilers. Only if your type is essentially obsolete for conforming C++ compilers. Only if your
compiler does not support variadic macros is the preprocessor array data compiler does not support variadic macros is the preprocessor array data
type still useful.</div> type still useful.</div>
<u style="font-weight: bold;">Using Variadic Data</u> <u style="font-weight: bold;">Using Variadic Data</u>
<div>Variadic data exists in the <div>Variadic data exists in the
form of comma-separated preprocessor tokens. This is the case whether form of comma-separated preprocessor tokens. This is the case whether
the variadic data comes from the __VA_ARGS__ of a variadic macro, from the variadic data comes from the __VA_ARGS__ of a variadic macro, from
@ -169,7 +174,7 @@
variadic data as a whole to variadic macros as the last parameter of variadic data as a whole to variadic macros as the last parameter of
the macro. However: <br> the macro. However: <br>
<br> <br>
<span style="font-weight: bold;">Attempting to pass <span style="font-weight: bold;">Attempting to pass
variadic data as a variadic data as a
whole directly into a non-variadic macro is not guaranteed to work and whole directly into a non-variadic macro is not guaranteed to work and
may fail.<br> may fail.<br>
@ -178,7 +183,7 @@
of compilers, currently most notably Visual C++. Even passing variadic of compilers, currently most notably Visual C++. Even passing variadic
data as arguments to a non-variadic macro, when it is not represented data as arguments to a non-variadic macro, when it is not represented
in in
the form of&nbsp; __VA_ARGS__, may fail with certain compilers.<br> the form of<EFBFBD> __VA_ARGS__, may fail with certain compilers.<br>
<br> <br>
What follows are very simple examples, showing how variadic data can be What follows are very simple examples, showing how variadic data can be
passed to a non-variadic macro.<br> passed to a non-variadic macro.<br>
@ -188,9 +193,9 @@
<h4>Example<u> - Passing variadic data as a whole to a <h4>Example<u> - Passing variadic data as a whole to a
non-variadic non-variadic
macro. DO NOT DO.</u></h4> macro. DO NOT DO.</u></h4>
<div class="code"> <div class="code">
<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 <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
style="font-weight: bold;"><span style="font-family: monospace;"></span></span>int xx = MACRO_ARG_2(VAR_MACRO(2,3));</pre> style="font-weight: bold;"><span style="font-family: monospace;"></span></span>int xx = MACRO_ARG_2(VAR_MACRO(2,3));</pre>
</div> </div>
<div> There are two ways to pass variadic data to a non-variadic <div> There are two ways to pass variadic data to a non-variadic
macro. macro.
@ -203,7 +208,7 @@ style="font-weight: bold;"><span style="font-family: monospace;"></span></span>i
a a
non-variadic macro.<br> non-variadic macro.<br>
</u></h4> </u></h4>
<div class="code"> <div class="code">
<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> <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>
</div> </div>
<div>The second way is to use a macro in the library called <div>The second way is to use a macro in the library called
@ -215,7 +220,7 @@ style="font-weight: bold;"><span style="font-family: monospace;"></span></span>i
BOOST_PP_OVERLOAD BOOST_PP_OVERLOAD
and on to a non-variadic macro.<br> and on to a non-variadic macro.<br>
</u></h4> </u></h4>
<div class="code"> <div class="code">
<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> <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>
</div> </div>
<br> <br>
@ -230,27 +235,28 @@ style="font-weight: bold;"><span style="font-family: monospace;"></span></span>i
</div> </div>
<b>See</b> <b>Also</b><br> <b>See</b> <b>Also</b><br>
<ul> <ul>
<li><a href="../ref/variadics.html">BOOST_PP_VARIADICS</a></li> <li><a href="../ref/variadics.html">BOOST_PP_VARIADICS</a></li>
<li><a href="../headers/tuple.html">Tuple Macros</a><br> <li><a href="../headers/tuple.html">Tuple Macros</a><br>
</li> </li>
<li><a href="../headers/variadic.html">Variadic <li><a href="../headers/variadic.html">Variadic
Macros<br> Macros<br>
</a></li> </a></li>
<li><a href="../ref/array_enum.html">BOOST_PP_ARRAY_ENUM</a></li> <li><a href="../ref/array_enum.html">BOOST_PP_ARRAY_ENUM</a></li>
<li><a href="../ref/list_enum_r.html">BOOST_PP_LIST_ENUM</a></li> <li><a href="../ref/list_enum_r.html">BOOST_PP_LIST_ENUM</a></li>
<li><a href="../ref/seq_enum.html">BOOST_PP_SEQ_ENUM</a></li> <li><a href="../ref/seq_enum.html">BOOST_PP_SEQ_ENUM</a></li>
<li><a href="../ref/tuple_enum.html">BOOST_PP_TUPLE_ENUM</a></li> <li><a href="../ref/tuple_enum.html">BOOST_PP_TUPLE_ENUM</a></li>
<li><a href="../ref/overload.html">BOOST_PP_OVERLOAD</a></li> <li><a href="../ref/overload.html">BOOST_PP_OVERLOAD</a></li>
</ul> </ul>
<hr size="1"> <hr size="1">
<div style="margin-left: 0px;"> <i><EFBFBD> Copyright <div style="margin-left: 0px;"> <i><EFBFBD> Copyright
Edward Diener Edward Diener
2011,2013</i> </div> 2011,2013,2016</i> </div>
<div style="margin-left: 0px;"> <div style="margin-left: 0px;">
<p><small>Distributed under the Boost Software License, <p><small>Distributed under the Boost Software License,
Version 1.0. Version 1.0.
(See accompanying file <a href="../../../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> (See accompanying file <a href="../../../../LICENSE_1_0.txt">LICENSE_1_0.txt</a>
or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</small></p> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</small></p>
</div> </div>
</body>
</html>
</body></html>