2020-08-23 20:12:06 -04:00
|
|
|
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
|
|
|
|
|
<html>
|
|
|
|
|
|
<head>
|
|
|
|
|
|
<meta content="text/html; charset=windows-1252"
|
|
|
|
|
|
http-equiv="content-type">
|
|
|
|
|
|
<title>limitations.html</title>
|
|
|
|
|
|
<link rel="stylesheet" type="text/css" href="../styles.css">
|
|
|
|
|
|
<style>
|
|
|
|
|
|
u { font-weight: normal; text-decoration: none; }
|
|
|
|
|
|
</style>
|
|
|
|
|
|
</head>
|
|
|
|
|
|
<body>
|
|
|
|
|
|
<h3>Preprocessor library limitations</h3>
|
|
|
|
|
|
<blockquote>
|
|
|
|
|
|
<p>The Boost preprocessor library has always had certain specific
|
|
|
|
|
|
limitations, which are specifically explained in other areas of
|
|
|
|
|
|
this documentation and are implemented as object-like macros in
|
|
|
|
|
|
the header file config/limits.hpp. These limitations largely
|
|
|
|
|
|
detail the maximum number for certain features in the library.
|
|
|
|
|
|
These maximums have been chosen in order to accommodate the
|
|
|
|
|
|
large number of compilers and their preprocessors which the
|
|
|
|
|
|
library supports, in order to provide a lowest common set of
|
|
|
|
|
|
limits with which the vast majority of these compilers can work
|
|
|
|
|
|
successfully. This reflects the situation that the C/C++
|
|
|
|
|
|
standard rarely specifies preprocessor limitations for compilers
|
|
|
|
|
|
but rather allows each compiler to choose whatever limitations
|
|
|
|
|
|
it deems necessary in its preprocessor. While this allows
|
|
|
|
|
|
individual compilers to largely choose what preprocessor
|
|
|
|
|
|
limitations it deems necessary, it makes it more difficult for a
|
|
|
|
|
|
preprocessor library like this one to work with a large number
|
|
|
|
|
|
of preprocessors across a number of operating system platforms.
|
|
|
|
|
|
The difficulty of this situation means that this Boost
|
|
|
|
|
|
preprocessor library has chosen fairly conservative limitations.<br>
|
|
|
|
|
|
</p>
|
|
|
|
|
|
<p>In fact the limitation macros, although indeed existing, have
|
|
|
|
|
|
never previously been used internally in the preprocessor
|
|
|
|
|
|
library code. Instead while the limitation macros do indeed
|
|
|
|
|
|
exist, the library has internally used fixed numbers equivalent
|
|
|
|
|
|
to what these macros represent. This historical situation most
|
|
|
|
|
|
probably reflects the fact that the library did not want the
|
|
|
|
|
|
end-user's possibly changing the limitations, by redefining the
|
|
|
|
|
|
macros in config/limits.hpp, to change how the library works and
|
|
|
|
|
|
therefore cause problems in using the library.<br>
|
|
|
|
|
|
</p>
|
|
|
|
|
|
<p>This situation has now changed and a number of the limitation
|
|
|
|
|
|
macros specified in config/limits.hpp are now used internally in
|
2020-09-14 18:26:49 -04:00
|
|
|
|
the library code when the preprocessor is C++ standard
|
|
|
|
|
|
conforming. This topic is therefore about how an end-user can
|
|
|
|
|
|
change the limitations of the library.<br>
|
2020-08-23 20:12:06 -04:00
|
|
|
|
</p>
|
|
|
|
|
|
</blockquote>
|
|
|
|
|
|
<h4>Type of limitations</h4>
|
|
|
|
|
|
<blockquote>
|
|
|
|
|
|
<p>The type of limitations in the Boost preprocessor library can
|
|
|
|
|
|
be divided as:<br>
|
|
|
|
|
|
</p>
|
|
|
|
|
|
<ul>
|
|
|
|
|
|
<li>Numbers</li>
|
|
|
|
|
|
<li>Sizes</li>
|
|
|
|
|
|
<li>Loops</li>
|
|
|
|
|
|
<li>Iterations</li>
|
|
|
|
|
|
</ul>
|
|
|
|
|
|
The library has support for numbers. This supports basic
|
|
|
|
|
|
arithmetic, comparisons, and logical operations. This support is
|
|
|
|
|
|
documented by the macro BOOST_PP_LIMIT_MAG, where 'MAG' is short
|
|
|
|
|
|
for "MAGNITUDE'. The current fixed maximum value is 256. This
|
|
|
|
|
|
means that the library supports numerical operations in the range
|
|
|
|
|
|
between 0 and 256.<br>
|
|
|
|
|
|
<br>
|
|
|
|
|
|
The library has support for the maximum sizes of higher level
|
|
|
|
|
|
types. These types are arrays, lists, seqs, tuples, and variadic
|
|
|
|
|
|
data. By sizes for these higher level constructs it is meant the
|
|
|
|
|
|
maximum number of elements of which a higher level construct can
|
|
|
|
|
|
consist. For arrays and tuples this value is documented by the
|
|
|
|
|
|
macro BOOST_PP_LIMIT_TUPLE while for variadic data this value is
|
|
|
|
|
|
documented by the macro BOOST_PP_LIMIT_VARIADIC. In both these
|
|
|
|
|
|
cases the current fixed maximum value is 64. For seqs the value is
|
|
|
|
|
|
documented by the macro BOOST_PP_LIMIT_SEQ, whose current fixed
|
|
|
|
|
|
value is 256. For lists there has never been a limitation macro
|
|
|
|
|
|
but in actual fact the limitation on the maximum number of list
|
|
|
|
|
|
elements is defined by the maximum number given above for
|
|
|
|
|
|
BOOST_PP_LIMIT_MAG. So a list, like a seq, has a default maximum
|
|
|
|
|
|
of 256 elements. The reason that the maximum number of elements
|
|
|
|
|
|
for arrays, tuples, and variadic data is 64 while for seqs and
|
|
|
|
|
|
lists it is the much larger value of 256 is because the
|
|
|
|
|
|
implementation of the former constructs often involves passing the
|
|
|
|
|
|
likewise number as parameters to internal macros and a number of
|
|
|
|
|
|
compilers have placed limitations on the number of parameters a
|
|
|
|
|
|
macro can have; so the much safer 64 was chosen so as to be able
|
|
|
|
|
|
to work with these compilers.<br>
|
|
|
|
|
|
<br>
|
|
|
|
|
|
The looping constructs consist of the control structure
|
|
|
|
|
|
BOOST_PP_WHILE and the repetition constructs BOOST_PP_FOR and
|
|
|
|
|
|
BOOST_PP_REPEAT. Each of these have a limitation macro, all
|
|
|
|
|
|
currently set to 256. This means that the loop can run at maximum
|
|
|
|
|
|
256 times. The corresponding limitation macros are
|
|
|
|
|
|
BOOST_PP_LIMIT_WHILE, BOOST_PP_LIMIT_FOR, and
|
|
|
|
|
|
BOOST_PP_LIMIT_REPEAT.<br>
|
|
|
|
|
|
<br>
|
|
|
|
|
|
Iteration constructs consist of local iteration and file iteration
|
|
|
|
|
|
constructs.The specifics are more fully discussed in their own
|
|
|
|
|
|
topics. The corresponding macro is BOOST_PP_LIMIT_ITERATION whose
|
|
|
|
|
|
value is 256.<br>
|
|
|
|
|
|
</blockquote>
|
|
|
|
|
|
<h4> Limitation dependencies</h4>
|
|
|
|
|
|
<blockquote>A number of the limitations are actually dependent on
|
|
|
|
|
|
other limitations. These are:<br>
|
|
|
|
|
|
<ul>
|
|
|
|
|
|
<li>BOOST_PP_LIMIT_MAG depends on BOOST_PP_LIMIT_WHILE. All the
|
|
|
|
|
|
arithmetic macros except for BOOST_PP_INC and BOOST_PP_DEC
|
|
|
|
|
|
depend on looping using BOOST_PP_WHILE. Similarly all the
|
|
|
|
|
|
comparison macros except for BOOST_PP_EQUAL and
|
|
|
|
|
|
BOOST_PP_NOT_EQUAL depend on BOOST_PP_WHILE. So whatever is
|
|
|
|
|
|
the value for BOOST_PP_LIMIT_MAG is also the value for
|
|
|
|
|
|
BOOST_PP_LIMIT_WHILE.</li>
|
2020-09-19 02:24:44 -04:00
|
|
|
|
<li>BOOST_PP_LIMIT_TUPLE depends on BOOST_PP_LIMIT_VARIADIC,
|
|
|
|
|
|
since array/tuple functionality often ends up calling variadic data
|
2020-08-23 20:12:06 -04:00
|
|
|
|
functionality. So while BOOST_PP_LIMIT_TUPLE can be smaller
|
|
|
|
|
|
than BOOST_PP_LIMIT_VARIADIC it can never be larger.<br>
|
|
|
|
|
|
</li>
|
|
|
|
|
|
<li>BOOST_PP_LIMIT_SEQ depends on BOOST_PP_LIMIT_MAG since the
|
|
|
|
|
|
total size of a seq must be at most the largest number. So
|
|
|
|
|
|
while BOOST_PP_LIMIT_SEQ could be smaller than
|
|
|
|
|
|
BOOST_PP_LIMIT_MAG it can never be larger.</li>
|
|
|
|
|
|
<li>BOOST_PP_LIMIT_FOR, BOOST_PP_LIMIT_REPEAT, and
|
|
|
|
|
|
BOOST_PP_LIMIT_ITERATION all depend on BOOST_PP_LIMIT_MAG.
|
|
|
|
|
|
While any of these values could be smaller than
|
|
|
|
|
|
BOOST_PP_LIMIT_MAG none of them can be larger.</li>
|
|
|
|
|
|
</ul>
|
|
|
|
|
|
</blockquote>
|
|
|
|
|
|
<h4>Changing the limitations</h4>
|
|
|
|
|
|
<blockquote>
|
|
|
|
|
|
<p>Limitations can be changed by the end-user defining a
|
|
|
|
|
|
limitation macro prior to including preprocessor library header
|
|
|
|
|
|
files. This can be done either in a source file or as part of a
|
|
|
|
|
|
compiler command line.<br>
|
|
|
|
|
|
</p>
|
|
|
|
|
|
</blockquote>
|
|
|
|
|
|
<blockquote>
|
|
|
|
|
|
<p>Before specifying which limitations can be changed a number of
|
|
|
|
|
|
items need to be emphasized:<br>
|
|
|
|
|
|
</p>
|
|
|
|
|
|
<ul>
|
|
|
|
|
|
<li>The limitations which can be changed can only be done for
|
|
|
|
|
|
C++ standard conforming preprocessors. You can use the macro
|
|
|
|
|
|
BOOST_PP_IS_STANDARD, invoking it as BOOST_PP_IS_STANDARD(),
|
|
|
|
|
|
to determine if your compiler has a C++ standard conforming
|
|
|
|
|
|
preprocessor. Almost all major compilers, including gcc and
|
|
|
|
|
|
clang, have C++ standard conforming preprocessors. Most
|
|
|
|
|
|
notably the default Visual C++ compiler is not a C++ standard
|
|
|
|
|
|
conforming preprocessor, but the new preprocessor for Visual
|
|
|
|
|
|
C++, available in Visual Studio 2019 and above, is a C++
|
|
|
|
|
|
standard conforming preprocessor. If you change a limitation
|
|
|
|
|
|
for a compiler that is not a C++ standard conforming
|
|
|
|
|
|
preprocessor the change is simply ignored and no preprocessor
|
2020-09-14 18:26:49 -04:00
|
|
|
|
error will occur. This is because any non-conforming
|
|
|
|
|
|
preprocessor does not actually include or use the macros in
|
|
|
|
|
|
the config/limits.hpp file.<br>
|
2020-08-23 20:12:06 -04:00
|
|
|
|
</li>
|
|
|
|
|
|
<li>WARNING ! WARNING ! WARNING ! Increasing limitations may
|
|
|
|
|
|
mean that preprocessors may fail because the compiler itself
|
|
|
|
|
|
can not handle the increase in the limitations. This may occur
|
|
|
|
|
|
because the compiler has an internal limit on the number of
|
|
|
|
|
|
parameters that can be passed to a macro, the number of nested
|
|
|
|
|
|
macro invocations, or even the amount of memory needed for the
|
|
|
|
|
|
preprocessor to expand a macro.</li>
|
|
|
|
|
|
<li>Except for possibly first including the preprocessor header
|
|
|
|
|
|
boost/preprocessor/config/config.hpp, changing any limitation
|
|
|
|
|
|
must be done before including Boost preprocessor headers in a
|
|
|
|
|
|
TU ( translation unit ) to work properly. Attempting to change
|
|
|
|
|
|
a limitation after including Boost preprocessor headers will
|
|
|
|
|
|
at worst lead to preprocessor errors and at best lead to UB (
|
|
|
|
|
|
undefined behavior ).</li>
|
|
|
|
|
|
<li>Limitations can only be changed to specific values as given
|
|
|
|
|
|
below. Attempting to change limitations to other than the
|
|
|
|
|
|
specific values will lead to the change being ignored or, if
|
|
|
|
|
|
incorrectly done after including Boost preprocessor headers, a
|
|
|
|
|
|
preprocessor error.</li>
|
|
|
|
|
|
</ul>
|
|
|
|
|
|
All the limitations whose default value is 256 can be changed to
|
|
|
|
|
|
either 512 or 1024, except for BOOST_PP_LIMIT_WHILE which can not
|
|
|
|
|
|
be changed.<br>
|
|
|
|
|
|
The two limitations whose default value is 64 can be changed to
|
|
|
|
|
|
128 or 256.<br>
|
|
|
|
|
|
<br>
|
|
|
|
|
|
For the individual limitations:<br>
|
|
|
|
|
|
<ul>
|
|
|
|
|
|
<li>BOOST_PP_LIMIT_MAG : When you change this limitation the
|
|
|
|
|
|
value of BOOST_PP_LIMIT_WHILE also changes so that it is equal
|
|
|
|
|
|
to BOOST_PP_LIMIT_MAG. This is because numerical computations
|
|
|
|
|
|
depend on the BOOST_PP_WHILE loop, and therefore
|
|
|
|
|
|
BOOST_PP_LIMIT_WHILE itself can not be changed. Also when you
|
|
|
|
|
|
change the BOOST_PP_LIMIT_MAG limitation the value of
|
|
|
|
|
|
BOOST_PP_LIMIT_SEQ, if it has not been also changed to be less
|
|
|
|
|
|
than BOOST_PP_LIMIT_MAG, is also changed to the value of
|
|
|
|
|
|
BOOST_PP_LIMIT_MAG. This is so that seqs, like lists, will
|
|
|
|
|
|
normally have the same maximum number of elements, as defined
|
|
|
|
|
|
by BOOST_PP_LIMIT_MAG, unless you decide otherwise and change
|
|
|
|
|
|
the BOOST_PP_LIMIT_SEQ yourself.<br>
|
|
|
|
|
|
</li>
|
|
|
|
|
|
<li>BOOST_PP_LIMIT_TUPLE: When you change this limitation the
|
|
|
|
|
|
value of BOOST_PP_LIMIT_VARIADIC also changes so that it is at
|
|
|
|
|
|
least equal to BOOST_PP_LIMIT_TUPLE if the value of
|
|
|
|
|
|
BOOST_PP_LIMIT_VARIADIC has not also been changed to be
|
|
|
|
|
|
greater than BOOST_PP_LIMIT_TUPLE. This is because
|
2020-09-19 02:24:44 -04:00
|
|
|
|
tuples/arrays depend on variadic functionality.</li>
|
2020-08-23 20:12:06 -04:00
|
|
|
|
<li>BOOST_PP_LIMIT_SEQ, BOOST_PP_LIMIT_FOR,
|
|
|
|
|
|
BOOST_PP_LIMIT_REPEAT, BOOST_PP_LIMIT_ITERATION: If you try to
|
|
|
|
|
|
set any of these values greater than the BOOST_PP_LIMIT_MAG
|
|
|
|
|
|
value, the particular limitation is set to equal the value of
|
|
|
|
|
|
BOOST_PP_LIMIT_MAG. This is because all of these limits depend
|
|
|
|
|
|
on the range of numerical values.</li>
|
|
|
|
|
|
</ul>
|
|
|
|
|
|
</blockquote>
|
|
|
|
|
|
<h4>Other considerations</h4>
|
|
|
|
|
|
<blockquote>
|
|
|
|
|
|
<p>There is no necessity to change any limitation if you are happy
|
|
|
|
|
|
with its default value. However if you decide to increase a
|
|
|
|
|
|
limitation you should be aware that doing so can affect both the
|
|
|
|
|
|
amount of memory used by the preprocessor and the speed in which
|
|
|
|
|
|
preprocessing is accomplished. In the first case some
|
|
|
|
|
|
preprocessors have been known to run out of memory if a
|
|
|
|
|
|
limitation value is increased, even though this should really
|
|
|
|
|
|
never happen in modern computer systems. In the latter case
|
|
|
|
|
|
preprocessing might become so slow that trying to use the
|
|
|
|
|
|
library with some increased limitation, and have your
|
|
|
|
|
|
preprocessing finish in some reasonable amount of time, becomes
|
|
|
|
|
|
impossible. The latter can occur when you are using lists or
|
|
|
|
|
|
seqs and while cycling through a large number of elements you
|
|
|
|
|
|
are also doing time consuming operations on each element value
|
|
|
|
|
|
which generates further macro looping. Nearly all arithmetic and
|
|
|
|
|
|
comparison operations involve further macro looping.<br>
|
|
|
|
|
|
</p>
|
|
|
|
|
|
<p>For lists and seqs there is functionality which uses the
|
|
|
|
|
|
BOOST_PP_FOR macro. If the maximum size for lists and seqs is
|
|
|
|
|
|
increased, by using BOOST_PP_LIMIT_MAG macro, you may also need
|
|
|
|
|
|
to define BOOST_PP_LIMIT_FOR to increase the maximum number of
|
|
|
|
|
|
'for' loops in order to cycle through all lists or seqs using
|
|
|
|
|
|
this functionality.<br>
|
|
|
|
|
|
</p>
|
|
|
|
|
|
<p>The BOOST_PP_WHILE construct is used internally for looping by
|
|
|
|
|
|
nearly all arithmetic and comparison macros as well as
|
|
|
|
|
|
internally by a number of other macros in the library which loop
|
|
|
|
|
|
through elements. While the construct can be called from within
|
|
|
|
|
|
an already running BOOST_PP_WHILE loop, it is possible to run
|
|
|
|
|
|
out of BOOST_PP_WHILE loops when this happens. In order to solve
|
|
|
|
|
|
this problem you can specify a BOOST_PP_LIMIT_MAG which is
|
|
|
|
|
|
larger than the maximum number you will ordinarily use. This
|
|
|
|
|
|
will give you twice the number of BOOST_PP_WHILE loops and will
|
|
|
|
|
|
keep you from running out of loops if you have to do arithmetic
|
|
|
|
|
|
computations while cycling through lists and seqs and the number
|
|
|
|
|
|
of lists and/or seqs you cycle through is anywhere near your
|
|
|
|
|
|
original maximum.<br>
|
|
|
|
|
|
</p>
|
|
|
|
|
|
</blockquote>
|
2020-09-14 18:26:49 -04:00
|
|
|
|
<h4>Testing limitations</h4>
|
|
|
|
|
|
<blockquote>
|
|
|
|
|
|
<p>The default testing of the preprocessor library, using Boost
|
|
|
|
|
|
Build's b2 command in the preprocessor test directory, only
|
|
|
|
|
|
tests the default limitations. If you want to test, within the
|
|
|
|
|
|
test directory, any of the non-default limitations which may be
|
|
|
|
|
|
set, you can do so by invoking the b2 command with any of these
|
|
|
|
|
|
explicit targets:<br>
|
|
|
|
|
|
</p>
|
|
|
|
|
|
<ul>
|
|
|
|
|
|
<li>preprocessor_128 : arrays, tuples, and variadics with up to
|
|
|
|
|
|
128 elements</li>
|
|
|
|
|
|
<li>preprocessor_256 : arrays, tuples, and variadics with up to
|
|
|
|
|
|
256 elements</li>
|
|
|
|
|
|
<li>preprocessor_512 : numbers, lists, seqs, looping, and
|
|
|
|
|
|
iteration constructs with 512 maximum</li>
|
|
|
|
|
|
<li>preprocessor_1024 : numbers, lists, seqs, looping, and
|
|
|
|
|
|
iteration constructs with 1024 maximum</li>
|
|
|
|
|
|
<li>preprocessor_tup : both the first and second items in this
|
|
|
|
|
|
list</li>
|
|
|
|
|
|
<li>preprocessor_num : both the third and fourth items in this
|
|
|
|
|
|
list</li>
|
|
|
|
|
|
<li>preprocessor_limits : all preprocessor limitations</li>
|
|
|
|
|
|
</ul>
|
|
|
|
|
|
If you invoke b2 with the last preprocessor_limits target your
|
|
|
|
|
|
testing may take awhile for your compiler. When you choose one of
|
|
|
|
|
|
the above targets, as in <code>'b2 preprocessor_limits'</code>,
|
|
|
|
|
|
the default tests are not run. If you want the default tests run,
|
|
|
|
|
|
along with any of the targets such as preprocessor_limits, your
|
|
|
|
|
|
command would be <code>'b2 . preprocessor_limits'</code>, where
|
|
|
|
|
|
the '.' notation means all the non-explicit ( aka default )
|
|
|
|
|
|
targets.<br>
|
|
|
|
|
|
</blockquote>
|
|
|
|
|
|
<blockquote> </blockquote>
|
2020-08-23 20:12:06 -04:00
|
|
|
|
<blockquote>
|
|
|
|
|
|
<ul>
|
|
|
|
|
|
</ul>
|
|
|
|
|
|
</blockquote>
|
|
|
|
|
|
<blockquote> </blockquote>
|
|
|
|
|
|
<b>See</b> <b>Also</b><br>
|
|
|
|
|
|
<ul>
|
|
|
|
|
|
<li><a href="../ref/is_standard.html">BOOST_PP_IS_STANDARD</a><br>
|
|
|
|
|
|
</li>
|
|
|
|
|
|
<li><a href="../ref/limit_mag.html">BOOST_PP_LIMIT_MAG</a></li>
|
|
|
|
|
|
<li><a href="../ref/limit_tuple.html">BOOST_PP_LIMIT_TUPLE</a></li>
|
|
|
|
|
|
<li><a href="../ref/limit_variadic.html">BOOST_PP_LIMIT_VARIADIC</a></li>
|
|
|
|
|
|
<li><a href="../ref/limit_seq.html">BOOST_PP_LIMIT_SEQ</a></li>
|
|
|
|
|
|
<li><a href="../ref/limit_while.html">BOOST_PP_LIMIT_WHILE</a></li>
|
|
|
|
|
|
<li><a href="../ref/limit_for.html">BOOST_PP_LIMIT_FOR</a></li>
|
|
|
|
|
|
<li><a href="../ref/limit_repeat.html">BOOST_PP_LIMIT_REPEAT</a></li>
|
|
|
|
|
|
<li><a href="../ref/limit_iteration.html">BOOST_PP_LIMIT_ITERATION</a><br>
|
|
|
|
|
|
</li>
|
|
|
|
|
|
</ul>
|
|
|
|
|
|
<hr size="1">
|
|
|
|
|
|
<div style="margin-left: 0px;"> <i><EFBFBD> Copyright Edward Diener 2020</i>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div style="margin-left: 0px;">
|
|
|
|
|
|
<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
|
|
|
|
|
|
copy at <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</small></p>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</body>
|
|
|
|
|
|
</html>
|