Explanations about using tuples rather than arrays with variadic macro support.

This commit is contained in:
Edward Diener
2013-12-05 17:43:48 -05:00
parent 58cf4ccba9
commit 6978c83372
3 changed files with 324 additions and 322 deletions

View File

@ -5,33 +5,29 @@
</head> </head>
<body> <body>
<h4>Arrays</h4> <h4>Arrays</h4>
<div> <div> An <i>array</i> is a data structure consisting of a two-element <i>tuple</i>.&nbsp;
An <i>array</i> is a data structure consisting of a two-element <i>tuple</i>.&nbsp;
The first element is the number of elements in the <i>array</i>.&nbsp; The first element is the number of elements in the <i>array</i>.&nbsp;
The second element is another <i>tuple</i> of the elements in the <i>array</i>.&nbsp; The second element is another <i>tuple</i> of the elements in the <i>array</i>.&nbsp;
For example, For example, </div>
</div> <div class="code"> (<i>3</i>, (<i>a</i>, <i>b</i>, <i>c</i>)) </div>
<div class="code"> <div> ...is an <i>array</i> of <i>3</i> elements--<i>a</i>, <i>b</i>, and
(<i>3</i>, (<i>a</i>, <i>b</i>, <i>c</i>)) <i>c</i>. </div>
</div> <div> The primary strength of <i>arrays</i> is that they store their own
<div> size.&nbsp; Because of this, access to elements does not require the
...is an <i>array</i> of <i>3</i> elements--<i>a</i>, <i>b</i>, and <i>c</i>. size.&nbsp; It only requires that an element exists at a certain index. </div>
</div> <div> This allows macro parameters to be variable in size and allows data
<div> states to change size without the user explicitly keeping track of the
The primary strength of <i>arrays</i> is that they store their own size.&nbsp; size independently.</div>
Because of this, access to elements does not require the size.&nbsp; <div>With variadic macro support a <i>tuple </i>has all of the
It only requires that an element exists at a certain index. functionality as an <i>array</i>, knows its own size, and is easier
</div> syntactically to use. Because of that an <i>array</i> should be used, as
<div> opposed to a <i>tuple</i>, only if your compiler does not support
This allows macro parameters to be variable in size and allows data states to change variadic macros.<br>
size without the user explicitly keeping track of the size independently. <br>
</div>
<div>
Elements of an <i>array</i> can be extracted with <b>BOOST_PP_ARRAY_ELEM</b>, Elements of an <i>array</i> can be extracted with <b>BOOST_PP_ARRAY_ELEM</b>,
an <i>array's</i> size can be extracted with <b>BOOST_PP_ARRAY_SIZE</b>, and an <i>array's</i> size can be extracted with <b>BOOST_PP_ARRAY_SIZE</b>,
an <i>array</i> can be converted to the more primitive <i>tuple</i> data structure and an <i>array</i> can be converted to the more primitive <i>tuple</i>
with <b>BOOST_PP_ARRAY_DATA</b>. data structure with <b>BOOST_PP_ARRAY_DATA</b>. </div>
</div>
<h4>Primitives</h4> <h4>Primitives</h4>
<ul> <ul>
<li><a href="../ref/array_data.html">BOOST_PP_ARRAY_DATA</a></li> <li><a href="../ref/array_data.html">BOOST_PP_ARRAY_DATA</a></li>
@ -39,15 +35,13 @@
<li><a href="../ref/array_size.html">BOOST_PP_ARRAY_SIZE</a></li> <li><a href="../ref/array_size.html">BOOST_PP_ARRAY_SIZE</a></li>
</ul> </ul>
<hr size="1"> <hr size="1">
<div style="margin-left: 0px;"> <div style="margin-left: 0px;"> <i><EFBFBD> Copyright <a href="http://www.housemarque.com"
<i><EFBFBD> Copyright <a href="http://www.housemarque.com" target="_top">Housemarque Oy</a> 2002</i> target="_top">Housemarque Oy</a> 2002</i> <br>
</br><i><EFBFBD> Copyright Paul Mensonides 2002</i> <i><EFBFBD> Copyright Paul Mensonides 2002</i> </div>
</div>
<div style="margin-left: 0px;"> <div style="margin-left: 0px;">
<p><small>Distributed under the Boost Software License, Version 1.0. (See <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> or accompanying file <a href="../../../../LICENSE_1_0.txt">LICENSE_1_0.txt</a>
copy at <a href= or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</small></p>
"http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</small></p>
</div> </div>
</body> </body>
</html> </html>

View File

@ -5,38 +5,31 @@
</head> </head>
<body> <body>
<h4>Tuples</h4> <h4>Tuples</h4>
<div> <div> A <i>tuple</i> is a simple comma-separated list of elements inside
A <i>tuple</i> is a simple comma-separated list of elements inside parenthesis.&nbsp; parenthesis.&nbsp; For example, </div>
For example, <div class="code"> (<i>a</i>, <i>b</i>, <i>c</i>) </div>
</div> <div> ...is a <i>tuple</i> of <i>3</i> elements--<i>a</i>, <i>b</i>, and
<div class="code"> <i>c</i>. </div>
(<i>a</i>, <i>b</i>, <i>c</i>) <div> <i>Tuples</i> are fast and easy to use.&nbsp; With variadic macro
</div> support it is not necessary to know the size of a <i>tuple; </i>without
<div> variadic macro support&nbsp;all access to <i>tuples</i> requires
...is a <i>tuple</i> of <i>3</i> elements--<i>a</i>, <i>b</i>, and <i>c</i>. knowledge of its size. Use a <i>tuple </i>instead of an <i>array</i> if
</div> your compiler supports variadic macros, since a <i>tuple </i>has all of
<div> the functionality as an <i>array </i>and is easier syntactically to use.</div>
<i>Tuples</i> are fast and easy to use.&nbsp; <div> Elements of a <i>tuple</i> can be extracted with <b>BOOST_PP_TUPLE_ELEM</b>.
However, all access to <i>tuples</i> requires knowledge of its size.
</div>
<div>
Elements of a <i>tuple</i> can be extracted with
<b>BOOST_PP_TUPLE_ELEM</b>.
</div> </div>
<h4>Primitives</h4> <h4>Primitives</h4>
<ul> <ul>
<li><a href="../ref/tuple_elem.html">BOOST_PP_TUPLE_ELEM</a></li> <li><a href="../ref/tuple_elem.html">BOOST_PP_TUPLE_ELEM</a></li>
</ul> </ul>
<hr size="1"> <hr size="1">
<div style="margin-left: 0px;"> <div style="margin-left: 0px;"> <i><EFBFBD> Copyright <a href="http://www.housemarque.com"
<i><EFBFBD> Copyright <a href="http://www.housemarque.com" target="_top">Housemarque Oy</a> 2002</i> target="_top">Housemarque Oy</a> 2002</i> <br>
</br><i><EFBFBD> Copyright Paul Mensonides 2002</i> <i><EFBFBD> Copyright Paul Mensonides 2002</i> </div>
</div>
<div style="margin-left: 0px;"> <div style="margin-left: 0px;">
<p><small>Distributed under the Boost Software License, Version 1.0. (See <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> or accompanying file <a href="../../../../LICENSE_1_0.txt">LICENSE_1_0.txt</a>
copy at <a href= or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</small></p>
"http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</small></p>
</div> </div>
</body> </body>
</html> </html>

View File

@ -13,7 +13,7 @@ They are
macros of the form: macros of the form:
</div> </div>
<div class="code"> <div class="code">
<pre>#define SOME_MACRO(ZeroOrMoreParameters,...) macro expansion possible specifying __VA_ARGS__<br></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 macro is invoked and the __VA_ARGS__ in the expansion data when the macro is invoked and the __VA_ARGS__ in the expansion
@ -32,7 +32,7 @@ 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)<br></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>
@ -131,6 +131,19 @@ BOOST_PP_SEQ_ENUM, and BOOST_PP_TUPLE_ENUM. However if one wishes to
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>
<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
constitutes the array data. Because a tuple knows its own size when the
compiler supports variadic macros, there is no reason to use the array preprocessor
data type as opposed to the tuple preprocessor data type; the tuple data
type now has all of the functionality which the array data type has and is
syntactically easier to use. With variadic macro support, which is now
officially part of the latest C++ standard, the preprocessor array data
type is essentially obsolete for conforming C++ compilers. Only if your
compiler does not support variadic macros is the preprocessor array data
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
@ -176,7 +189,8 @@ First an example of what NOT to do.<br>
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 style="font-weight: bold;"><span style="font-family: monospace;"></span></span>int xx = MACRO_ARG_2(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 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>
</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 +217,8 @@ 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><br> </div>
<br>
<div>Although these techniques will work when passing variadic <div>Although these techniques will work when passing variadic
data to data to
non-variadic macros, it is much better and less problematical to non-variadic macros, it is much better and less problematical to