lib cleanup

[SVN r15700]
This commit is contained in:
Paul Mensonides
2002-10-03 23:36:33 +00:00
parent afd693d86e
commit cace45b77f
18 changed files with 0 additions and 1805 deletions

View File

@ -1,43 +0,0 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../../../boost.css">
<title>Boost.Preprocessor - Acknowledgements</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center">Boost.Preprocessor</h1>
<h2 align="center">Acknowledgements</h2>
</td>
</tr>
</table>
<hr>
<p>The original idea of passing two extra parameters to REPEAT, which makes it
possible to create preprocessor code on top of it, was due to Aleksey Gurtovoy.
The invokeable IDENTITY macro was also invented by him. He also suggested the
name for the library. Many thanks to Aleksey for his insights!</p>
<p>Thanks to everyone who participated in the review: David Abrahams, Beman Dawes,
Ronald Garcia, Douglas Gregor, Aleksey Gurtovoy, Jeremy Siek, and Daryle Walker.</p>
<p>Thanks to Chris Little and Mat Marcus for providing help with MWCW.</p>
<p>The original automatic recursion technique, which makes many of the library
primitives easier to use, was invented by Paul Mensonides.</p>
<p>The PREPROCESSOR library has been developed by Vesa Karvonen. </p>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="http://www.housemarque.com">Housemarque Oy</a> 2002</i></p>
<p>Permission to copy, use, modify, sell and distribute this document is granted
provided this copyright notice appears in all copies. This document is provided
"as is" without express or implied warranty, and with no claim as to its suitability
for any purpose.</p>
</body>
</html>

View File

@ -1,48 +0,0 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../../../boost.css">
<title>Boost.Preprocessor - Bibliography</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center">Boost.Preprocessor</h1>
<h2 align="center">Bibliography</h2>
</td>
</tr>
</table>
<hr>
<table>
<tr><td><b>[Stroustrup]</b></td><td><a name="[Stroustrup]">Stroustrup: <i>The Design and Evolution of C++</i>, ISBN 0201543303</a></td></tr>
<tr><td><b>[Czarnecki]</b></td><td><a name="[Czarnecki]">Czarnecki, Eisenecker: <i>Generative Programming</i>, ISBN 0201309777</a></td></tr>
<tr><td><b>[Barton]</b></td><td><a name="[Barton]">Barton, Nackman: <i>Scientific and Engineering C++</i>, ISBN 0201533936</a></td></tr>
<tr><td><b>[McConnell]</b></td><td><a name="[McConnell]">McConnell: <i>Code Complete</i>, ISBN 1556154844</a></td></tr>
<tr><td><b>[Std]</b></td><td><a name="[Std]">ISO/IEC 14882:1998 <i>Programming languages - C++</i></a></td></tr>
<tr><td><b>[Thompson]</b></td><td><a name="[Thompson]">Thompson: <i>Haskell: The Craft of Functional Programming</i>, ISBN 0201342758</a></td></tr>
<tr><td><b>[Okasaki]</b></td><td><a name="[Okasaki]">Okasaki: <i>Purely Functional Data Structures</i>, ISBN 0521663504</a></td></tr>
<tr><td><b>[Cousineau]</b></td><td><a name="[Cousineau]">Cousineau, Mauny: <i>The Functional Approach to Programming</i>, ISBN 0521576814</a></td></tr>
<tr><td><b>[Abelson]</b></td><td><a name="[Abelson]">Abelson, Sussman, Sussman: <i>Structure and Interpretation of Computer Programs</i>, ISBN 0262011530</a></td></tr>
</table>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="http://www.housemarque.com">Housemarque Oy</a> 2002</i></p>
<p>Permission to copy, use, modify, sell and distribute this document is granted
provided this copyright notice appears in all copies. This document is provided
"as is" without express or implied warranty, and with no claim as to its suitability
for any purpose.</p>
</body>
</html>

View File

@ -1,91 +0,0 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../../../boost.css">
<title>Boost.Preprocessor - Bibliography</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center">Boost.Preprocessor</h1>
<h2 align="center">Examples</h2>
</td>
</tr>
</table>
<hr>
<table>
<tr><td><a href="../example/array_arithmetic.c">array_arithmetic.c</a></td><td>Implements over 2200 functions for 1-dimensional arithmetic
array manipulation in C. The idea is to use preprocessor data structures,
lists and tuples, for storing metainformation to be used for generating
the actual C code.</td></tr>
<tr>
<td><a href="../example/catch_builtin.cpp">catch_builtin.cpp</a></td>
<td>Demonstrates the usage of lists and BOOST_PP_LIST_FOR_EACH().</td>
</tr>
<tr>
<td><a href="../example/count_down.c">count_down.c</a></td>
<td> Trivial example of using BOOST_PP_WHILE() that simply counts
down from N to 0 ultimately expanding to a 0.</td>
</tr>
<tr>
<td><a href="../example/delay.c">delay.c</a></td>
<td>Implements a macro whose expansion takes exponential amount
of time.</td>
</tr>
<tr>
<td><a href="../example/duffs_device.c">duffs_device.c</a></td>
<td>Uses the preprocessor library to implement a generalized
macro for implementing a Duff's Device.</td>
</tr>
<tr>
<td><a href="../example/is_integral.cpp">is_integral.cpp</a></td>
<td>Demonstrates the usage of preprocessor lists for generating
C++ code.</td>
</tr>
<tr>
<td><a href="../example/linear_fib.c">linear_fib.c</a></td>
<td>Shows how BOOST_PP_WHILE() can be used for implementing macros.</td>
</tr>
<tr>
<td><a href="../example/note.c">note.c</a></td>
<td>Shows how BOOST_PP_STRINGIZE() can be used to allow macro
expansion before stringization.</td>
</tr>
<tr>
<td><a href="../example/repeat_2d.c">repeat_2d.c</a></td>
<td>Implements a generalized macro for 2D repetition using the
simple repetition primitives of the preprocessor library.</td>
</tr>
<tr>
<td><a href="../example/static_assert.c">static_assert.c</a></td>
<td>Shows how BOOST_PP_CAT() can be used to allow macro expansion
before token concatenation.</td>
</tr>
<tr>
<td><a href="../example/subscript_layer.cpp">subscript_layer.cpp</a></td>
<td>Shows how BOOST_PP_EMPTY can be used as an unused or empty
parameter.</td>
</tr>
</table>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="http://www.housemarque.com">Housemarque Oy</a> 2002</i></p>
<p>Permission to copy, use, modify, sell and distribute this document is granted
provided this copyright notice appears in all copies. This document is provided
"as is" without express or implied warranty, and with no claim as to its suitability
for any purpose.</p>
</body>
</html>

View File

@ -1,326 +0,0 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../../../boost.css">
<title>Boost.Preprocessor - Tutorial examples preprocessed</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center">Boost.Preprocessor</h1>
<h2 align="center">Tutorial examples preprocessed</h2>
</td>
</tr>
</table>
<hr>
<p>The following code snippets were produced by actually preprocessing the code
snippets of the tutorial. After preprocessing the code was reformatted manually.</p>
<hr>
<p><strong><a name="Local Macro"></a><a href="tutorial.htm#Local Macro">EXAMPLE</a>:</strong>
Use a Local Macro to avoid small scale repetition</p>
<pre>template&lt;class T, int n&gt;
vec&lt;T,n&gt;&
operator +=
( vec&lt;T,n&gt;&
lhs
, const vec&lt;T,n&gt;&
rhs
)
{ for (int i=0; i&lt;n; ++i)
lhs(i) += rhs(i);
return lhs;
}
template&lt;class T, int n&gt;
vec&lt;T,n&gt;&
operator -=
( vec&lt;T,n&gt;&
lhs
, const vec&lt;T,n&gt;&
rhs
)
{ for (int i=0; i&lt;n; ++i)
lhs(i) -= rhs(i);
return lhs;
}
template&lt;class T, int n&gt;
vec&lt;T,n&gt;&
operator *=
( vec&lt;T,n&gt;&
lhs
, const vec&lt;T,n&gt;&
rhs
)
{ for (int i=0; i&lt;n; ++i)
lhs(i) *= rhs(i);
return lhs;
}
template&lt;class T, int n&gt;
vec&lt;T,n&gt;&
operator /=
( vec&lt;T,n&gt;&
lhs
, const vec&lt;T,n&gt;&
rhs
)
{ for (int i=0; i&lt;n; ++i)
lhs(i) /= rhs(i);
return lhs;
}
</pre>
<hr>
<p><strong><a name="UNUSED"></a><a href="tutorial.htm#UNUSED">EXAMPLE</a>:</strong>
Use BOOST_PP_EMPTY() as an unused parameter in Local Macro instantiations</p>
<pre>template&lt;class base&gt;
typename implement_subscript_using_begin_subscript&lt;base&gt;::value_type&
implement_subscript_using_begin_subscript&lt;base&gt;::operator[]
( index_type
i
)
{ return base::begin()[i];
}
template&lt;class base&gt;
const typename implement_subscript_using_begin_subscript&lt;base&gt;::value_type&
implement_subscript_using_begin_subscript&lt;base&gt;::operator[]
( index_type
i
) const
{ return base::begin()[i];
}
</pre>
<hr>
<p><b><a name="CAT"></a><a href="tutorial.htm#CAT">EXAMPLE:</a></b> Use BOOST_PP_CAT instead of ## when necessary</p>
<pre>enum
{ static_check_152 = (sizeof(int) &lt;= sizeof(long)) ? 1 : -1
};
typedef char
static_assert_152
[ static_check_152
];
</pre>
<hr>
<p><b><a name="STRINGIZE"></a><a href="tutorial.htm#STRINGIZE">EXAMPLE:</a></b> Use BOOST_PP_STRINGIZE instead of # whenever necessary</p>
<pre>#pragma message("examples.cpp" "(" "20" ") : " "TBD!")</pre>
<hr>
<p><strong><a name="ENUM_PARAMS"></a><a href="tutorial.htm#ENUM_PARAMS">EXAMPLE</a>:</strong>
Use:</p>
<ul>
<li> BOOST_PP_ENUM_PARAMS,</li>
<li> BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT,</li>
<li> BOOST_PP_ENUM_PARAMS_WITH_DEFAULTS,</li>
<li> BOOST_PP_ENUM_SHIFTED_PARAMS, or</li>
<li>BOOST_PP_REPEAT, and</li>
<li> BOOST_PP_COMMA_IF</li>
</ul>
<p>to avoid O(N) repetition on lists in general</p>
<pre>struct make_type_list_end;
template
&lt; class T0=make_type_list_end
, class T1=make_type_list_end
, class T2=make_type_list_end
, class T3=make_type_list_end
, class T4=make_type_list_end
, class T5=make_type_list_end
, class T6=make_type_list_end
, class T7=make_type_list_end
&gt;
struct make_type_list
{
private:
enum
{ end = is_same&lt;T0,make_type_list_end&gt;::value
};
public:
typedef typename
type_if
&lt; end
, type_cons_empty
, type_cons
&lt; T0
, typename
type_inner_if
&lt; end
, type_identity&lt;end&gt;
, make_type_list
&lt; T1
, T2
, T3
, T4
, T5
, T6
, T7
&gt;
&gt;::type
&gt;
&gt;::type type;
};
</pre>
<hr>
<p><strong><a name="Token Look-Up"></a><a href="tutorial.htm#Token Look-Up">EXAMPLE</a>:</strong>
Use BOOST_PP_REPEAT and a Token Look-Up Function to eliminate categorical
repetition</p>
<pre>catch (bool t)
{ report_typeid(t);
report_value(t);
}
catch (char t)
{ report_typeid(t);
report_value(t);
}
catch (signed char t)
{ report_typeid(t);
report_value(t);
}
catch (unsigned char t)
{ report_typeid(t);
report_value(t);
}
catch (short t)
{ report_typeid(t);
report_value(t);
}
catch (unsigned short t)
{ report_typeid(t);
report_value(t);
}
catch (int t)
{ report_typeid(t);
report_value(t);
}
catch (unsigned int t)
{ report_typeid(t);
report_value(t);
}
catch (long t)
{ report_typeid(t);
report_value(t);
}
catch (unsigned long t)
{ report_typeid(t);
report_value(t);
}
catch (float t)
{ report_typeid(t);
report_value(t);
}
catch (double t)
{ report_typeid(t);
report_value(t);
}
catch (long double t)
{ report_typeid(t);
report_value(t);
}
</pre>
<hr>
<p><strong><a name="2ND_REPEAT"></a><a href="tutorial.htm#2ND_REPEAT">EXAMPLE</a>:</strong>
Use BOOST_PP_REPEAT_2ND to avoid O(N*N) repetition</p>
<pre>vec()
{
}
vec(T a0)
{ (*this)[0] = a0;
}
vec(T a0, T a1)
{ (*this)[0] = a0;
(*this)[1] = a1;
}
vec(T a0, T a1, T a2)
{ (*this)[0] = a0;
(*this)[1] = a1;
(*this)[2] = a2;
}
vec(T a0, T a1, T a2, T a3)
{ (*this)[0] = a0;
(*this)[1] = a1;
(*this)[2] = a2;
(*this)[3] = a3;
}
vec(T a0, T a1, T a2, T a3, T a4)
{ (*this)[0] = a0;
(*this)[1] = a1;
(*this)[2] = a2;
(*this)[3] = a3;
(*this)[4] = a4;
}
vec(T a0, T a1, T a2, T a3, T a4, T a5)
{ (*this)[0] = a0;
(*this)[1] = a1;
(*this)[2] = a2;
(*this)[3] = a3;
(*this)[4] = a4;
(*this)[5] = a5;
}
vec(T a0, T a1, T a2, T a3, T a4, T a5, T a6)
{ (*this)[0] = a0;
(*this)[1] = a1;
(*this)[2] = a2;
(*this)[3] = a3;
(*this)[4] = a4;
(*this)[5] = a5;
(*this)[6] = a6;
}
vec(T a0, T a1, T a2, T a3, T a4, T a5, T a6, T a7)
{ (*this)[0] = a0;
(*this)[1] = a1;
(*this)[2] = a2;
(*this)[3] = a3;
(*this)[4] = a4;
(*this)[5] = a5;
(*this)[6] = a6;
(*this)[7] = a7;
}
</pre>
<p>
<hr>
<p><a name="IF"></a><a href="tutorial.htm#IF"><b>EXAMPLE:</b></a>
Use BOOST_PP_IF to implement special case for the first element</p>
<pre>false == false;
true == true;
</pre>
<p>
<hr>
<p><a name="Arithmetic"></a><a href="tutorial.htm#Arithmetic"><B>EXAMPLE:</B></a> Use arithmetic, logical and comparison operations when necessary</p>
<pre>S, E0, E1
E0, S, E1
E0, E1, S
BAD PARAMS FOR SPECIAL_NUMBERED_LIST! E0, E1, E2, S</pre>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="http://www.housemarque.com">Housemarque Oy</a> 2002</i></p>
<p>Permission to copy, use, modify, sell and distribute this document is granted
provided this copyright notice appears in all copies. This document is provided
"as is" without express or implied warranty, and with no claim as to its suitability
for any purpose.</p>
</body>
</html>

View File

@ -1,48 +0,0 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../../../boost.css">
<title>Boost.Preprocessor - Index</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center">Boost.Preprocessor</h1>
<h2 align="center">Index</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="index">
<dt><a href="tutorial.htm">Tutorial</a></dt>
<dt><a href="examples.htm">Examples</a></dt>
<dt><a href="reference/index.htm">Reference</a></dt>
<dt><a href="known_problems_with_cpp.htm">Widely known problems with the C preprocessor</a></dt>
<dt><a href="keywords.txt">Keywords for syntax highlighting</a></dt>
<dt><a href="problems_with_compilers.htm">Known problems with specific compilers</a></dt>
<dt><a href="bibliography.htm">Bibliography</a></dt>
<dt><a href="acknowledgements.htm">Acknowledgements</a></dt>
</dl>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan --><!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="http://www.housemarque.com">Housemarque Oy</a> 2002</i></p>
<p>Permission to copy, use, modify, sell and distribute this document is granted
provided this copyright notice appears in all copies. This document is provided
"as is" without express or implied warranty, and with no claim as to its suitability
for any purpose.</p>
</body>
</html>

View File

@ -1,99 +0,0 @@
BOOST_PP_ADD
BOOST_PP_ADD_D
BOOST_PP_AND
BOOST_PP_ASSERT_MSG
BOOST_PP_BOOL
BOOST_PP_CAT
BOOST_PP_COMMA
BOOST_PP_COMMA_IF
BOOST_PP_DEC
BOOST_PP_DIV
BOOST_PP_DIV_D
BOOST_PP_EMPTY
BOOST_PP_ENUM
BOOST_PP_ENUM_PARAMS
BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT
BOOST_PP_ENUM_PARAMS_WITH_DEFAULTS
BOOST_PP_ENUM_SHIFTED
BOOST_PP_ENUM_SHIFTED_PARAMS
BOOST_PP_EQUAL
BOOST_PP_EQUAL_D
BOOST_PP_EXPAND
BOOST_PP_EXPR_IF
BOOST_PP_FOR
BOOST_PP_GREATER
BOOST_PP_GREATER_D
BOOST_PP_GREATER_EQUAL
BOOST_PP_GREATER_EQUAL_D
BOOST_PP_IDENTITY
BOOST_PP_IF
BOOST_PP_INC
BOOST_PP_LESS
BOOST_PP_LESS_D
BOOST_PP_LESS_EQUAL
BOOST_PP_LESS_EQUAL_D
BOOST_PP_LIMIT_DIM
BOOST_PP_LIMIT_MAG
BOOST_PP_LIMIT_TUPLE
BOOST_PP_LIST_APPEND
BOOST_PP_LIST_APPEND_D
BOOST_PP_LIST_AT
BOOST_PP_LIST_AT_D
BOOST_PP_LIST_CAT
BOOST_PP_LIST_CAT_D
BOOST_PP_LIST_CONS
BOOST_PP_LIST_ENUM
BOOST_PP_LIST_ENUM_R
BOOST_PP_LIST_FILTER
BOOST_PP_LIST_FILTER_D
BOOST_PP_LIST_FIRST
BOOST_PP_LIST_FIRST_N
BOOST_PP_LIST_FIRST_N_D
BOOST_PP_LIST_FOLD_LEFT
BOOST_PP_LIST_FOLD_LEFT_D
BOOST_PP_LIST_FOLD_RIGHT
BOOST_PP_LIST_FOLD_RIGHT_D
BOOST_PP_LIST_FOR_EACH
BOOST_PP_LIST_FOR_EACH_I
BOOST_PP_LIST_FOR_EACH_I_R
BOOST_PP_LIST_FOR_EACH_R
BOOST_PP_LIST_FOR_EACH_PRODUCT
BOOST_PP_LIST_FOR_EACH_PRODUCT_R
BOOST_PP_LIST_IS_CONS
BOOST_PP_LIST_IS_NIL
BOOST_PP_LIST_NIL
BOOST_PP_LIST_REST
BOOST_PP_LIST_REST_N
BOOST_PP_LIST_REST_N_D
BOOST_PP_LIST_REVERSE
BOOST_PP_LIST_REVERSE_D
BOOST_PP_LIST_SIZE
BOOST_PP_LIST_SIZE_D
BOOST_PP_LIST_TO_TUPLE
BOOST_PP_LIST_TO_TUPLE_R
BOOST_PP_LIST_TRANSFORM
BOOST_PP_LIST_TRANSFORM_D
BOOST_PP_MAX
BOOST_PP_MAX_D
BOOST_PP_MIN
BOOST_PP_MIN_D
BOOST_PP_MOD
BOOST_PP_MOD_D
BOOST_PP_MUL
BOOST_PP_MUL_D
BOOST_PP_NOR
BOOST_PP_NOT
BOOST_PP_NOT_EQUAL
BOOST_PP_NOT_EQUAL_D
BOOST_PP_OR
BOOST_PP_REPEAT
BOOST_PP_REPEAT_FROM_TO
BOOST_PP_STRINGIZE
BOOST_PP_SUB
BOOST_PP_SUB_D
BOOST_PP_TUPLE_EAT
BOOST_PP_TUPLE_ELEM
BOOST_PP_TUPLE_REVERSE
BOOST_PP_TUPLE_TO_LIST
BOOST_PP_WHILE
BOOST_PP_XOR

View File

@ -1,125 +0,0 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../../../boost.css">
<title>Boost.Preprocessor - Widely known problems with the C preprocessor</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center">Boost.Preprocessor</h1>
<h2 align="center">Widely known problems with the C preprocessor</h2>
</td>
</tr>
</table>
<hr>
<p>Preprocessor metaprogramming is subject to heated discussions. Part of this is caused by
bad experiences with dangerous techniques, such as defining inline functions using macros. As a rule
of thumb, if you can find a clean and
manageable way to do something without using the preprocessor, then
you should do it that way.</p>
<p>Let's survey some of the widely known problems with the preprocessor in a problem/solution
format.</p>
<HR>
<p><B>PROBLEM:</B>&nbsp;Preprocessor does not
respect scope, therefore macros can accidentally and sometimes silently replace
code.</p>
<p><B>SOLUTION A:</B> Use all caps identifiers
for macros and only macros. This practically eliminates the possibility that a
macro might replace other kind of code accidentally.</p>
<p><B>SOLUTION B:</B> Use the Local Macro
idiom:</p>
<pre>#define MACRO ...
// Use MACRO
#undef MACRO
</pre>
<p>This makes sure that a macro can not accidentally
replace code outside of the scope of the local macro.</p>
<P>A problem with this solution is&nbsp;that the #undef can not be automated and may be
forgotten. Experienced programmers generally write the #undef either immediately
before (in time) or immediately after writing the macro definition.</P>
<P><B>SOLUTION C:</B> Use the Unique Macro Prefix idiom:</P>
<pre>#define UMP_MACRO
// Use UMP_MACRO
</pre>
<P>This makes accidental substitution and collisions highly
unlikely. Problems with this solution:</P>
<UL>
<LI>
There can still be naming collisions inside a large project.
<LI>
Macros still pollute the global namespace. </LI></UL>
<P><EM><B>By combining all solutions, whenever
possible, the scope problem can be largely avoided.</B></EM></P>
<HR>
<P><B>PROBLEM:</B> &nbsp;Preprocessor code is difficult to read.
It requires understanding the basic process of how
the&nbsp;preprocessor recursively expands macros, finding the macro definition and mentally
substituting the parameters of the macro. </P>
<P><B>SOLUTION:</B> Any kind of programming requires basic understanding
of how the code is executed. Any parameterization technique, including simple
functions and templates requires finding the definition and mentally substituting
parameters. </P>
<P>However, it is good to know a few techniques:</P>
<UL>
<LI>
By using as many Local Macros as reasonable, the bulk of the searching
process can be eliminated.
<LI>
Code browsers and text search tools make it easier to find the
definitions.
<LI>
The compiler can be used for generating the preprocessed source code in
order to look for bugs.
<LI>
Before turning something into a&nbsp;preprocessor metaprogram, first
implement a small scale version of it without preprocessor. Then work
bottom-&gt;up replacing hand written constructs by using preprocessor. This
way you can test the code incrementally. Experienced programmers often skip
many stages, but if something proves too complex to write directly, it is
always possible to fall back to incremental methods.
<LI>
If you insert a special symbol into the preprocessor code in places where
there should be a line break, you can make code readable after preprocessing
simply by using a search and replace tool. </LI></UL>
<P><B><EM> An especially important thing to remember is to limit the use of&nbsp;preprocessor
to the structured, well understood and safe methods. Structure helps to understand
complex systems <A href="bibliography.htm#[McConnell]">[McConnell]</A>.</EM></B></P>
<HR>
<P><B>PROBLEM:</B> "I'd
like to see Cpp abolished." - Bjarne Stroustrup in&nbsp;<A href="bibliography.htm#[Stroustrup]">[Stroustrup]</A></P>
<P><B>SOLUTION:</B>&nbsp;The C preprocessor&nbsp;will be here for a
long time.</P>
<P><EM><B>In practice, preprocessor metaprogramming is far simpler and more portable
than template metaprogramming <A href="bibliography.htm#[Czarnecki]">[Czarnecki]</A>.</B></EM></P>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="http://www.housemarque.com">Housemarque Oy</a> 2002</i></p>
<p>Permission to copy, use, modify, sell and distribute this document is granted
provided this copyright notice appears in all copies. This document is provided
"as is" without express or implied warranty, and with no claim as to its suitability
for any purpose.</p>
</body>
</html>

View File

@ -1,138 +0,0 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../../../boost.css">
<title>Boost.Preprocessor - Known problems with specific compilers</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center">Boost.Preprocessor</h1>
<h2 align="center">Known problems with specific compilers</h2>
</td>
</tr>
</table>
<hr>
<p> Some compilers have buggy or limited preprocessors. This page explains known
problems with specific compilers.</p>
<hr>
<h2>Contents</h2>
<ul>
<li><a href="#Metrowerks Codewarrior 7.0">Metrowerks Codewarrior 7.0</a></li>
<li><a href="#Comeau C/C++ 4.2.45.2">Comeau C/C++ 4.2.45.2 for Windows</a></li>
</ul>
<HR>
<h3><a name="Metrowerks Codewarrior 7.0">Metrowerks Codewarrior 7.0</a></h3>
<p>Metrowerks Codewarrior 7.0 has a bug in preprocessor (to be more
concrete, in function-like macro replacement mechanism) that restricts usage
of the library to only very simple cases, at least if you don't write code that
specifically address this issue; for example, the above NUMBERED_EXPRESSION
example doesn't compile on CW 7.0. Below is a simple test case that reproduces
the bug:</p>
<pre>#define IDENTITY_MACRO(x) IDENTITY_MACRO_BODY(x)
#define IDENTITY_MACRO_BODY(x) x
#define COMMA_TOKEN() ,
int a IDENTITY_MACRO(COMMA_TOKEN)() b; // this works
int c IDENTITY_MACRO(IDENTITY_MACRO(COMMA_TOKEN))() d; // this doesn't
</pre>
<p>Basically, what's happening here is that function-like COMMA_TOKEN macro gets
expanded _inside_ of the nested IDENTITY_MACRO call - even although it's NOT
followed by a '(' as the next preprocessing token - which is a clearly an incorrect
behavior (see 16.3 [cpp.replace] para 9 for the detailed description of the
function-like macro replacement process). I've submitted a bug report, but they
haven't confirmed it yet.</p>
<p>So, this is not a problem of the library, but probably something that needs
to be mentioned in the documentation, may be with some examples of how to workaround
the issue. Just to show one possible way around the problem, here is a NUMBERED_EXPRESSION
macro that does work on MWCW:</p>
<pre>#define NUMBERED_EXPRESSION(n, x) \
BOOST_PP_CAT(BOOST_, \
BOOST_PP_IF( \
n \
, PREPROCESSOR_IDENTITY(x##n) \
, PREPROCESSOR_EMPTY \
))() \
/**/
</pre>
<p align="right"><i>Reported by Aleksey Gurtovoy</i></p>
<h3><a name="Comeau C/C++ 4.2.45.2">Comeau C/C++ 4.2.45.2 for Windows</a></h3>
<p>It appears that their algorithm of macro call invocation is quite far
from ideal, because for the following code fragment (which is a part of
<a href="../test/preprocessor_test.cpp">preprocessor_test.cpp</a>), the
linear increasing of IS_FUNCTION_HELPER_TEST_MAX value leads to not even
quadratic, but something like exponential increasing of compilation time!
(see the timing data below). This behavior may or may not be problematic
for you, depending on how intense is your usage of the library.
<pre>#ifndef IS_FUNCTION_HELPER_TEST_MAX
#define IS_FUNCTION_HELPER_TEST_MAX 40
#endif
typedef char yes_type;
#define IS_FUNCTION_HELPER(I,A)\
template\
&ltBOOST_PP_ENUM_PARAMS(BOOST_PP_INC(I),class P)&gt;\
yes_type is_function_helper(\
P0 (*)(BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_INC(I),P)));
BOOST_PP_REPEAT_2ND(BOOST_PP_INC(IS_FUNCTION_HELPER_TEST_MAX),IS_FUNCTION_HELPER,A)
#undef IS_FUNCTION_HELPER
</pre>
<h4>Timing data:</h4>
<table border="1">
<tr align="center">
<th>&nbsp;</th>
<th>Comeau C/C++ 4.2.45.2</th>
<th>Microsoft Visual C++ 6.0 SP5</th>
</tr>
<tr align="center">
<td>10 parameters</td>
<td><font color="red">&lt; 1 sec</font></td>
<td>&lt; 1 sec</td>
</tr>
<tr align="center">
<td>20 parameters</td>
<td><font color="red">~ 2 sec</font></td>
<td>&lt; 1 sec</td>
</tr>
<tr align="center">
<td>30 parameters</td>
<td><font color="red">~ 15 sec</font></td>
<td>&lt; 1 sec</td>
</tr>
<tr align="center">
<td>40 parameters</td>
<td><font color="red">~ 50 sec</font></td>
<td>&lt; 1 sec</td>
</tr>
</table>
<p align="right"><i>Reported by Aleksey Gurtovoy</i></p>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="http://www.housemarque.com">Housemarque Oy</a> 2002</i></p>
<p>Permission to copy, use, modify, sell and distribute this document is granted
provided this copyright notice appears in all copies. This document is provided
"as is" without express or implied warranty, and with no claim as to its suitability
for any purpose.</p>
</body>
</html>

View File

@ -1,478 +0,0 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../../../boost.css">
<title>Boost.Preprocessor - Tutorial</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center">Boost.Preprocessor</h1>
<h2 align="center">Tutorial</h2>
</td>
</tr>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#Motivation">Motivation</a></dt>
<dt><a href="#Techniques">Preprocessor Metaprogramming Techniques</a>
<dl class="page-index">
<dt><a href="#Local Macro">Use a Local Macro to avoid small scale repetition</a></dt>
<dt><a href="#UNUSED">Use BOOST_PP_EMPTY as an unused parameter in Local
Macro instantiations</a></dt>
<dt><a href="#CAT">Use BOOST_PP_CAT instead of ## when necessary</a></dt>
<dt><a href="#STRINGIZE">Use BOOST_PP_STRINGIZE instead of # whenever necessary</a></dt>
<dt><a href="#ENUM_PARAMS">Avoid O(N) repetition on lists in general</a></dt>
<dt><a href="#Conditional Define">Use a Conditional Define to enable user configuration of code repetition</a></dt>
<dt><a href="#Token Look-Up">Use Token Look-Up Function to eliminate categorical repetition</a></dt>
<dt><a href="#2ND_REPEAT">Use BOOST_PP_REPEAT to avoid O(N*N) repetition</a></dt>
<dt><a href="#IF">Use BOOST_PP_IF to implement special case for the first element</a></dt>
<dt><a href="#Arithmetic">Use arithmetic, logical and comparison operations when necessary</a></dt>
</dl>
</dt>
</dl>
<hr>
<h2><a name="Motivation">Motivation</a></h2>
<p>The C++ function and template parameter lists are special syntactic constructs
and it is impossible to directly manipulate or generate them using C++ constructs.
This leads to unnecessary code repetition.</p>
<p> Consider the implementation of the is_function<> metafunction in Boost. The
implementation uses an overloaded is_function_tester() function that is used
for testing if a type is convertible to pointer to a function. Because of the
special treatment of parameter lists, it is not possible to directly match a
function with an arbitrary parameter list. Instead, the is_function_tester()
must be overloaded for every distinct number of parameters that is to be supported.
Example:</p>
<pre>template &lt;class R&gt;
yes_type is_function_tester(R (*)());
template &lt;class R, class A0&gt;
yes_type is_function_tester(R (*)(A0));
template &lt;class R, class A0, A1&gt;
yes_type is_function_tester(R (*)(A0, A1));
template &lt;class R, class A0, A1, A2&gt;
yes_type is_function_tester(R (*)(A0, A1, A2));
// ...
</pre>
<P>The need for this kind of repetition occurs particularly frequently while implementing
generic components or metaprogramming facilities, but the need also manifests
itself in many far simpler situations. </P>
<h3>Typical solutions</h3>
<p>Typically the repetition is done manually. Manual code repetition is highly
unproductive, but sometimes more readable to the untrained eye.</p>
<p>Another solution is to write an external program for generating the repeated
code or use some other extra linquistic means such as a smart editor. Unfortunately,
using external code generators has many disadvantages:</p>
<ul>
<li>writing the generator takes time (this could be helped by using a standard
generator)</li>
<li>it is no longer productive to manipulate C++ code directly</li>
<li>invoking the generator may be difficult</li>
<li>automating the invocation of the generator can be difficult in certain environments
(automatic invocation is desirable for active libraries)</li>
<li>porting and distributing the generator may be difficult or simply takes
precious time</li>
</ul>
<h3>What about the preprocessor?</h3>
<p>Because C++ comes with a preprocessor, one would assume that it would support
these kind of needs directly. Using the preprocessor in this case is highly
desirable because:</p>
<ul>
<li>preprocessor is highly portable</li>
<li>preprocessor is automatically invoked as part of the compiling process</li>
<li>preprocessor metacode can be directly embedded into the C++ source code</li>
<li>Compilers generally allow to view or output the preprocessed code, which
can be used for debugging or to copy-paste the generated code.</li>
</ul>
<p>Most unfortunately, the preprocessor is a very low level preprocessor that
specifically does not support repetition or recursive macros. Library support
is needed!</p>
<p><i>For detailed information on the capabilities and limitations of the preprocessor,
please refer to the C++ standard <A href="bibliography.htm#[Std]">[Std]</A>.</i></p>
<h3>The motivation example revisited</h3>
<p>Using the primitives of the PREPROCESSOR library, the is_function_tester()s
could be implemented like this:</p>
<pre>#define IS_FUNCTION_TESTER(N,_)\
template&lt;class R BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_PARAMS(N, class A)&gt;\
yes_type is_function_tester(R (*)(BOOST_PP_ENUM_PARAMS(N,A)));
BOOST_PP_REPEAT(BOOST_PP_INC(MAX_IS_FUNCTION_TESTER_PARAMS),IS_FUNCTION_TESTER,_)
#undef IS_FUNCTION_TESTER
</pre>
<p>In order to change the maximum number of function parameters supported, you
now simply change the MAX_IS_FUNCTION_TESTER_PARAMS definition and recompile.</p>
<HR>
<H2><a name="Techniques">Preprocessor Metaprogramming Techniques</a></H2>
<P>The&nbsp;preprocessor metaprogramming techniques are presented in example format.
</P>
<HR>
<P><B><a name="Local Macro"></a><a href="examples_preprocessed.htm#Local Macro">EXAMPLE</a>:</B>
Use a Local Macro to avoid small scale repetition</P>
<pre>#define BOOST_PP_DEF(OP) \
template&lt;class T, int n&gt; \
vec&lt;T,n&gt;&amp; \
operator OP##= \
( vec&lt;T,n&gt;&amp; \
lhs \
, const vec&lt;T,n&gt;&amp; \
rhs \
) \
{ for (int i=0; i&lt;n; ++i)\
lhs(i) OP##= rhs(i); \
return lhs; \
}
BOOST_PP_DEF(+)
BOOST_PP_DEF(-)
BOOST_PP_DEF(*)
BOOST_PP_DEF(/)
#undef BOOST_PP_DEF
</pre>
<P><B>TIP:</B> It is usually okay to use a standard macro name like BOOST_PP_DEF
for this kind of code, because the macro is both defined and undefined in the
immediate site of its use.</P>
<P><B>TIP:</B> It is easier to verify proper use of
the line continuation operator when they are aligned.</P>
<P><B>NOTES:</B> You can extend this example by defining more and different kinds
of operators. Before doing so, consider using the Algebraic Categories technique
introduced in <A href="bibliography.htm#[Barton]">[Barton]</A> or a Layered Architecture (see for instance
<A href="bibliography.htm#[Czarnecki]">[Czarnecki]</A>). However, at some point you must type the operator tokens
*, /, +, -, ..., because it is impossible to generate them using templates.
The resulting Categorical Repetition of tokens can be eliminated by using preprocessor
metaprogramming.</P>
<HR>
<P><B><a name="UNUSED"></a><a href="examples_preprocessed.htm#UNUSED">EXAMPLE</a>:</B>
Use BOOST_PP_EMPTY as an unused parameter in Local Macro instantiations</P>
<pre>#define BOOST_PP_DEF(CV) \
template&lt;class base&gt; \
CV() typename implement_subscript_using_begin_subscript&lt;base&gt;::value_type&amp;\
implement_subscript_using_begin_subscript&lt;base&gt;::operator[]\
( index_type \
i \
) CV() \
{ return base::begin()[i];\
}
BOOST_PP_DEF(BOOST_PP_EMPTY)
BOOST_PP_DEF(const BOOST_PP_EMPTY)
#undef BOOST_PP_DEF
</pre>
<P><B>HOW:</B> BOOST_PP_EMPTY() expands to nothing and can be used as
an unused parameter.</P>
<P><b>NOTE:</b> BOOST_PP_EMPTY without the () never gets expanded. The
() is necessary to invoke a function-like macro.</P>
<B>CAVEAT:</B> You can not safely use concatenation while using BOOST_PP_EMPTY().
<P><B>TIP:</B> Occasionally one or two lines are
considerably longer than the rest. It can often save some work to not align all
of the line continuation operators without making the code too unreadable.</P>
<P><B>TIP:</B> Use syntax highlighting on preprocessor metaprogramming macro and
parameter identifiers such as</P>
<ul>
<li>BOOST_PP_DEF,</li>
<li>BOOST_PP_EMPTY,</li>
<li>BOOST_PP_REPEAT,</li>
<li>OP,</li>
<li>CV,</li>
<li>...</li>
</ul>
<p>It can greatly improve readability.</p>
<HR>
<P><a name="CAT"></a><a href="examples_preprocessed.htm#CAT"><B>EXAMPLE:</B></a> Use BOOST_PP_CAT instead of ## when necessary</P>
<pre>#define STATIC_ASSERT(EXPR)\
enum\
{ BOOST_PP_CAT(static_check_,__LINE__) = (EXPR) ? 1 : -1\
};\
typedef char\
BOOST_PP_CAT(static_assert_,__LINE__)\
[ BOOST_PP_CAT(static_check_,__LINE__)\
]
// ...
STATIC_ASSERT(sizeof(int) &lt;= sizeof(long));
</pre>
<P><B>WHY:</B> Macro expansion proceeds recursively in "layers". Token pasting
prevents the&nbsp;preprocessor from performing macro expansion, therefore it
is often necessary to delay token concatenation.</P>
<hr>
<p><a name="STRINGIZE"></a><a href="examples_preprocessed.htm#STRINGIZE"><B>EXAMPLE:</B></a> Use BOOST_PP_STRINGIZE instead of # whenever necessary</p>
<pre>#define NOTE(STR)\
message(__FILE__ &quot;(&quot; BOOST_PP_STRINGIZE(__LINE__) &quot;) : &quot; STR)
// ...
#pragma NOTE("TBD!")
</pre>
<p><b>WHY:</b> Macro expansion proceeds recursively in &quot;layers&quot;. Stringization
prevents the preprocessor from performing macro expansion, therefore it is often
necessary to delay stringization.</p>
<HR>
<P><B><a name="ENUM_PARAMS"></a><a href="examples_preprocessed.htm#ENUM_PARAMS">EXAMPLE</a>:</B>
Use:</P>
<ul>
<li>BOOST_PP_ENUM_PARAMS,</li>
<li>BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT,</li>
<li>BOOST_PP_ENUM_PARAMS_WITH_DEFAULTS,</li>
<li>BOOST_PP_ENUM_SHIFTED_PARAMS, or</li>
<li>BOOST_PP_REPEAT, and</li>
<li>BOOST_PP_COMMA_IF</li>
</ul>
<p>to avoid O(N) repetition on lists in general</p>
<pre>struct make_type_list_end;
template
&lt; BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT
( MAKE_TYPE_LIST_MAX_LENGTH
, class T
, make_type_list_end
)
&gt;
struct make_type_list
{
private:
enum
{ end = is_same&lt;T0,make_type_list_end&gt;::value
};
public:
typedef typename
type_if
&lt; end
, type_cons_empty
, type_cons
&lt; T0
, typename
type_inner_if
&lt; end
, type_identity&lt;end&gt;
, make_type_list
&lt; BOOST_PP_ENUM_SHIFTED_PARAMS
( MAKE_TYPE_LIST_MAX_LENGTH
, T
)
&gt;
&gt;::type
&gt;
&gt;::type type;
};
</pre>
<P><B>HOW:</B> BOOST_PP_REPEAT uses simulated recursion (pseudo code):</P>
<pre>#define BOOST_PP_REPEAT(N,M,P) BOOST_PP_REPEAT##N(M,P)
#define BOOST_PP_REPEAT0(M,P)
#define BOOST_PP_REPEAT1(M,P) M(0,P)
#define BOOST_PP_REPEAT2(M,P) M(0,P) M(1,P)
#define BOOST_PP_REPEAT3(M,P) BOOST_PP_REPEAT2(M,P) M(2,P)
#define BOOST_PP_REPEAT4(M,P) BOOST_PP_REPEAT3(M,P) M(3,P)
// ...
</pre>
<P>BOOST_PP_ENUM_PARAMS variations use BOOST_PP_REPEAT</P>
<P>BOOST_PP_COMMA_IF(I) expands to a comma if I != 0.</P>
<P>BOOST_PP_INC(I) expands essentially to "I+1" and BOOST_PP_DEC(I)
expands essentially to "I-1".</P>
<HR>
<P><a name="Conditional Define"><B>EXAMPLE:</B></a> Use a Conditional Define to
enable user configuration of code repetition based on need rather than some
"reasonable" upper limit</P>
<pre>#ifndef MAKE_TYPE_LIST_MAX_LENGTH
#define MAKE_TYPE_LIST_MAX_LENGTH 8
#endif
</pre>
<P>Now the user can configure the make_type_list primitive without modifying library
code.</P>
<HR>
<P><B><a name="Token Look-Up"></a><a href="examples_preprocessed.htm#Token Look-Up">EXAMPLE</a>:</B>
Use BOOST_PP_REPEAT and a Token Look-Up Function to eliminate categorical
repetition</P>
<pre>// CAVEAT: My compiler is not standard on arithmetic types.
#define ARITHMETIC_TYPE(I) ARITHMETIC_TYPE##I
#define ARITHMETIC_TYPE0 bool
#define ARITHMETIC_TYPE1 char
#define ARITHMETIC_TYPE2 signed char
#define ARITHMETIC_TYPE3 unsigned char
#define ARITHMETIC_TYPE4 short
#define ARITHMETIC_TYPE5 unsigned short
#define ARITHMETIC_TYPE6 int
#define ARITHMETIC_TYPE7 unsigned int
#define ARITHMETIC_TYPE8 long
#define ARITHMETIC_TYPE9 unsigned long
#define ARITHMETIC_TYPE10 float
#define ARITHMETIC_TYPE11 double
#define ARITHMETIC_TYPE12 long double
#define ARITHMETIC_TYPE_CNT 13
// ...
#define BOOST_PP_DEF(I,_)\
catch (ARITHMETIC_TYPE(I) t)\
{ report_typeid(t);\
report_value(t);\
}
BOOST_PP_REPEAT
( ARITHMETIC_TYPE_CNT
, BOOST_PP_DEF
, _
)
#undef BOOST_PP_DEF
// ...
</pre>
<P><B>NOTE:</B> The repetition of the above
example can be eliminated using template metaprogramming <A href="bibliography.htm#[Czarnecki]">[Czarnecki]</A>&nbsp;as well. However
categorical repetition of operator tokens can not be completely eliminated by
using template metaprogramming.</P>
<HR>
<P><B><a name="2ND_REPEAT"></a><a href="examples_preprocessed.htm#2ND_REPEAT">EXAMPLE</a>:</B>
Use BOOST_PP_REPEAT to avoid O(N*N) repetition</P>
<pre>#ifndef MAX_VEC_ARG_CNT
#define MAX_VEC_ARG_CNT 8
#endif
// ...
#define ARG_FUN(I,_) BOOST_PP_COMMA_IF(I) T a##I
#define ASSIGN_FUN(I,_) (*this)[I] = a##I;
#define DEF_VEC_CTOR_FUN(I,_)\
vec( BOOST_PP_REPEAT(I,ARG_FUN,_) )\
{ BOOST_PP_REPEAT(I,ASSIGN_FUN,_)\
}
BOOST_PP_REPEAT
( BOOST_PP_INC(MAX_VEC_ARG_CNT)
, DEF_VEC_CTOR_FUN
, _
)
#undef ARG_FUN
#undef ASSIGN_FUN
#undef DEF_VEC_CTOR_FUN
// ...
</pre>
<P><B>HOW:</B> BOOST_PP_REPEAT is implemented in a special way to enable
automatic recursion.</P>
<HR>
<P><a name="IF"></a><a href="examples_preprocessed.htm#IF"><B>EXAMPLE:</B></a> Use BOOST_PP_IF to implement special case for the first element</P>
<pre>#define BOOST_PP_COMMA_IF(C)\
BOOST_PP_IF(C,BOOST_PP_COMMA,BOOST_PP_EMPTY)()
BOOST_PP_IF(0,true,false) == false;
BOOST_PP_IF(1,true,false) == true;
</pre>
<P>BOOST_PP_IF enables convenient generation of lists using BOOST_PP_REPEAT.</P>
<P><B>NOTE:</B> THEN and ELSE don't have to be macros. However, if at least one
of them is a function-like macro and you want it to be expanded conditionally,
you have to make the other parameter a function-like macro, too. This can often
be done using BOOST_PP_IDENTITY. Consider the following example (by
Aleksey Gurtovoy):</P>
<pre>#define NUMBERED_EXPRESSION(I,X)\
BOOST_PP_IF \
( I \
, BOOST_PP_IDENTITY(X##I) \
, BOOST_PP_EMPTY \
)()</pre>
<P><b>NOTE:</b> Like in the above implementation of COMMA_IF, the result of IF
is often invoked and not the THEN and ELSE parameters. If the parameters were
invoked, the code would not expand correctly, because the EMPTY parameter would
get expanded to nothing before the IF would be properly expanded.</P>
<P><b>HOW:</b> BOOST_PP_IF is defined for the entire repeat range (pseudo
code):</P>
<pre>#define BOOST_PP_IF(C,THEN,ELSE) BOOST_PP_IF##C(THEN,ELSE)
#define BOOST_PP_IF0(THEN,ELSE) ELSE
#define BOOST_PP_IF1(THEN,ELSE) THEN
#define BOOST_PP_IF2(THEN,ELSE) THEN
// ...
</pre>
<hr>
<p><a name="Arithmetic"></a><a href="examples_preprocessed.htm#Arithmetic"><B>EXAMPLE:</B></a> Use arithmetic, logical and comparison operations when necessary</p>
<P>The PREPROCESSOR library supports saturated arithmetic, logical and
comparison operations on decimal integer literals in the range [0,BOOST_PP_LIMIT_MAG].</p>
<p>Suppose that you want to generate a numbered lists with a special element inserted
at a desired position. For example: E0, E1, S, E2. Consider the following example:</p>
<pre>#define SPECIAL_NUMBERED_LIST(N,I,ELEM,SPECIAL)\
BOOST_PP_ASSERT_MSG(BOOST_PP_LESS(I,N),BAD PARAMS FOR SPECIAL_NUMBERED_LIST!)\
BOOST_PP_ENUM_PARAMS(I,ELEM)\
BOOST_PP_COMMA_IF(I) SPECIAL\
BOOST_PP_REPEAT(BOOST_PP_SUB(\
BOOST_PP_DEC(N),I),SPECIAL_NUMBERED_LIST_HELPER,(ELEM,I))
#define SPECIAL_NUMBERED_LIST_HELPER(I,ELEM_BASE)\
,\
BOOST_PP_CAT\
( BOOST_PP_TUPLE_ELEM(2,0,ELEM_BASE)\
, BOOST_PP_ADD\
( I\
, BOOST_PP_TUPLE_ELEM(2,1,ELEM_BASE)\
)\
)
SPECIAL_NUMBERED_LIST(3,0,E,S)
SPECIAL_NUMBERED_LIST(3,1,E,S)
SPECIAL_NUMBERED_LIST(3,2,E,S)
SPECIAL_NUMBERED_LIST(3,3,E,S)
</pre>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="http://www.housemarque.com">Housemarque Oy</a> 2002</i></p>
<p>Permission to copy, use, modify, sell and distribute this document is granted
provided this copyright notice appears in all copies. This document is provided
"as is" without express or implied warranty, and with no claim as to its suitability
for any purpose.</p>
</body>
</html>

View File

@ -1,69 +0,0 @@
/* Copyright (C) 2001
* Housemarque Oy
* http://www.housemarque.com
*
* Permission to copy, use, modify, sell and distribute this software is
* granted provided this copyright notice appears in all copies. This
* software is provided "as is" without express or implied warranty, and
* with no claim as to its suitability for any purpose.
*
* See http://www.boost.org for most recent version.
*/
#include <boost/preprocessor/arithmetic.hpp>
#include <boost/preprocessor/comparison.hpp>
#include <boost/preprocessor/limits.hpp>
#include <boost/preprocessor/min.hpp>
#include <boost/preprocessor/max.hpp>
#include <libs/preprocessor/test/test.hpp>
/* *** */
TEST_B BOOST_PP_ADD(2,3) == 5 TEST_E
TEST_B BOOST_PP_ADD(21,BOOST_PP_SUB(BOOST_PP_LIMIT_MAG,20)) == BOOST_PP_LIMIT_MAG TEST_E
TEST_B BOOST_PP_SUB(11,0) == 11 TEST_E
TEST_B BOOST_PP_SUB(12,1) == 11 TEST_E
TEST_B BOOST_PP_SUB(3,4) == 0 TEST_E
TEST_B BOOST_PP_MUL(0,1) == 0 TEST_E
TEST_B BOOST_PP_MUL(1,0) == 0 TEST_E
TEST_B BOOST_PP_MUL(1,1) == 1 TEST_E
TEST_B BOOST_PP_MUL(4,3) == 12 TEST_E
TEST_B BOOST_PP_DIV(2,1) == 2 TEST_E
TEST_B BOOST_PP_DIV(0,5) == 0 TEST_E
TEST_B BOOST_PP_DIV(7,3) == 2 TEST_E
TEST_B BOOST_PP_EQUAL(1,0) == 0 TEST_E
TEST_B BOOST_PP_EQUAL(10,10) == 1 TEST_E
TEST_B BOOST_PP_NOT_EQUAL(3,4) == 1 TEST_E
TEST_B BOOST_PP_NOT_EQUAL(7,7) == 0 TEST_E
TEST_B BOOST_PP_LESS_EQUAL(6,7) == 1 TEST_E
TEST_B BOOST_PP_LESS_EQUAL(8,1) == 0 TEST_E
TEST_B BOOST_PP_LESS_EQUAL(5,5) == 1 TEST_E
TEST_B BOOST_PP_GREATER_EQUAL(6,7) == 0 TEST_E
TEST_B BOOST_PP_GREATER_EQUAL(10,10) == 1 TEST_E
TEST_B BOOST_PP_GREATER_EQUAL(8,1) == 1 TEST_E
TEST_B BOOST_PP_LESS(2,1) == 0 TEST_E
TEST_B BOOST_PP_LESS(1,1) == 0 TEST_E
TEST_B BOOST_PP_LESS(1,2) == 1 TEST_E
TEST_B BOOST_PP_GREATER(2,1) == 1 TEST_E
TEST_B BOOST_PP_GREATER(1,1) == 0 TEST_E
TEST_B BOOST_PP_GREATER(1,2) == 0 TEST_E
TEST_B BOOST_PP_MIN(1,0) == 0 TEST_E
TEST_B BOOST_PP_MIN(1,2) == 1 TEST_E
TEST_B BOOST_PP_MAX(3,2) == 3 TEST_E
TEST_B BOOST_PP_MAX(4,5) == 5 TEST_E
TEST_B BOOST_PP_MOD(5,5) == 0 TEST_E
TEST_B BOOST_PP_MOD(9,5) == 4 TEST_E
TEST_B BOOST_PP_MOD(7,4) == 3 TEST_E

View File

@ -1,28 +0,0 @@
/* Copyright (C) 2001
* Housemarque Oy
* http://www.housemarque.com
*
* Permission to copy, use, modify, sell and distribute this software is
* granted provided this copyright notice appears in all copies. This
* software is provided "as is" without express or implied warranty, and
* with no claim as to its suitability for any purpose.
*
* See http://www.boost.org for most recent version.
*/
#include <boost/preprocessor/for.hpp>
#include <boost/preprocessor/dec.hpp>
#include <libs/preprocessor/test/test.hpp>
/* *** */
#ifndef FOR_TEST_MAX
#define FOR_TEST_MAX 50
#endif
#define C(D,X) X
#define F(D,X) BOOST_PP_DEC(X)
#define I(D,X) -X
TEST_B (FOR_TEST_MAX*(FOR_TEST_MAX+1)/2)+1 BOOST_PP_FOR(FOR_TEST_MAX,C,F,I) TEST_E

View File

@ -1,57 +0,0 @@
/* Copyright (C) 2001
* Housemarque Oy
* http://www.housemarque.com
*
* Permission to copy, use, modify, sell and distribute this software is
* granted provided this copyright notice appears in all copies. This
* software is provided "as is" without express or implied warranty, and
* with no claim as to its suitability for any purpose.
*
* See http://www.boost.org for most recent version.
*/
#include <boost/preprocessor/list.hpp>
#include <boost/preprocessor/tuple/to_list.hpp>
#include <boost/preprocessor/arithmetic/add.hpp>
#include <boost/preprocessor/arithmetic/sub.hpp>
#include <boost/preprocessor/comparison/less.hpp>
#include <libs/preprocessor/test/test.hpp>
/* *** */
#define TEST_LIST BOOST_PP_TUPLE_TO_LIST(4,(4,1,5,2))
TEST_B BOOST_PP_LIST_FOLD_LEFT(BOOST_PP_SUB_D,22,TEST_LIST) == 10 TEST_E
TEST_B BOOST_PP_LIST_CAT(BOOST_PP_LIST_REVERSE(TEST_LIST)) == 2514 TEST_E
TEST_B BOOST_PP_LIST_FOLD_RIGHT(BOOST_PP_SUB_D,TEST_LIST,0) == 4 TEST_E
TEST_B BOOST_PP_LIST_CAT(BOOST_PP_LIST_REST_N(2,TEST_LIST)) == 52 TEST_E
TEST_B BOOST_PP_LIST_CAT(BOOST_PP_LIST_FIRST_N(2,TEST_LIST)) == 41 TEST_E
TEST_B BOOST_PP_LIST_AT(TEST_LIST,2) == 5 TEST_E
TEST_B BOOST_PP_LIST_SIZE(TEST_LIST) == 4 TEST_E
TEST_B BOOST_PP_LIST_CAT(BOOST_PP_LIST_TRANSFORM(BOOST_PP_ADD_D,2,TEST_LIST)) == 6374 TEST_E
TEST_B BOOST_PP_LIST_CAT(BOOST_PP_LIST_APPEND(BOOST_PP_LIST_REST(TEST_LIST),TEST_LIST)) == 1524152 TEST_E
#define F(I,P,X) +X+P
TEST_B BOOST_PP_LIST_FOR_EACH(F,1,TEST_LIST) == 16 TEST_E
#undef F
TEST_B BOOST_PP_TUPLE_ELEM(4,3,BOOST_PP_LIST_TO_TUPLE(TEST_LIST)) == 2 TEST_E
TEST_B BOOST_PP_LIST_CAT(BOOST_PP_LIST_FILTER(BOOST_PP_LESS_D,3,TEST_LIST)) == 45 TEST_E
#define F(R,X) +BOOST_PP_TUPLE_ELEM(2,0,X)+2-BOOST_PP_TUPLE_ELEM(2,1,X)
TEST_B BOOST_PP_LIST_FOR_EACH_PRODUCT(F,2,(BOOST_PP_TUPLE_TO_LIST(2,(1,0)),BOOST_PP_TUPLE_TO_LIST(2,(2,3)))) == 0 TEST_E
#undef F
TEST_B BOOST_PP_LIST_CAT(BOOST_PP_LIST_FOLD_RIGHT(BOOST_PP_LIST_APPEND_D,
BOOST_PP_TUPLE_TO_LIST(3,
(BOOST_PP_TUPLE_TO_LIST(2,(0,x)),
BOOST_PP_TUPLE_TO_LIST(4,(A,1,B,2)),
BOOST_PP_TUPLE_TO_LIST(3,(C,3,D)))),
BOOST_PP_LIST_NIL)) == 0xA1B2C3D TEST_E

View File

@ -1,40 +0,0 @@
/* Copyright (C) 2001
* Housemarque Oy
* http://www.housemarque.com
*
* Permission to copy, use, modify, sell and distribute this software is
* granted provided this copyright notice appears in all copies. This
* software is provided "as is" without express or implied warranty, and
* with no claim as to its suitability for any purpose.
*
* See http://www.boost.org for most recent version.
*/
#include <boost/preprocessor/logical.hpp>
#include <libs/preprocessor/test/test.hpp>
/* *** */
TEST_B BOOST_PP_NOT(0) == 1 TEST_E
TEST_B BOOST_PP_NOT(2) == 0 TEST_E
TEST_B BOOST_PP_AND(0,0) == 0 TEST_E
TEST_B BOOST_PP_AND(0,3) == 0 TEST_E
TEST_B BOOST_PP_AND(4,0) == 0 TEST_E
TEST_B BOOST_PP_AND(5,6) == 1 TEST_E
TEST_B BOOST_PP_OR(0,0) == 0 TEST_E
TEST_B BOOST_PP_OR(0,7) == 1 TEST_E
TEST_B BOOST_PP_OR(8,0) == 1 TEST_E
TEST_B BOOST_PP_OR(9,1) == 1 TEST_E
TEST_B BOOST_PP_XOR(0,0) == 0 TEST_E
TEST_B BOOST_PP_XOR(0,2) == 1 TEST_E
TEST_B BOOST_PP_XOR(3,0) == 1 TEST_E
TEST_B BOOST_PP_XOR(4,5) == 0 TEST_E
TEST_B BOOST_PP_NOR(0,0) == 1 TEST_E
TEST_B BOOST_PP_NOR(0,6) == 0 TEST_E
TEST_B BOOST_PP_NOR(7,0) == 0 TEST_E
TEST_B BOOST_PP_NOR(8,9) == 0 TEST_E

View File

@ -1,57 +0,0 @@
/* Copyright (C) 2001
* Housemarque Oy
* http://www.housemarque.com
*
* Permission to copy, use, modify, sell and distribute this software is
* granted provided this copyright notice appears in all copies. This
* software is provided "as is" without express or implied warranty, and
* with no claim as to its suitability for any purpose.
*
* See http://www.boost.org for most recent version.
*/
#include <boost/preprocessor/empty.hpp>
#include <boost/preprocessor/identity.hpp>
#include <boost/preprocessor/if.hpp>
#include <boost/preprocessor/expr_if.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/stringize.hpp>
#include <boost/preprocessor/tuple/elem.hpp>
#include <libs/preprocessor/test/test.hpp>
/* *** */
struct Container
{
#define BOOST_PP_DEF(CV)\
CV() int& operator[](int i) CV();
BOOST_PP_DEF(BOOST_PP_EMPTY)
BOOST_PP_DEF(BOOST_PP_IDENTITY(const))
BOOST_PP_DEF(BOOST_PP_IDENTITY(volatile))
BOOST_PP_DEF(BOOST_PP_IDENTITY(const volatile))
#undef BOOST_PP_DEF
};
/* *** */
TEST_B BOOST_PP_IF(BOOST_PP_IF(1,1,1),true,false) &&
BOOST_PP_IF(BOOST_PP_IF(0,0,0),false,true) TEST_E
/* *** */
TEST_B BOOST_PP_EXPR_IF(1,1) TEST_E
/* *** */
TEST_B BOOST_PP_CAT(BOOST_PP_IF(1,tru,fals), e) TEST_E
/* *** */
char stringize_test[3] = BOOST_PP_STRINGIZE(__LINE__);
/* *** */
TEST_B BOOST_PP_TUPLE_ELEM(2,0,(1,0)) TEST_E

View File

@ -1,62 +0,0 @@
/* Copyright (C) 2001
* Housemarque Oy
* http://www.housemarque.com
*
* Permission to copy, use, modify, sell and distribute this software is
* granted provided this copyright notice appears in all copies. This
* software is provided "as is" without express or implied warranty, and
* with no claim as to its suitability for any purpose.
*
* See http://www.boost.org for most recent version.
*/
#include <boost/preprocessor/enum_params.hpp>
#include <boost/preprocessor/enum_shifted_params.hpp>
#include <boost/preprocessor/inc.hpp>
#include <boost/preprocessor/repeat_from_to.hpp>
#include <libs/preprocessor/test/test.hpp>
/* *** */
/* RATIONALE:
* - BOOST_PP_REPEAT, BOOST_PP_ENUM, BOOST_PP_REPEAT_FROM_TO and must work
* recursively together.
* - BOOST_PP_REPEAT is already tested with
* BOOST_PP_ENUM_PARAMS.
* - The tested repeat count should exceed imaginable usage.
* - Testing the generation of is_function_helper()s upto 40 arguments should
* be sufficient in this case. Many compilers may fail the repetition tests
* (at least with higher counts). However, the primary purpose of the
* repetition primitives is to enable configurability with reasonable
* defaults, and not necessarily "the most impressive repetition".
* - ENUM_SHIFTED_PARAMS must be tested so that the shifted range is shown to
* be correct.
*/
#ifndef IS_FUNCTION_HELPER_TEST_MAX
#define IS_FUNCTION_HELPER_TEST_MAX 40
#endif
typedef char yes_type;
#define IS_FUNCTION_HELPER(I,A)\
template\
<BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(I),class P)>\
yes_type is_function_helper(\
P0 (*)(BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_INC(I),P)));
BOOST_PP_REPEAT(BOOST_PP_INC(IS_FUNCTION_HELPER_TEST_MAX),IS_FUNCTION_HELPER,A)
#undef IS_FUNCTION_HELPER
/* *** */
#define ELEM(_,X) X
#define COL(I,_) - BOOST_PP_TUPLE_ELEM(2,0,(BOOST_PP_ENUM(2,ELEM,I)))
#define ROW(I,_) BOOST_PP_REPEAT(I,COL,_)
TEST_B 0 == (1 +1+2 +1+2+3) BOOST_PP_REPEAT_FROM_TO(2,5,ROW,_) TEST_E
#undef ROW
#undef COL
#undef ELEM

View File

@ -1,56 +0,0 @@
/* Copyright (C) 2001
* Housemarque Oy
* http://www.housemarque.com
*
* Permission to copy, use, modify, sell and distribute this software is
* granted provided this copyright notice appears in all copies. This
* software is provided "as is" without express or implied warranty, and
* with no claim as to its suitability for any purpose.
*
* See http://www.boost.org for most recent version.
*/
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/enum_params.hpp>
#include <boost/preprocessor/enum_params_with_a_default.hpp>
#include <boost/preprocessor/enum_params_with_defaults.hpp>
#include <boost/preprocessor/repeat_from_to.hpp>
#include <libs/preprocessor/test/test.hpp>
/* *** */
/* RATIONALE:
* - All forms of ENUM_PARAMS must be tested with 0 and n, where n is
* sufficiently large to exceed imaginable usage like. 50 should be
* suffient in this case.
*/
#ifndef ENUM_PARAMS_TEST_MAX
#define ENUM_PARAMS_TEST_MAX 50
#endif
#define CONSTANT(I,A) BOOST_PP_CAT(A,I) = I
const int BOOST_PP_ENUM(ENUM_PARAMS_TEST_MAX, CONSTANT, default_param_);
#undef CONSTANT
#define TEST_ENUM_PARAMS(N)\
void BOOST_PP_CAT(test_enum_params,N)(\
BOOST_PP_ENUM_PARAMS(N, int x));\
void BOOST_PP_CAT(test_enum_params_with_a_default,N)(\
BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(N, int x, 0));\
void BOOST_PP_CAT(test_enum_params_with_defaults,N)(\
BOOST_PP_ENUM_PARAMS_WITH_DEFAULTS(N, int x, default_param_));
TEST_ENUM_PARAMS(0)
TEST_ENUM_PARAMS(ENUM_PARAMS_TEST_MAX)
#undef TEST_ENUM_PARAMS
template<BOOST_PP_ENUM_PARAMS(ENUM_PARAMS_TEST_MAX,class T)>
struct no_rescan;
/* *** */
#define F(I,P) P I
TEST_B 1 + (4+5+6) BOOST_PP_REPEAT_FROM_TO(4,7,F,-) TEST_E
#undef F

View File

@ -1,28 +0,0 @@
#ifndef BOOST_LIBS_PREPROCESSOR_TEST_TEST_HPP
#define BOOST_LIBS_PREPROCESSOR_TEST_TEST_HPP
/* Copyright (C) 2001
* Housemarque Oy
* http://www.housemarque.com
*
* Permission to copy, use, modify, sell and distribute this software is
* granted provided this copyright notice appears in all copies. This
* software is provided "as is" without express or implied warranty, and
* with no claim as to its suitability for any purpose.
*
* See http://www.boost.org for most recent version.
*/
#include <boost/preprocessor/cat.hpp>
/* The TEST macro has been broken into two pieces to avoid
* double expansion:
* 1. as a macro argument
* 2. rescan
*/
#define TEST_B typedef int BOOST_PP_CAT(test_,__LINE__)[((
#define TEST_E )==1) ? 1 : -1];
#define MACRO(X) X
#define MACRO_ARGS(X) (X)
#endif

View File

@ -1,12 +0,0 @@
/* Copyright (C) 2002 Vesa Karvonen
*
* Permission to copy, use, modify, sell and distribute this software is
* granted provided this copyright notice appears in all copies. This
* software is provided "as is" without express or implied warranty, and
* with no claim as to its suitability for any purpose.
*
* See http://www.boost.org for most recent version.
*/
/* This simply attempts to include all preprocessor library headers. */
#include <boost/preprocessor.hpp>