diff --git a/doc/acknowledgements.html b/doc/acknowledgements.html
new file mode 100644
index 0000000..e9ef104
--- /dev/null
+++ b/doc/acknowledgements.html
@@ -0,0 +1,55 @@
+
+
+ acknowledgements.html
+
+
+
+
Acknowledgements
+
+ The following are a few acknowledgements of people that contributed to
+ or were instrumental in the development of the library by Vesa Karnoven and myself.
+
+
Vesa Karvonen
+
+ 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 invented by him.
+ He also suggested the name for the library.
+ Many thanks to Aleksey for his insights!
+
+
+ Thanks to everyone who participated in the review: David Abrahams, Beman Dawes, Ronald Garcia, Douglas Gregor, Aleksey Gurtovoy, Jeremy Siek, and Daryle Walker.
+
+
+ Thanks to Chris Little and Mat Marcus for providing help with MWCW.
+
+
+ The original automatic recursion technique, which makes many of the library
+ primitives easier to use, was invented by Paul Mensonides.
+
+
+ The PREPROCESSOR library has been developed by Vesa Karvonen.
+
+
Paul Mensonides
+
+ Thanks to Vesa Karvonen for the original conception of the library.
+ His work, his help, and his opinions are all much appreciated.
+
+
+ Thanks also to David Abrahams for his observations and continued support.
+
+
+ The help of several other Boost developers is also greatly appreciated.
+ In particular, thanks to Aleksey Gurtovoy for his suggestions and to Ralf W. Grosse-Kunstleve for providing
+ access to several compilers for testing.
+
+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.
+
+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.
+
+ An array is a data structure consisting of a two-element tuple.
+ The first element is the number of elements in the array.
+ The second element is another tuple of the elements in the array.
+ For example,
+
+
+ (3, (a, b, c))
+
+
+ ...is an array of 3 elements--a, b, and c.
+
+
+ The primary strength of arrays is that they store their own size.
+ Because of this, access to elements does not require the size.
+ It only requires that an element exists at a certain index.
+
+
+ This allows macro parameters to be variable in size and allows data states to change
+ size without the user explicitly keeping track of the size independently.
+
+
+ Elements of an array can be extracted with BOOST_PP_ARRAY_ELEM,
+ an array's size can be extracted with BOOST_PP_ARRAY_SIZE, and
+ an array can be converted to the more primitive tuple data structure
+ with BOOST_PP_ARRAY_DATA.
+
+ A list is a simple cons-style list with a head and a tail.
+ The head of a list is an element,
+ and the tail is either another list or BOOST_PP_NIL.
+ For example,
+
+
+ (a, (b, (c, BOOST_PP_NIL)))
+
+
+ ...is a list of 3 elements--a, b, and c.
+
+
+ This allows macro parameters to be variable in size and allows data states to change
+ size without the user explicitly keeping track of the size independently.
+
+
+ Elements of a list can be extracted with
+ BOOST_PP_LIST_FIRST and BOOST_PP_LIST_REST.
+
+
+
\ No newline at end of file
diff --git a/doc/ref/add.html b/doc/ref/add.html
new file mode 100644
index 0000000..42c7d02
--- /dev/null
+++ b/doc/ref/add.html
@@ -0,0 +1,57 @@
+
+
+ BOOST_PP_ADD
+
+
+
+
+ The BOOST_PP_ADD macro expands to the sum of its arguments.
+
+
Usage
+
+ BOOST_PP_ADD(x, y)
+
+
Arguments
+
+
x
+
+ The first addend of the operation.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
y
+
+ The second addend of the operation.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
+
Remarks
+
+ If the sum of x and y is greater than BOOST_PP_LIMIT_MAG, the result is saturated to BOOST_PP_LIMIT_MAG.
+
+
+ Previously, this macro could not be used inside BOOST_PP_WHILE.
+ There is no longer any such restriction.
+ It is more efficient, however, to use BOOST_PP_ADD_D in such a situation.
+
+
+ This macro is the most efficient when x is less than or equal to y.
+ However, the efficiency gain is not worth actually comparing the two arguments prior to invocation.
+ In other words, x should be the addend that is most likely to be the largest of the two operands.
+
+ The BOOST_PP_ADD_D macro expands to the sum of its second and third arguments.
+ It reenters BOOST_PP_WHILE with maximum efficiency.
+
+
Usage
+
+ BOOST_PP_ADD_D(d, x, y)
+
+
Arguments
+
+
d
+
+ The next available BOOST_PP_WHILE iteration.
+
+
x
+
+ The first addend of the operation.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
y
+
+ The second addend of the operation.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
+
Remarks
+
+ If the sum of x and y is greater than BOOST_PP_LIMIT_MAG, the result is saturated to BOOST_PP_LIMIT_MAG.
+
+
+ This macro is the most efficient when x is less than or equal to y.
+ However, the efficiency gain is not worth actually comparing the two arguments prior to invocation.
+ In other words, x should be the addend that is most likely to be the largest of the two operands.
+
+ The BOOST_PP_AND macro expands to the logical AND of its operands.
+
+
Usage
+
+ BOOST_PP_AND(p, q)
+
+
Arguments
+
+
p
+
+ The left operand of the operation.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
q
+
+ The right operand of the operation.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
+
Remarks
+
+ If both p and q are non-zero, this macro expands to 1.
+ Otherwise, it expands to 0.
+
+
+ This macro performs a boolean conversion on each operand before performing the logical AND operation.
+ If that conversion is not necessary, use BOOST_PP_BITAND instead.
+
+ The BOOST_PP_ASSIGN_SLOT macro fully evaluates a numeric macro or expression.
+
+
Usage
+
+ #include BOOST_PP_ASSIGN_SLOT(i)
+
+
Arguments
+
+
i
+
+ The slot index that is to be assigned.
+ This value must be in the range of 1 to BOOST_PP_LIMIT_SLOT_COUNT.
+
+
+
Remarks
+
+ Prior to use, the named external argumentBOOST_PP_VALUE must be defined.
+ Also, it must expand to a numeric value that is in the range of 0 to 2^32 - 1.
+
+ The BOOST_PP_BITAND macro expands to the bitwise AND of its operands.
+
+
Usage
+
+ BOOST_PP_BITAND(x, y)
+
+
Arguments
+
+
x
+
+ The left operand of the operation.
+ This value must expand to 0 or 1.
+
+
y
+
+ The right operand of the operation.
+ This value must expand to 0 or 1.
+
+
+
Remarks
+
+ If both x and y are 1, this macro expands to 1.
+ Otherwise, it expands to 0.
+
+
+ This macro does not perform a boolean conversion on either operand before performing the bitwise AND operation.
+ If that conversion is necessary, use BOOST_PP_AND instead.
+
+ The BOOST_PP_BITNOR macro expands to the bitwise NOR of its operands.
+
+
Usage
+
+ BOOST_PP_BITNOR(x, y)
+
+
Arguments
+
+
x
+
+ The left operand of the operation.
+ This value must expand to 0 or 1.
+
+
y
+
+ The right operand of the operation.
+ This value must expand to 0 or 1.
+
+
+
Remarks
+
+ If neither x nor y is 1, this macro expands to 1.
+ Otherwise, it expands to 0.
+
+
+ This macro does not perform a boolean conversion on either operand before performing the bitwise NOR operation.
+ If that conversion is necessary, use BOOST_PP_NOR instead.
+
+ The BOOST_PP_BITOR macro expands to the bitwise OR of its operands.
+
+
Usage
+
+ BOOST_PP_BITOR(x, y)
+
+
Arguments
+
+
x
+
+ The left operand of the operation.
+ This value must expand to 0 or 1.
+
+
y
+
+ The right operand of the operation.
+ This value must expand to 0 or 1.
+
+
+
Remarks
+
+ If either x or y is 1, this macro expands to 1.
+ Otherwise, it expands to 0.
+
+
+ This macro does not perform a boolean conversion on either operand before performing the bitwise OR operation.
+ If that conversion is necessary, use BOOST_PP_OR instead.
+
+ The BOOST_PP_BITXOR macro expands to the bitwise XOR of its operands.
+
+
Usage
+
+ BOOST_PP_BITXOR(x, y)
+
+
Arguments
+
+
x
+
+ The left operand of the operation.
+ This value must expand to 0 or 1.
+
+
y
+
+ The right operand of the operation.
+ This value must expand to 0 or 1.
+
+
+
Remarks
+
+ If either x or y is 1 exclusively, this macro expands to 1.
+ Otherwise, it expands to 0.
+
+
+ This macro does not perform a boolean conversion on either operand before performing the bitwise OR operation.
+ If that conversion is necessary, use BOOST_PP_XOR instead.
+
+ The BOOST_PP_COMPL macro performs a bitwise inversion (bitwise NOT or one's complement) on its operand.
+
+
Usage
+
+ BOOST_PP_COMPL(x)
+
+
Arguments
+
+
x
+
+ The value to be converted.
+ This value must expand to 0 or 1.
+
+
+
Remarks
+
+ If x is 0, this macro expands to 1.
+ If x is 1, this it expands to 0.
+
+
+ This macro does not perform a boolean conversion on its operand before performing the inversion OR operation.
+ If that conversion is necessary, use BOOST_PP_NOT instead.
+
+ The BOOST_PP_CONFIG_EXTENDED_LINE_INFO is a user-defined macro that determines whether BOOST_PP_LINE outputs extended file-iteration state information.
+
+
Usage
+
+ #define BOOST_PP_CONFIG_EXTENDED_LINE_INFOn
+
+
Arguments
+
+
n
+
+ The value that determines if BOOST_PP_LINE outputs extended file-iteration information.
+ This value must be 0 or 1.
+
+
+
Remarks
+
+ If n is 1, BOOST_PP_LINE will output extended data.
+ By default, this macro is set to 0.
+
+ The BOOST_PP_DEDUCE_D macro manually deduces the state of the BOOST_PP_WHILE construct.
+
+
Usage
+
+ BOOST_PP_DEDUCE_D()
+
+
Remarks
+
+ This macro is intended to avoid the use of automatic-recursion at deep expansion depths.
+ Automatic-recursion at such depths can be inefficient on some preprocessors.
+ It is not intended to be used directly with the invocation of macros with a _D suffix such as:
+
+ BOOST_PP_ADD_D(BOOST_PP_DEDUCE_D(), x, y)
+
+ If it is used in this context, the _D macro will fail.
+ The _D macros directly concatenate to the d parameter that is passed to them,
+ which would prevent BOOST_PP_DEDUCE_D() from expanding.
+ Furthermore, it is pointless to use this macro in a situation such as this
+ because it would already be too late to gain any efficiency.
+
+ The BOOST_PP_DEDUCE_R macro manually deduces the state of the BOOST_PP_FOR construct.
+
+
Usage
+
+ BOOST_PP_DEDUCE_R()
+
+
Remarks
+
+ This macro is intended to avoid the use of automatic-recursion at deep expansion depths.
+ Automatic-recursion at such depths can be inefficient on some preprocessors.
+ It is not intended to be used directly with the invocation of macros with a _R suffix such as:
+
+ If it is used in this context, the _R macro will fail.
+ The _R macros directly concatenate to the r parameter that is passed to them,
+ which would prevent BOOST_PP_DEDUCE_R() from expanding.
+ Furthermore, it is pointless to use this macro in a situation such as this
+ because it would already be too late to gain any efficiency.
+
+ The BOOST_PP_DEDUCE_Z macro manually deduces the state of the BOOST_PP_REPEAT construct.
+
+
Usage
+
+ BOOST_PP_DEDUCE_Z()
+
+
Remarks
+
+ This macro is intended to avoid the use of automatic-recursion at deep expansion depths.
+ Automatic-recursion at such depths can be inefficient on some preprocessors.
+ It is not intended to be used directly with the invocation of macros with a _Z suffix such as:
+
+ If it is used in this context, the _Z macro will fail.
+ The _Z macros directly concatenate to the r parameter that is passed to them,
+ which would prevent BOOST_PP_DEDUCE_Z() from expanding.
+ Furthermore, it is pointless to use this macro in a situation such as this
+ because it would already be too late to gain any efficiency.
+
+ The BOOST_PP_DIV macro expands to the quotient of its arguments.
+
+
Usage
+
+ BOOST_PP_DIV(x, y)
+
+
Arguments
+
+
x
+
+ The dividend (numerator) of the operation.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
y
+
+ The divisor (denominator) of the operation.
+ Valid values range from 1 to BOOST_PP_LIMIT_MAG.
+
+
+
Remarks
+
+ Previously, this macro could not be used inside BOOST_PP_WHILE.
+ There is no longer any such restriction.
+ It is more efficient, however, to use BOOST_PP_DIV_D in such a situation.
+
+ The BOOST_PP_ENUM macro generates a comma-separated list.
+
+
Usage
+
+ BOOST_PP_ENUM(count, macro, data)
+
+
Arguments
+
+
count
+
+ The number of repetitious calls to macro.
+ Valid values range from 0 to BOOST_PP_LIMIT_REPEAT.
+
+
macro
+
+ A ternary operation of the form macro(z, n, data).
+ This macro is expanded by BOOST_PP_ENUM with the next available repetition depth,
+ the current repetition number, and the auxiliary data argument.
+
+
data
+
+ Auxiliary data passed to macro.
+
+
+
Remarks
+
+ This macro expands to the comma-separated sequence:
+
+ The z value that is passed to macro represents the next available repetition dimension.
+ Other macros that have _Z suffix variants internally use BOOST_PP_REPEAT--for example, BOOST_PP_ENUM_PARAMS and BOOST_PP_ENUM_PARAMS_Z.
+ Using these _Z versions is not strictly necessary, but passing the z value (that is passed to macro) to these macros allows them to reenter BOOST_PP_REPEAT with maximum efficiency.
+
+
+ To directly use this z value, rather than simply passing it to another macro, see BOOST_PP_ENUM_z.
+
+
+ Previously, this macro could not be used recursively inside BOOST_PP_REPEAT.
+ This limitation no longer exists, as the library can automatically detect the next available repetition depth.
+
+ The BOOST_PP_ENUM_BINARY_PARAMS macro generates a comma-separated list of binary parameters.
+
+
Usage
+
+ BOOST_PP_ENUM_BINARY_PARAMS(count, p1, p2)
+
+
Arguments
+
+
count
+
+ The number of parameters to generate.
+ Valid values range from 0 to BOOST_PP_LIMIT_REPEAT.
+
+
p1
+
+ The text of the first part of the parameter.
+ BOOST_PP_ENUM_BINARY_PARAMS concatenates numbers ranging from 0 to count - 1
+ to generate parameters.
+
+
p2
+
+ The text of the first part of the parameter.
+ BOOST_PP_ENUM_BINARY_PARAMS concatenates numbers ranging from 0 to count - 1
+ to generate parameters.
+
+
+
Remarks
+
+ This macro expands to the comma-separated sequence:
+
+ The BOOST_PP_ENUM_BINARY_PARAMS_Z macro generates a comma-separated list of binary parameters.
+ It reenters BOOST_PP_REPEAT with maximum efficiency.
+
+ The number of parameters to generate.
+ Valid values range from 0 to BOOST_PP_LIMIT_REPEAT.
+
+
p1
+
+ The text of the first part of the parameter.
+ BOOST_PP_ENUM_BINARY_PARAMS concatenates numbers ranging from 0 to count - 1
+ to generate parameters.
+
+
p2
+
+ The text of the first part of the parameter.
+ BOOST_PP_ENUM_BINARY_PARAMS concatenates numbers ranging from 0 to count - 1
+ to generate parameters.
+
+
+
Remarks
+
+ This macro expands to the comma-separated sequence:
+
+ To use the z parameter passed from other macros that use BOOST_PP_REPEAT, see BOOST_PP_ENUM_PARAMS_Z.
+
+
+ Previously, this macro could not be used recursively inside BOOST_PP_REPEAT.
+ This limitation no longer exists, as the library can automatically detect the next available repetition depth.
+
+ Previously, this macro could not be used recursively inside BOOST_PP_REPEAT.
+ This limitation no longer exists, as the library can automatically detect the next available repetition depth.
+
+
+ This macro is deprecated.
+ It only exists for backward compatibility.
+ Use BOOST_PP_ENUM_BINARY_PARAMS with BOOST_PP_INTERCEPT instead:
+
+ The number of parameters to generate.
+ Valid values range from 0 to BOOST_PP_LIMIT_REPEAT.
+
+
param
+
+ The text of the parameter.
+ BOOST_PP_ENUM_PARAMS_WITH_DEFAULTS concatenates numbers ranging from 0 to count - 1
+ to generate parameters.
+
+
def
+
+ The default value that trails each parameter.
+ BOOST_PP_ENUM_PARAMS_WITH_DEFAULTS concatenates numbers ranging from 0 to count - 1
+ to generate default arguments.
+
+
+
Remarks
+
+ This macro expands to the comma-separated sequence:
+
+ Previously, this macro could not be used recursively inside BOOST_PP_REPEAT.
+ This limitation no longer exists, as the library can automatically detect the next available repetition depth.
+
+
+ This macro is deprecated.
+ It only exists for backward compatibility.
+ Use BOOST_PP_ENUM_BINARY_PARAMS instead:
+
+ The BOOST_PP_ENUM_SHIFTED macro generates a comma-separated, shifted list.
+
+
Usage
+
+ BOOST_PP_ENUM_SHIFTED(count, macro, data)
+
+
Arguments
+
+
count
+
+ The number of repetitious calls to macro.
+ Valid values range from 0 to BOOST_PP_LIMIT_REPEAT.
+
+
macro
+
+ A ternary operation of the form macro(z, n, data).
+ This macro is expanded by BOOST_PP_ENUM_SHIFTED with the next available repetition depth,
+ the current repetition number, and the auxiliary data argument.
+
+
data
+
+ Auxiliary data passed to macro.
+
+
+
Remarks
+
+ This macro expands to the comma-separated sequence:
+
+ The z value that is passed to macro represents the next available repetition dimension.
+ Other macros that have _Z suffix variants internally use BOOST_PP_REPEAT--for example, BOOST_PP_ENUM_PARAMS and BOOST_PP_ENUM_PARAMS_Z.
+ Using these _Z versions is not strictly necessary, but passing the z value (that is passed to macro) to these macros allows them to reenter BOOST_PP_REPEAT with maximum efficiency.
+
+
+ To directly use this z value, rather than simply passing it to another macro, see BOOST_PP_ENUM_SHIFTED_z.
+
+
+ Previously, this macro could not be used recursively inside BOOST_PP_REPEAT.
+ This limitation no longer exists, as the library can automatically detect the next available repetition depth.
+
+ The BOOST_PP_ENUM_SHIFTED_PARAMS macro generates a comma-separated, shifted list of parameters.
+
+
Usage
+
+ BOOST_PP_ENUM_SHIFTED_PARAMS(count, param)
+
+
Arguments
+
+
count
+
+ The number of parameters to generate.
+ Valid values range from 0 to BOOST_PP_LIMIT_REPEAT.
+
+
param
+
+ The text of the parameter.
+ BOOST_PP_ENUM_SHIFTED_PARAMS concatenates numbers ranging from 1 to count - 1
+ to generate parameters.
+
+
+
Remarks
+
+ This macro expands to the comma-separated sequence:
+
+ param ## 1, ... param ## count - 1
+
+
+
+ This macro facilitates a typical usage of the library.
+ Shifted parameter lists are common in template metaprograms.
+
+
+ To use the z parameter passed from other macros that use BOOST_PP_REPEAT, see BOOST_PP_ENUM_SHIFTED_PARAMS_Z.
+
+
+ Previously, this macro could not be used recursively inside BOOST_PP_REPEAT.
+ This limitation no longer exists, as the library can automatically detect the next available repetition depth.
+
+ The BOOST_PP_ENUM_SHIFTED_PARAMS_Z macro generates a comma-separated, shifted list of parameters.
+ It reenters BOOST_PP_REPEAT with maximum efficiency.
+
+ The number of repetitious calls to macro.
+ Valid values range from 0 to BOOST_PP_LIMIT_REPEAT.
+
+
macro
+
+ A ternary operation of the form macro(z, n, data).
+ This macro is expanded by BOOST_PP_ENUM_SHIFTED with the next available repetition depth,
+ the current repetition number, and the auxiliary data argument.
+
+ At certain times, it may be necessary to perform the concatenation with BOOST_PP_CAT rather than the preprocessor token-pasting operator.
+ This happens when the z value is a macro invocation itself.
+ It needs a delay to allow it to expand.
+ The syntax in such a scenario becomes:
+
+ The BOOST_PP_ENUM_TRAILING macro generates a comma-separated list with a leading comma.
+
+
Usage
+
+ BOOST_PP_ENUM_TRAILING(count, macro, data)
+
+
Arguments
+
+
count
+
+ The number of repetitious calls to macro.
+ Valid values range from 0 to BOOST_PP_LIMIT_REPEAT.
+
+
macro
+
+ A ternary operation of the form macro(z, n, data).
+ This macro is expanded by BOOST_PP_ENUM with the next available repetition depth,
+ the current repetition number, and the auxiliary data argument.
+
+
data
+
+ Auxiliary data passed to macro.
+
+
+
Remarks
+
+ This macro expands to the comma-separated sequence:
+
+ The z value that is passed to macro represents the next available repetition dimension.
+ Other macros that have _Z suffix variants internally use BOOST_PP_REPEAT--for example, BOOST_PP_ENUM_PARAMS and BOOST_PP_ENUM_PARAMS_Z.
+ Using these _Z versions is not strictly necessary, but passing the z value (that is passed to macro) to these macros allows them to reenter BOOST_PP_REPEAT with maximum efficiency.
+
+
+ To directly use this z value, rather than simply passing it to another macro, see BOOST_PP_ENUM_TRAILING_z.
+
+ The number of parameters to generate.
+ Valid values range from 0 to BOOST_PP_LIMIT_REPEAT.
+
+
p1
+
+ The text of the first part of the parameter.
+ BOOST_PP_ENUM_TRAILING_BINARY_PARAMS concatenates numbers ranging from 0 to count - 1
+ to generate parameters.
+
+
p2
+
+ The text of the first part of the parameter.
+ BOOST_PP_ENUM_TRAILING_BINARY_PARAMS concatenates numbers ranging from 0 to count - 1
+ to generate parameters.
+
+
+
Remarks
+
+ This macro expands to the comma-separated sequence:
+
+ The BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z macro generates a comma-separated list of binary parameters with a leading comma.
+ It reenters BOOST_PP_REPEAT with maximum efficiency.
+
+ The number of parameters to generate.
+ Valid values range from 0 to BOOST_PP_LIMIT_REPEAT.
+
+
p1
+
+ The text of the first part of the parameter.
+ BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z concatenates numbers ranging from 0 to count - 1
+ to generate parameters.
+
+
p2
+
+ The text of the first part of the parameter.
+ BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z concatenates numbers ranging from 0 to count - 1
+ to generate parameters.
+
+
+
Remarks
+
+ This macro expands to the comma-separated sequence:
+
+ The BOOST_PP_ENUM_TRAILING_PARAMS_Z macro generates a comma-separated list of parameters with a leading comma.
+ It reenters BOOST_PP_REPEAT with maximum efficiency.
+
+ The number of repetitious calls to macro.
+ Valid values range from 0 to BOOST_PP_LIMIT_REPEAT.
+
+
macro
+
+ A ternary operation of the form macro(z, n, data).
+ This macro is expanded by BOOST_PP_ENUM with the next available repetition depth,
+ the current repetition number, and the auxiliary data argument.
+
+ At certain times, it may be necessary to perform the concatenation with BOOST_PP_CAT rather than the preprocessor token-pasting operator.
+ This happens when the z value is a macro invocation itself.
+ It needs a delay to allow it to expand.
+ The syntax in such a scenario becomes:
+
+ The BOOST_PP_ENUM_z macro represents a reentry into the BOOST_PP_ENUM repetition construct.
+
+
Usage
+
+ BOOST_PP_ENUM_ ## z(count, macro, data)
+
+
Arguments
+
+
z
+
+ The next available BOOST_PP_REPEAT dimension.
+
+
count
+
+ The number of repetitious calls to macro.
+ Valid values range from 0 to BOOST_PP_LIMIT_REPEAT.
+
+
macro
+
+ A ternary operation of the form macro(z, n, data).
+ This macro is expanded by BOOST_PP_ENUM with the next available repetition depth,
+ the current repetition number, and the auxiliary data argument.
+
+ At certain times, it may be necessary to perform the concatenation with BOOST_PP_CAT rather than the preprocessor token-pasting operator.
+ This happens when the z value is a macro invocation itself.
+ It needs a delay to allow it to expand.
+ The syntax in such a scenario becomes:
+
+ The BOOST_PP_EQUAL macro compares two values for equality.
+
+
Usage
+
+ BOOST_PP_EQUAL(x, y)
+
+
Arguments
+
+
x
+
+ The left operand of the comparison.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
y
+
+ The right operand of the comparison.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
+
Remarks
+
+ If x is equal to y, this macro expands to 1.
+ Otherwise, it expands to 0.
+
+
+ Previously, this macro could not be used inside BOOST_PP_WHILE.
+ There is no longer any such restriction because this macro no longer uses BOOST_PP_WHILE.
+
+ The BOOST_PP_EXPAND macro performs a double macro-expansion on its argument.
+
+
Usage
+
+ BOOST_PP_EXPAND(x)
+
+
Arguments
+
+
x
+
+ The argument to be expanded twice.
+
+
+
Remarks
+
+ This macro is useful when a delay is necessary to produce the correct semantics of a macro invocation.
+ For example, when a macro expands to an argument list to another macro.
+ This macro will expand the the argument list on the first pass, and then rescan to expand any more macros.
+
+ The BOOST_PP_FOR macro represents a generalized horizontal repetition construct.
+
+
Usage
+
+ BOOST_PP_FOR(state, pred, op, macro)
+
+
Arguments
+
+
state
+
+ The initial state.
+
+
pred
+
+ A binary predicate of the form pred(r, state).
+ This macro must expand to an integer in the range of 0 to BOOST_PP_LIMIT_MAG.
+ BOOST_PP_FOR repeatedly expands macro while this predicate returns non-zero.
+ This macro is called with the next available BOOST_PP_FOR repetition and the current state.
+
+
op
+
+ A binary operation of the form op(r, state).
+ This operation is expanded by BOOST_PP_FOR with the next available BOOST_PP_FOR repetition and the current state.
+ This macro is repeatedly applied to the state, each time producing a new state, until pred returns 0.
+
+
macro
+
+ A binary macro of the form macro(r, state).
+ This macro is expanded by BOOST_PP_FOR with the next available BOOST_PP_FOR repetition and the current state.
+ This macro is is repeated by BOOST_PP_FOR until pred returns 0.
+
+ The r value that is passed to pred, op, and macro represents the next available BOOST_PP_FOR repetition.
+ Other macros that have _R suffix variants internally use BOOST_PP_FOR--for example, BOOST_PP_LIST_FOR_EACH and BOOST_PP_LIST_FOR_EACH_R.
+ Using these _R versions is not strictly necessary, but passing the r value (that is passed to pred, op, and macro) to these macros allows them to reenter BOOST_PP_FOR with maximum efficiency.
+
+
+ To directly use this r value, rather than simply passing it to another macro, see BOOST_PP_FOR_r.
+
+
+ Previously, this macro could not be used recursively inside BOOST_PP_FOR.
+ This limitation no longer exists, as the library can automatically detect the next available BOOST_PP_FOR repetition.
+
+ The BOOST_PP_FOR_r macro represents a reentry into the BOOST_PP_FOR repetition construct.
+
+
Usage
+
+ BOOST_PP_FOR_ ## r(state, pred, op, macro)
+
+
Arguments
+
+
r
+
+ The next available BOOST_PP_FOR repetition.
+
+
state
+
+ The initial state.
+
+
pred
+
+ A binary predicate of the form pred(r, state).
+ This macro must expand to an integer in the range of 0 to BOOST_PP_LIMIT_MAG.
+ BOOST_PP_FOR repeatedly expands macro while this predicate returns non-zero.
+ This macro is called with the next available BOOST_PP_FOR repetition and the current state.
+
+
op
+
+ A binary operation of the form op(r, state).
+ This operation is expanded by BOOST_PP_FOR with the next available BOOST_PP_FOR repetition and the current state.
+ This macro is repeatedly applied to the state, each time producing a new state, until pred returns 0.
+
+
macro
+
+ A binary macro of the form macro(r, state).
+ This macro is expanded by BOOST_PP_FOR with the next available BOOST_PP_FOR repetition and the current state.
+ This macro is is repeated by BOOST_PP_FOR until pred returns 0.
+
+ At certain times, it may be necessary to perform the concatenation with BOOST_PP_CAT rather than the preprocessor token-pasting operator.
+ This happens when the r value is a macro invocation itself.
+ It needs a delay to allow it to expand.
+ The syntax in such a scenario becomes:
+
+ The BOOST_PP_GREATER macro compares two values for greater magnitude.
+
+
Usage
+
+ BOOST_PP_GREATER(x, y)
+
+
Arguments
+
+
x
+
+ The left operand of the comparison.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
y
+
+ The right operand of the comparison.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
+
Remarks
+
+ If x is greater than y, this macro expands to 1.
+ Otherwise, it expands to 0.
+
+
+ Previously, this macro could not be used inside BOOST_PP_WHILE.
+ There is no longer any such restriction.
+ It is more efficient, however, to use BOOST_PP_GREATER_D in such a situation.
+
+ The BOOST_PP_GREATER_EQUAL macro compares two values for equality or greater magnitude.
+
+
Usage
+
+ BOOST_PP_GREATER_EQUAL(x, y)
+
+
Arguments
+
+
x
+
+ The left operand of the comparison.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
y
+
+ The right operand of the comparison.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
+
Remarks
+
+ If x is greater than or equal to y, this macro expands to 1.
+ Otherwise, it expands to 0.
+
+
+ Previously, this macro could not be used inside BOOST_PP_WHILE.
+ There is no longer any such restriction.
+ It is more efficient, however, to use BOOST_PP_GREATER_EQUAL_D in such a situation.
+
+ The BOOST_PP_INCLUDE_SELF macro includes a file indirectly.
+
+
Usage
+
+ #include BOOST_PP_INCLUDE_SELF()
+
+
Arguments
+
+
filename
+
+ A quoted or angle-bracketed filename to be included by BOOST_PP_INCLUDE_SELF.
+
+
+
Remarks
+
+ BOOST_PP_INDIRECT_SELF must be defined prior to using this macro.
+
+
+ Most preprocessors will not allow a file to directly include itself--even when the file protects itself from such a scenario.
+ This macro, in combination with BOOST_PP_INDIRECT_SELF allows a file to include itself indirectly.
+
+
+ While BOOST_PP_INDIRECT_SELF is being included, BOOST_PP_INCLUDE_SELF defines the macro BOOST_PP_IS_SELFISH to 1.
+ When it returns from the inclusion, BOOST_PP_IS_SELFISH is undefined.
+
+ The BOOST_PP_INDIRECT_SELF macro is a user-defined named external argument used by BOOST_PP_INCLUDE_SELF.
+
+
Usage
+
+ #define BOOST_PP_INDIRECT_SELFfilename
+
+
Arguments
+
+
filename
+
+ A quoted or angle-bracketed filename to be included by BOOST_PP_INCLUDE_SELF.
+
+
+
Remarks
+
+ Most preprocessors will not allow a file to directly include itself--even when the file protects itself from such a scenario.
+ This macro, in combination with BOOST_PP_INCLUDE_SELF allows a file to include itself indirectly.
+
+
+ This macro is automatically undefined for reuse by a call to BOOST_PP_INCLUDE_SELF.
+
+ The BOOST_PP_INTERCEPT macro intercepts a numeric concatenation and expands to nothing.
+
+
Usage
+
+ BOOST_PP_INTERCEPT
+
+
Remarks
+
+ This macro is used to intercept concatenations performed by various other library constructs.
+ It is typically used after other text to prevent eat the concatenation expand to nothing.
+ This macro can only intercept integer constants in the range of 0 to BOOST_PP_LIMIT_MAG.
+
+ The BOOST_PP_ITERATE macro initiates a file-iteration.
+
+
Usage
+
+ #include BOOST_PP_ITERATE()
+
+
Remarks
+
+ Arguments to this macro are passed as external named arguments in one of two
+ ways--either through BOOST_PP_FILENAME_x and BOOST_PP_ITERATION_LIMITSor
+ through BOOST_PP_ITERATION_PARAMS_x.
+
+
+ Three pieces of information are required to perform a file-iteration.
+ First, the name of a file to iterate over.
+ This is passed via BOOST_PP_FILENAME_xor as part of BOOST_PP_ITERATION_PARAMS_x.
+ The file-iteration mechanism will repeatedly include this file with iteration values ranging from a lower bound to an upper bound--the second and third required parameters.
+ These two boundaries are either passed through BOOST_PP_ITERATION_LIMITSor as part of BOOST_PP_ITERATION_PARAMS_x.
+
+
+ Optionally, a fourth parameter may be passed that associates flags with an iteration.
+ These flags are primarily useful to distinguish one iteration from another in the same file.
+ This parameter can only be passed through BOOST_PP_ITERATION_PARAMS_x.
+
+
+ While a file-iteration is in progress, BOOST_PP_IS_ITERATING is defined as 1.
+
+ The BOOST_PP_ITERATION_LIMITS macro is a user-defined named external argument used by BOOST_PP_ITERATE.
+ It denotes the lower and upper bounds of a file-iteration.
+
+ The lower bound (inclusive) of a file-iteration.
+ Valid values range from 0 to BOOST_PP_LIMIT_ITERATION.
+
+
finish
+
+ The upper bound (inclusive) of a file-iteration.
+ Valid values range from 0 to BOOST_PP_LIMIT_ITERATION.
+
+
+
Remarks
+
+ Note that there is a whitespace character after the macro identifier.
+
+
+ This macro is part of the secondary method of passing arguments to BOOST_PP_ITERATE.
+ The other part is BOOST_PP_FILENAME_x. Both start and finish are evaluated parameters.
+ This implies that they may include simple arithmetic.
+
+
+ This macro is automatically undefined for reuse by a call to BOOST_PP_ITERATE.
+
+ The BOOST_PP_ITERATION_PARAMS_x macro is a user-defined named external argument used by BOOST_PP_ITERATE.
+ It denotes the lower bound, upper bound, and the filename of a file-iteration. It can optionally denote flags associated with a file-iteration as well.
+
+ The iteration depth of the next file-iteration.
+ This value must be the current iteration depth + 1.
+
+
c
+
+ The number of parameters.
+ If flags is specified, this value must be 4.
+ Otherwise, it must be 3.
+
+
start
+
+ The lower bound (inclusive) of a file-iteration.
+ Valid values range from 0 to BOOST_PP_LIMIT_ITERATION.
+
+
finish
+
+ The upper bound (inclusive) of a file-iteration.
+ Valid values range from 0 to BOOST_PP_LIMIT_ITERATION.
+
+
filename
+
+ A quoted or angle-bracketed filename to used as the target of a file-iteration.
+
+
[flags]
+
+ A quoted or angle-bracketed filename to used as the target of a file-iteration.
+
+
+
Remarks
+
+ Note that there is a whitespace character after the macro identifier.
+
+
+ This macro is must be defined as an array of arguments in one of the two formats above (with or without flags).
+ It is the primary method of passing arguments to BOOST_PP_ITERATE.
+ Both start and finish are evaluated parameters, which implies that simple arithmetic can be used.
+
+
+ This macro is automatically undefined for reuse by a call to BOOST_PP_ITERATE.
+
+ The BOOST_PP_LESS macro compares two values for lesser magnitude.
+
+
Usage
+
+ BOOST_PP_LESS(x, y)
+
+
Arguments
+
+
x
+
+ The left operand of the comparison.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
y
+
+ The right operand of the comparison.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
+
Remarks
+
+ If x is less than y, this macro expands to 1.
+ Otherwise, it expands to 0.
+
+
+ Previously, this macro could not be used inside BOOST_PP_WHILE.
+ There is no longer any such restriction.
+ It is more efficient, however, to use BOOST_PP_LESS_D in such a situation.
+
+ The BOOST_PP_LESS_EQUAL macro compares two values for equality or lesser magnitude.
+
+
Usage
+
+ BOOST_PP_LESS_EQUAL(x, y)
+
+
Arguments
+
+
x
+
+ The left operand of the comparison.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
y
+
+ The right operand of the comparison.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
+
Remarks
+
+ If x is lesser than or equal to y, this macro expands to 1.
+ Otherwise, it expands to 0.
+
+
+ Previously, this macro could not be used inside BOOST_PP_WHILE.
+ There is no longer any such restriction.
+ It is more efficient, however, to use BOOST_PP_LESS_EQUAL_D in such a situation.
+
+ The BOOST_PP_LINE macro places notes encoded as line directives in the preprocessing output.
+
+
Usage
+
+ #line BOOST_PP_LINE(line, file)
+
+
Arguments
+
+
line
+
+ The new line number of the trailing line.
+ The predefined macro __LINE__ is commonly used.
+
+
file
+
+ Typically the name of the current file.
+ However, any informative text will work.
+ This text is internally stringized, so quotation marks are unnecessary.
+
+
+
Remarks
+
+ If the macro BOOST_PP_CONFIG_EXTENDED_LINE_INFO is defined as 1 and a file-iteration
+ is in progress, this macro will automatically insert debugging information about the state of file-iteration.
+ This information will show the all of the current iteration values with the inner most iteration last.
+
+
+ This information is useful when errors might be spanning multiple iterations of the same source text.
+ Finding any errors is sometimes less than straightforward.
+ Use of this macro can provide information to make this much easier.
+ For example, instead of getting several errors like this:
+
+ "file.hpp", line 2: error: expected a ";"
+ "file.hpp", line 4: error: improperly terminated macro invocation
+
+ You might get something like this instead....
+
+ "file.hpp [1]", line 2: error: expected a ";"
+ "file.hpp [5]", line 4: error: improperly terminated macro invocation
+
+ It is immediately evident that this error is spanning multiple iterations of the same source text.
+ If it wasn't, the same errors would occur on each iteration.
+
+
+ It must be noted however, that some compilers don't like filenames that aren't actually files.
+ Those compilers typically issues warnings about the bad filename.
+ This makes it a good idea to only define BOOST_PP_CONFIG_EXTENDED_LINE_INFO to 1only when debugging.
+
+ The BOOST_PP_LIST_APPEND macro appends two lists.
+
+
Usage
+
+ BOOST_PP_LIST_APPEND(a, b)
+
+
Arguments
+
+
a
+
+ The first list.
+
+
b
+
+ The second list.
+
+
+
Remarks
+
+ This macro appends two lists.
+ For example, if a is (1, (2, (3, BOOST_PP_NIL))) and b is (4, (5, BOOST_PP_NIL)),
+ this macro will expand to:
+
+ (1, (2, (3, (4, (5, BOOST_PP_NIL)))))
+
+
+
+ Previously, this macro could not be used inside BOOST_PP_WHILE.
+ There is no longer any such restriction.
+ It is more efficient, however, to use BOOST_PP_LIST_APPEND_D in such a situation.
+
+ The BOOST_PP_LIST_AT macro extracts an element in a list.
+
+
Usage
+
+ BOOST_PP_LIST_AT(list, index)
+
+
Arguments
+
+
list
+
+ The list from which a element is to be extracted.
+ This list must have at least index + 1 elements.
+
+
index
+
+ The zero-based position in the list of the element to be extracted.
+
+
+
Remarks
+
+ Previously, this macro could not be used inside BOOST_PP_WHILE.
+ There is no longer any such restriction.
+ It is more efficient, however, to use BOOST_PP_LIST_AT_D in such a situation.
+
+ The BOOST_PP_LIST_CAT macro concatenates all elements in a list.
+
+
Usage
+
+ BOOST_PP_LIST_CAT(list)
+
+
Arguments
+
+
list
+
+ The list whose elements are to be concatenated.
+
+
+
Remarks
+
+ Elements are concatenated left-to-right starting with index 0.
+
+
+ Previously, this macro could not be used inside BOOST_PP_WHILE.
+ There is no longer any such restriction.
+ It is more efficient, however, to use BOOST_PP_LIST_CAT_D in such a situation.
+
+ The BOOST_PP_LIST_ENUM macro converts a list to a comma-separated list.
+
+
Usage
+
+ BOOST_PP_LIST_ENUM(list)
+
+
Arguments
+
+
list
+
+ The list to be converted.
+
+
+
Remarks
+
+ If list is, for example, (a, (b, (c, BOOST_PP_NIL))),
+ this macro will produce:
+
+ a, b, c
+
+
+
+ Previously, this macro could not be used inside BOOST_PP_FOR.
+ There is no longer any such restriction.
+ It is more efficient, however, to use BOOST_PP_LIST_ENUM_R in such a situation.
+
+ The BOOST_PP_LIST_FILTER macro filters a list according to a supplied criterion.
+
+
Usage
+
+ BOOST_PP_LIST_FILTER(pred, data, list)
+
+
Arguments
+
+
pred
+
+ A ternary predicate of the form pred(d, data, elem).
+ This predicate is expanded by BOOST_PP_LIST_FILTER for each element in list with the next available BOOST_PP_WHILE iteration,
+ the auxiliary data, and the current element in list.
+ This macro must return a integral value in the range of 0 to BOOST_PP_LIMIT_MAG.
+ If this predicate expands to non-zero for a certain element, that element is included in the resulting list.
+
+
data
+
+ Auxiliary data passed to pred.
+
+
list
+
+ The list to be filtered.
+
+
+
Remarks
+
+ This macro expands pred for each element in list.
+ It builds a new list out of each element for which pred returns non-zero.
+
+
+ Previously, this macro could not be used inside BOOST_PP_WHILE.
+ There is no longer any such restriction.
+ It is more efficient, however, to use BOOST_PP_LIST_FILTER_D in such a situation.
+
+ The BOOST_PP_LIST_FILTER_D macro filters a list according to a supplied criterion.
+ It reenters BOOST_PP_WHILE with maximum efficiency.
+
+
Usage
+
+ BOOST_PP_LIST_FILTER_D(d, pred, data, list)
+
+
Arguments
+
+
d
+
+ The next available BOOST_PP_WHILE iteration.
+
+
pred
+
+ A ternary predicate of the form pred(d, data, elem).
+ This predicate is expanded by BOOST_PP_LIST_FILTER for each element in list with the next available BOOST_PP_WHILE iteration,
+ the auxiliary data, and the current element in list.
+ This macro must return a integral value in the range of 0 to BOOST_PP_LIMIT_MAG.
+ If this predicate expands to non-zero for a certain element, that element is included in the resulting list.
+
+
data
+
+ Auxiliary data passed to pred.
+
+
list
+
+ The list to be filtered.
+
+
+
Remarks
+
+ This macro expands pred for each element in list.
+ It builds a new list out of each element for which pred returns non-zero.
+
+ The BOOST_PP_LIST_FIRST_N macro expands to a list of the first count elements of a list.
+
+
Usage
+
+ BOOST_PP_LIST_FIRST_N(count, list)
+
+
Arguments
+
+
count
+
+ The number of elements to extract.
+
+
list
+
+ The list from which the elements are extracted.
+
+
+
Remarks
+
+ This macro extracts count elements from the beginning of list and returns them as a list
+
+
+ Previously, this macro could not be used inside BOOST_PP_WHILE.
+ There is no longer any such restriction.
+ It is more efficient, however, to use BOOST_PP_LIST_FIRST_N_D in such a situation.
+
+ The BOOST_PP_LIST_FOLD_LEFT macro folds (or accumulates) the elements of a list left-to-right.
+
+
Usage
+
+ BOOST_PP_LIST_FOLD_LEFT(op, state, list)
+
+
Arguments
+
+
op
+
+ A ternary operation of the form op(d, state, elem).
+ This macro is called for each element in list--each time returning a new state.
+ This operation is expanded by BOOST_PP_LIST_FOLD_LEFT with the next available BOOST_PP_WHILE iteration,
+ the current state, and the current element.
+
+
state
+
+ The initial state of the fold.
+
+
list
+
+ The list to be folded.
+
+
+
Remarks
+
+ For the list, (0, (1, (2, BOOST_PP_NIL))), this macro expands to:
+
+ op(d, op(d, op(d, state, 0), 1), 2)
+
+
+
+ Previously, this macro could not be used inside BOOST_PP_WHILE.
+ There is no longer any such restriction.
+ It is more efficient, however, to use BOOST_PP_LIST_FOLD_LEFT_d in such a situation.
+
+ The BOOST_PP_LIST_FOLD_LEFT_2ND macro folds (or accumulates) the elements of a list left-to-right.
+
+
Usage
+
+ BOOST_PP_LIST_FOLD_LEFT_2ND(op, state, list)
+
+
Arguments
+
+
op
+
+ A ternary operation of the form op(d, state, elem).
+ This macro is called for each element in list--each time returning a new state.
+ This operation is expanded by BOOST_PP_LIST_FOLD_LEFT with the next available BOOST_PP_WHILE iteration,
+ the current state, and the current element.
+
+
state
+
+ The initial state of the fold.
+
+
list
+
+ The list to be folded.
+
+
+
Remarks
+
+ For the list, (0, (1, (2, BOOST_PP_NIL))), this macro expands to:
+
+ op(d, op(d, op(d, state, 0), 1), 2)
+
+
+
+ This macro is deprecated.
+ Use BOOST_PP_LIST_FOLD_LEFT_d instead.
+
+ The BOOST_PP_LIST_FOLD_LEFT_2ND_D macro folds (or accumulates) the elements of a list left-to-right.
+ It reenters BOOST_PP_WHILE with maximum efficiency.
+
+ A ternary operation of the form op(d, state, elem).
+ This macro is called for each element in list--each time returning a new state.
+ This operation is expanded by BOOST_PP_LIST_FOLD_LEFT with the next available BOOST_PP_WHILE iteration,
+ the current state, and the current element.
+
+
state
+
+ The initial state of the fold.
+
+
list
+
+ The list to be folded.
+
+
+
Remarks
+
+ For the list, (0, (1, (2, BOOST_PP_NIL))), this macro expands to:
+
+ op(d, op(d, op(d, state, 0), 1), 2)
+
+
+
+ This macro has been superceded by BOOST_PP_LIST_FOLD_LEFT_d and is deprecated.
+ It only allows a single reentry into BOOST_PP_LIST_FOLD_LEFT.
+
+ The BOOST_PP_LIST_FOLD_LEFT_d macro folds (or accumulates) the elements of a list left-to-right.
+ It reenters BOOST_PP_WHILE with maximum efficiency.
+
+ A ternary operation of the form op(d, state, elem).
+ This macro is called for each element in list--each time returning a new state.
+ This operation is expanded by BOOST_PP_LIST_FOLD_LEFT with the next available BOOST_PP_WHILE iteration,
+ the current state, and the current element.
+
+
state
+
+ The initial state of the fold.
+
+
list
+
+ The list to be folded.
+
+
+
Remarks
+
+ For the list, (0, (1, (2, BOOST_PP_NIL))), this macro expands to:
+
+ The BOOST_PP_LIST_FOLD_LEFT_D macro folds (or accumulates) the elements of a list left-to-right.
+ It reenters BOOST_PP_WHILE with maximum efficiency.
+
+
Usage
+
+ BOOST_PP_LIST_FOLD_LEFT_D(d, op, state, list)
+
+
Arguments
+
+
d
+
+ The next available BOOST_PP_WHILE iteration.
+
+
op
+
+ A ternary operation of the form op(d, state, elem).
+ This macro is called for each element in list--each time returning a new state.
+ This operation is expanded by BOOST_PP_LIST_FOLD_LEFT with the next available BOOST_PP_WHILE iteration,
+ the current state, and the current element.
+
+
state
+
+ The initial state of the fold.
+
+
list
+
+ The list to be folded.
+
+
+
Remarks
+
+ For the list, (0, (1, (2, BOOST_PP_NIL))), this macro expands to:
+
+ op(d, op(d, op(d, state, 0), 1), 2)
+
+
+
+ This macro has been superceded by BOOST_PP_LIST_FOLD_LEFT_d and is deprecated.
+ It only allows a single reentry into BOOST_PP_LIST_FOLD_LEFT.
+
+ The BOOST_PP_LIST_FOLD_RIGHT macro folds (or accumulates) the elements of a list right-to-left.
+
+
Usage
+
+ BOOST_PP_LIST_FOLD_RIGHT(op, state, list)
+
+
Arguments
+
+
op
+
+ A ternary operation of the form op(d, state, elem).
+ This macro is called for each element in list--each time returning a new state.
+ This operation is expanded by BOOST_PP_LIST_FOLD_RIGHT with the next available BOOST_PP_WHILE iteration,
+ the current state, and the current element.
+
+
state
+
+ The initial state of the fold.
+
+
list
+
+ The list to be folded.
+
+
+
Remarks
+
+ This macro does not have the same signature as it previously did.
+ The arguments have been swapped to provide a uniform interface with BOOST_PP_LIST_FOLD_LEFT.
+
+
+ For the list, (0, (1, (2, BOOST_PP_NIL))), this macro expands to:
+
+ op(d, op(d, op(d, state, 2), 1), 0)
+
+
+
+ Previously, this macro could not be used inside BOOST_PP_WHILE.
+ There is no longer any such restriction.
+ It is more efficient, however, to use BOOST_PP_LIST_FOLD_RIGHT_d in such a situation.
+
+ The BOOST_PP_LIST_FOLD_RIGHT_2ND macro folds (or accumulates) the elements of a list right-to-left.
+
+
Usage
+
+ BOOST_PP_LIST_FOLD_RIGHT_2ND(op, state, list)
+
+
Arguments
+
+
op
+
+ A ternary operation of the form op(d, state, elem).
+ This macro is called for each element in list--each time returning a new state.
+ This operation is expanded by BOOST_PP_LIST_FOLD_RIGHT with the next available BOOST_PP_WHILE iteration,
+ the current state, and the current element.
+
+
state
+
+ The initial state of the fold.
+
+
list
+
+ The list to be folded.
+
+
+
Remarks
+
+ This macro does not have the same signature as it previously did.
+ The arguments have been swapped to provide a uniform interface with BOOST_PP_LIST_FOLD_LEFT.
+
+
+ For the list, (0, (1, (2, BOOST_PP_NIL))), this macro expands to:
+
+ op(d, op(d, op(d, state, 0), 1), 2)
+
+
+
+ This macro is deprecated.
+ Use BOOST_PP_LIST_FOLD_RIGHT_d instead.
+
+ The BOOST_PP_LIST_FOLD_RIGHT_2ND_D macro folds (or accumulates) the elements of a list right-to-left.
+ It reenters BOOST_PP_WHILE with maximum efficiency.
+
+ A ternary operation of the form op(d, state, elem).
+ This macro is called for each element in list--each time returning a new state.
+ This operation is expanded by BOOST_PP_LIST_FOLD_RIGHT with the next available BOOST_PP_WHILE iteration,
+ the current state, and the current element.
+
+
state
+
+ The initial state of the fold.
+
+
list
+
+ The list to be folded.
+
+
+
Remarks
+
+ For the list, (0, (1, (2, BOOST_PP_NIL))), this macro expands to:
+
+ op(d, op(d, op(d, state, 0), 1), 2)
+
+
+
+ This macro has been superceded by BOOST_PP_LIST_FOLD_RIGHT_d and is deprecated.
+ It only allows a single reentry into BOOST_PP_LIST_FOLD_RIGHT.
+
+ The BOOST_PP_LIST_FOLD_RIGHT_d macro folds (or accumulates) the elements of a list right-to-left.
+ It reenters BOOST_PP_WHILE with maximum efficiency.
+
+ A ternary operation of the form op(d, state, elem).
+ This macro is called for each element in list--each time returning a new state.
+ This operation is expanded by BOOST_PP_LIST_FOLD_RIGHT with the next available BOOST_PP_WHILE iteration,
+ the current state, and the current element.
+
+
state
+
+ The initial state of the fold.
+
+
list
+
+ The list to be folded.
+
+
+
Remarks
+
+ For the list, (0, (1, (2, BOOST_PP_NIL))), this macro expands to:
+
+ The BOOST_PP_LIST_FOLD_RIGHT_D macro folds (or accumulates) the elements of a list right-to-left.
+ It reenters BOOST_PP_WHILE with maximum efficiency.
+
+ A ternary operation of the form op(d, state, elem).
+ This macro is called for each element in list--each time returning a new state.
+ This operation is expanded by BOOST_PP_LIST_FOLD_RIGHT with the next available BOOST_PP_WHILE iteration,
+ the current state, and the current element.
+
+
state
+
+ The initial state of the fold.
+
+
list
+
+ The list to be folded.
+
+
+
Remarks
+
+ This macro does not have the same signature as it previously did.
+ The arguments have been swapped to provide a uniform interface with BOOST_PP_LIST_FOLD_LEFT.
+
+
+ For the list, (0, (1, (2, BOOST_PP_NIL))), this macro expands to:
+
+ op(d, op(d, op(d, state, 2), 1), 0)
+
+
+
+ This macro has been superceded by BOOST_PP_LIST_FOLD_RIGHT_d and is deprecated.
+ It only allows a single reentry into BOOST_PP_LIST_FOLD_RIGHT.
+
+ The BOOST_PP_LIST_FOR_EACH macro repeats a macro for each element in a list.
+
+
Usage
+
+ BOOST_PP_LIST_FOR_EACH(macro, data, list)
+
+
Arguments
+
+
macro
+
+ A ternary macro of the form macro(r, data, elem).
+ This macro is expanded by BOOST_PP_LIST_FOR_EACH with each element in list.
+ It is expanded with the next available BOOST_PP_FOR repetition, the auxiliary data, and the current element.
+
+
data
+
+ Auxiliary data passed to macro.
+
+
list
+
+ The list for which macro will be invoked on each element.
+
+
+
Remarks
+
+ This macro is a repetition construct.
+ If list is (a, (b, (c, BOOST_PP_NIL))), it expands to the sequence:
+
+ macro(r, data, a) macro(r, data, b) macro(r, data, c)
+
+
+
+ Previously, this macro could not be used inside BOOST_PP_FOR.
+ There is no longer any such restriction.
+ It is more efficient, however, to use BOOST_PP_LIST_FOR_EACH_R in such a situation.
+
+ The BOOST_PP_LIST_FOR_EACH_I macro repeats a macro for each element in a list.
+
+
Usage
+
+ BOOST_PP_LIST_FOR_EACH_I(macro, data, list)
+
+
Arguments
+
+
macro
+
+ A macro of the form macro(r, data, i, elem).
+ This macro is expanded by BOOST_PP_LIST_FOR_EACH with each element in list.
+ It is expanded with the next available BOOST_PP_FOR repetition, the auxiliary data, the index of the current element, and the current element.
+
+
data
+
+ Auxiliary data passed to macro.
+
+
list
+
+ The list for which macro will be invoked on each element.
+
+
+
Remarks
+
+ This macro is a repetition construct.
+ If list is (a, (b, (c, BOOST_PP_NIL))), it expands to the sequence:
+
+ macro(r, data, 0, a) macro(r, data, 1, b) macro(r, data, 2, c)
+
+
+
+ Previously, this macro could not be used inside BOOST_PP_FOR.
+ There is no longer any such restriction.
+ It is more efficient, however, to use BOOST_PP_LIST_FOR_EACH_I_R in such a situation.
+
+ A macro of the for macro(r, data, i, elem).
+ This macro is expanded by BOOST_PP_LIST_FOR_EACH_I with each element in list.
+ It is expanded with the next available BOOST_PP_FOR repetition, the auxiliary data, the index of the current element, and the current element.
+
+
data
+
+ Auxiliary data passed to macro.
+
+
list
+
+ The list for which macro will be invoked on each element.
+
+
+
Remarks
+
+ This macro is a repetition construct.
+ If list is (a, (b, (c, BOOST_PP_NIL))), it expands to the sequence:
+
+ macro(r, data, 0, a) macro(r, data, 1, b) macro(r, data, 2, c)
+
+ The binary macro of the form macro(r, product).
+ This macro is expanded by BOOST_PP_FOR_EACH_PRODUCT with each cartesian product in tuple.
+ It is expanded with the next available BOOST_PP_FOR repetition and a tuple containing a cartesian product.
+ This tuple will have size elements.
+
+
size
+
+ The size of tuple.
+
+
tuple
+
+ A tuple of lists from which cartesian products are obtained.
+
+
+
Remarks
+
+ This macro is a repetition construct.
+ If two lists are (a, (b, (c, BOOST_PP_NIL))) and (x, (y, (z, BOOST_PP_NIL))),
+ this macro will produce the following sequence:
+
+ Previously, this macro could not be used inside BOOST_PP_FOR.
+ There is no longer any such restriction.
+ It is more efficient, however, to use BOOST_PP_LIST_FOR_EACH_PRODUCT_R in such a situation.
+
+ The BOOST_PP_LIST_FOR_EACH_PRODUCT_R macro repeats a macro for each cartesian product of several lists.
+ It reenters BOOST_PP_FOR with maximum efficiency.
+
+ The binary macro of the form macro(r, product).
+ This macro is expanded by BOOST_PP_FOR_EACH_PRODUCT with each cartesian product in tuple.
+ It is expanded with the next available BOOST_PP_FOR repetition and a tuple containing a cartesian product.
+ This tuple will have size elements.
+
+
size
+
+ The size of tuple.
+
+
tuple
+
+ A tuple of lists from which cartesian products are obtained.
+
+
+
Remarks
+
+ This macro is a repetition construct.
+ If two lists are (a, (b, (c, BOOST_PP_NIL))) and (x, (y, (z, BOOST_PP_NIL))),
+ this macro will produce the following sequence:
+
+ A ternary macro of the form macro(r, data, elem).
+ This macro is expanded by BOOST_PP_LIST_FOR_EACH with each element in list.
+ It is expanded with the next available BOOST_PP_FOR repetition, the auxiliary data, and the current element.
+
+
data
+
+ Auxiliary data passed to macro.
+
+
list
+
+ The list for which macro will be invoked on each element.
+
+
+
Remarks
+
+ This macro is a repetition construct.
+ If list is (a, (b, (c, BOOST_PP_NIL))), it expands to the sequence:
+
+ macro(r, data, a) macro(r, data, b) macro(r, data, c)
+
+ The BOOST_PP_LIST_REST_N macro expands to a list of all but the first count elements of a list.
+
+
Usage
+
+ BOOST_PP_LIST_REST_N(count, list)
+
+
Arguments
+
+
count
+
+ The number of elements to remove from the beginning of list.
+
+
list
+
+ The list from which the elements are extracted.
+
+
+
Remarks
+
+ This macro removes count elements from the beginning of list and returns the remainder as a list
+
+
+ Previously, this macro could not be used inside BOOST_PP_WHILE.
+ There is no longer any such restriction.
+ It is more efficient, however, to use BOOST_PP_LIST_REST_N_D in such a situation.
+
+ The BOOST_PP_LIST_REST_N_D macro expands to a list of all but the first count elements of a list.
+ It reenters BOOST_PP_WHILE with maximum efficiency.
+
+
Usage
+
+ BOOST_PP_LIST_REST_N_D(d, count, list)
+
+
Arguments
+
+
d
+
+ The next available BOOST_PP_WHILE iteration.
+
+
count
+
+ The number of elements to remove from the beginning of list.
+
+
list
+
+ The list from which the elements are extracted.
+
+
+
Remarks
+
+ This macro removes count elements from the beginning of list and returns the remainder as a list
+
+ The BOOST_PP_LIST_REVERSE macro expands to the reverse a list.
+
+
Usage
+
+ BOOST_PP_LIST_REVERSE(list)
+
+
Arguments
+
+
list
+
+ A list to be reversed.
+
+
+
Remarks
+
+ Previously, this macro could not be used inside BOOST_PP_WHILE.
+ There is no longer any such restriction.
+ It is more efficient, however, to use BOOST_PP_LIST_REVERSE_D in such a situation.
+
+ The BOOST_PP_LIST_SIZE macro expands to the size of a list.
+
+
Usage
+
+ BOOST_PP_LIST_SIZE(list)
+
+
Arguments
+
+
list
+
+ A list whose size is to be calculated.
+
+
+
Remarks
+
+ Previously, this macro could not be used inside BOOST_PP_WHILE.
+ There is no longer any such restriction.
+ It is more efficient, however, to use BOOST_PP_LIST_SIZE_D in such a situation.
+
+ The BOOST_PP_LIST_TO_TUPLE macro converts a list to a tuple.
+
+
Usage
+
+ BOOST_PP_LIST_TO_TUPLE(list)
+
+
Arguments
+
+
list
+
+ The list to be converted.
+
+
+
Remarks
+
+ If list is, for example, (a, (b, (c, BOOST_PP_NIL))),
+ this macro will produce:
+
+ (a, b, c)
+
+
+
+ Previously, this macro could not be used inside BOOST_PP_FOR.
+ There is no longer any such restriction.
+ It is more efficient, however, to use BOOST_PP_LIST_TO_TUPLE_R in such a situation.
+
+ The BOOST_PP_LIST_TRANSFORM macro transforms each element in a list according to a supplied transformation.
+
+
Usage
+
+ BOOST_PP_LIST_TRANSFORM(op, data, list)
+
+
Arguments
+
+
op
+
+ A ternary predicate of the form op(d, data, elem).
+ This transformation is expanded by BOOST_PP_LIST_TRANSFORM for each element in list with the next available BOOST_PP_WHILE iteration,
+ the auxiliary data, and the current element in list.
+
+
data
+
+ Auxiliary data passed to pred.
+
+
list
+
+ The list to be transformed.
+
+
+
Remarks
+
+ This macro expands op for each element in list.
+ It builds a new list out of the results of each call.
+ If, for example, list is (a, (b, (c, BOOST_PP_NIL))),
+ this macro expands to...
+
+ Previously, this macro could not be used inside BOOST_PP_WHILE.
+ There is no longer any such restriction.
+ It is more efficient, however, to use BOOST_PP_LIST_TRANSFORM_D in such a situation.
+
+ The BOOST_PP_LIST_TRANSFORM_D macro transforms each element in a list according to a supplied transformation.
+ It reenters BOOST_PP_WHILE with maximum efficiency.
+
+
Usage
+
+ BOOST_PP_LIST_TRANSFORM_D(d, op, data, list)
+
+
Arguments
+
+
d
+
+ The next available BOOST_PP_WHILE iteration.
+
+
op
+
+ A ternary predicate of the form op(d, data, elem).
+ This transformation is expanded by BOOST_PP_LIST_TRANSFORM for each element in list with the next available BOOST_PP_WHILE iteration,
+ the auxiliary data, and the current element in list.
+
+
data
+
+ Auxiliary data passed to pred.
+
+
list
+
+ The list to be transformed.
+
+
+
Remarks
+
+ This macro expands op for each element in list.
+ It builds a new list out of the results of each call.
+ If, for example, list is (a, (b, (c, BOOST_PP_NIL))),
+ this macro expands to...
+
+ The BOOST_PP_LOCAL_ITERATE macro initiates a local-iteration.
+
+
Usage
+
+ #include BOOST_PP_LOCAL_ITERATE()
+
+
Remarks
+
+ This macro causes the user-defined macro BOOST_PP_LOCAL_MACRO to be expanded vertically with values in the range specified by BOOST_PP_LOCAL_LIMITS.
+
+ The BOOST_PP_LOCAL_LIMITS macro is a user-defined named external argument used by BOOST_PP_LOCAL_ITERATE.
+
+
Usage
+
+ #define BOOST_PP_LOCAL_LIMITS (start, finish)
+
+
Arguments
+
+
start
+
+ The lower bound (inclusive) of a local iteration.
+ Valid values range from 0 to BOOST_PP_LIMIT_ITERATION.
+
+
finish
+
+ The upper bound (inclusive) of a local iteration.
+ Valid values range from 0 to BOOST_PP_LIMIT_ITERATION.
+
+
+
Remarks
+
+ Note that there is a whitespace character after the macro identifier.
+
+
+ This macro must expand to a 2-element tuple.
+ The elements of this tuple represent the lower and upper boundaries of a local iteration.
+ Both start and finish are evaluated parameters.
+ This implies that they can include simple arithmetic expressions (such as 1 + 3), etc..
+
+
+ This macro is automatically undefined for reuse by a call to BOOST_PP_LOCAL_ITERATE.
+
+ The BOOST_PP_MAX macro expands to the greater of its two arguments.
+
+
Usage
+
+ BOOST_PP_MAX(x, y)
+
+
Arguments
+
+
x
+
+ The first operand.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
y
+
+ The second operand.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
+
Remarks
+
+ This macro returns the greater of its two arguments or the value of both arguments if they are equal.
+
+
+ Previously, this macro could not be used inside BOOST_PP_WHILE.
+ There is no longer any such restriction.
+ It is more efficient, however, to use BOOST_PP_MAX_D in such a situation.
+
+ The BOOST_PP_MIN macro expands to the lesser of its two arguments.
+
+
Usage
+
+ BOOST_PP_MIN(x, y)
+
+
Arguments
+
+
x
+
+ The first operand.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
y
+
+ The second operand.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
+
Remarks
+
+ This macro returns the lesser of its two arguments or the value of both arguments if they are equal.
+
+
+ Previously, this macro could not be used inside BOOST_PP_WHILE.
+ There is no longer any such restriction.
+ It is more efficient, however, to use BOOST_PP_MIN_D in such a situation.
+
+ The BOOST_PP_MOD macro expands to the modulus of its arguments.
+
+
Usage
+
+ BOOST_PP_MOD(x, y)
+
+
Arguments
+
+
x
+
+ The dividend (numerator) of the operation.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
y
+
+ The divisor (denominator) of the operation.
+ Valid values range from 1 to BOOST_PP_LIMIT_MAG.
+
+
+
Remarks
+
+ Previously, this macro could not be used inside BOOST_PP_WHILE.
+ There is no longer any such restriction.
+ It is more efficient, however, to use BOOST_PP_MOD_D in such a situation.
+
+ The BOOST_PP_MUL macro expands to the product of its arguments.
+
+
Usage
+
+ BOOST_PP_MUL(x, y)
+
+
Arguments
+
+
x
+
+ The multiplicand of the operation.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
y
+
+ The multiplier of the operation.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
+
Remarks
+
+ If the product of x and y is greater than BOOST_PP_LIMIT_MAG, the result is saturated to BOOST_PP_LIMIT_MAG.
+
+
+ Previously, this macro could not be used inside BOOST_PP_WHILE.
+ There is no longer any such restriction.
+ It is more efficient, however, to use BOOST_PP_MUL_D in such a situation.
+
+
+ This macro is the most efficient when x is less than or equal to y.
+ However, the efficiency gain is not worth actually comparing the two arguments prior to invocation.
+ In other words, x should be the value that is most likely to be the largest of the two operands.
+
+ The BOOST_PP_MUL_D macro expands to the product of its second and third arguments.
+ It reenters BOOST_PP_WHILE with maximum efficiency.
+
+
Usage
+
+ BOOST_PP_MUL_D(d, x, y)
+
+
Arguments
+
+
d
+
+ The next available BOOST_PP_WHILE iteration.
+
+
x
+
+ The multiplicand of the operation.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
y
+
+ The multiplier of the operation.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
+
Remarks
+
+ If the product of x and y is greater than BOOST_PP_LIMIT_MAG, the result is saturated to BOOST_PP_LIMIT_MAG.
+
+
+ This macro is the most efficient when x is less than or equal to y.
+ However, the efficiency gain is not worth actually comparing the two arguments prior to invocation.
+ In other words, x should be the value that is most likely to be the largest of the two operands.
+
+ The BOOST_PP_NOR macro expands to the logical NOR of its operands.
+
+
Usage
+
+ BOOST_PP_NOR(p, q)
+
+
Arguments
+
+
p
+
+ The left operand of the operation.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
q
+
+ The right operand of the operation.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
+
Remarks
+
+ If both p and q are both 0, this macro expands to 1.
+ Otherwise, it expands to 0.
+
+
+ This macro performs a boolean conversion on each operand before performing the logical NOR operation.
+ If that conversion is not necessary, use BOOST_PP_BITNOR instead.
+
+ The BOOST_PP_NOT macro performs a logical NOT on its operand.
+
+
Usage
+
+ BOOST_PP_NOT(x)
+
+
Arguments
+
+
x
+
+ The value to be converted.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
+
Remarks
+
+ If x is non-zero, this macro expands to 1.
+ Otherwise, it expands to 0.
+
+
+ This macro performs a boolean conversion on its operand before performing the logical NOT operation.
+ If that conversion is not necessary, use BOOST_PP_COMPL instead.
+
+ The BOOST_PP_NOT_EQUAL macro compares two values for inequality.
+
+
Usage
+
+ BOOST_PP_NOT_EQUAL(x, y)
+
+
Arguments
+
+
x
+
+ The left operand of the comparison.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
y
+
+ The right operand of the comparison.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
+
Remarks
+
+ If x is equal to y, this macro expands to 0.
+ Otherwise, it expands to 1.
+
+
+ Previously, this macro could not be used inside BOOST_PP_WHILE.
+ There is no longer any such restriction because this macro no longer uses BOOST_PP_WHILE.
+
+ The BOOST_PP_OR macro expands to the logical OR of its operands.
+
+
Usage
+
+ BOOST_PP_OR(p, q)
+
+
Arguments
+
+
p
+
+ The left operand of the operation.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
q
+
+ The right operand of the operation.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
+
Remarks
+
+ If either p or q is non-zero, this macro expands to 1.
+ Otherwise, it expands to 0.
+
+
+ This macro performs a boolean conversion on each operand before performing the logical OR operation.
+ If that conversion is not necessary, use BOOST_PP_BITOR instead.
+
+ The BOOST_PP_RELATIVE_ITERATION macro expands to the iteration value of a file-iteration depth relative to the current depth.
+
+
Usage
+
+ BOOST_PP_RELATIVE_ITERATION(i)
+
+
Arguments
+
+
i
+
+ The relative depth of the frame whose iteration value is to be retreived.
+ Valid values range from 0 to BOOST_PP_ITERATION_DEPTH() - 1.
+
+
+
Remarks
+
+ This macro is only valid when a file-iteration is in progress.
+
+
+ The argument i is interpreted as the number of frames outward from the current frame.
+ Therefore, BOOST_PP_RELATIVE_ITERATION(0) is equivalent to BOOST_PP_ITERATION().
+
+ The BOOST_PP_REPEAT macro represents a fast horizontal repetition construct.
+
+
Usage
+
+ BOOST_PP_REPEAT(count, macro, data)
+
+
Arguments
+
+
count
+
+ The number of repetitious calls to macro.
+ Valid values range from 0 to BOOST_PP_LIMIT_REPEAT.
+
+
macro
+
+ A ternary operation of the form macro(z, n, data).
+ This macro is expanded by BOOST_PP_REPEAT with the next available repetition depth,
+ the current repetition number, and the auxiliary data argument.
+
+ The z value that is passed to macro represents the next available repetition dimension.
+ Other macros that have _Z suffix variants internally use BOOST_PP_REPEAT--for example, BOOST_PP_ENUM_PARAMS and BOOST_PP_ENUM_PARAMS_Z.
+ Using these _Z versions is not strictly necessary, but passing the z value (that is passed to macro) to these macros allows them to reenter BOOST_PP_REPEAT with maximum efficiency.
+
+
+ To directly use this z value, rather than simply passing it to another macro, see BOOST_PP_REPEAT_z.
+
+
+ Previously, this macro could not be used recursively inside BOOST_PP_REPEAT.
+ This limitation no longer exists, as the library can automatically detect the next available repetition depth.
+
+ The BOOST_PP_REPEAT_1ST macro represents the first dimension of BOOST_PP_REPEAT.
+
+
Usage
+
+ BOOST_PP_REPEAT_1ST(count, macro, data)
+
+
Arguments
+
+
count
+
+ The number of repetitious calls to macro.
+ Valid values range from 0 to BOOST_PP_LIMIT_REPEAT.
+
+
macro
+
+ A ternary operation of the form macro(z, n, data).
+ This macro is expanded by BOOST_PP_REPEAT_1ST with the next available repetition depth,
+ the current repetition number, and the auxiliary data argument.
+
+ The z value that is passed to macro represents the next available repetition dimension.
+ Other macros that have _Z suffix variants internally use BOOST_PP_REPEAT--for example, BOOST_PP_ENUM_PARAMS and BOOST_PP_ENUM_PARAMS_Z.
+ Using these _Z versions is not strictly necessary, but passing the z value (that is passed to macro) to these macros allows them to reenter BOOST_PP_REPEAT with maximum efficiency.
+
+
+ To directly use this z value, rather than simply passing it to another macro, see BOOST_PP_REPEAT_z.
+
+
+ This macro is deprecated.
+ It only exists for backward compatibility.
+ Use BOOST_PP_REPEAT instead.
+
+ The BOOST_PP_REPEAT_2ND macro represents the second dimension of BOOST_PP_REPEAT.
+
+
Usage
+
+ BOOST_PP_REPEAT_2ND(count, macro, data)
+
+
Arguments
+
+
count
+
+ The number of repetitious calls to macro.
+ Valid values range from 0 to BOOST_PP_LIMIT_REPEAT.
+
+
macro
+
+ A ternary operation of the form macro(z, n, data).
+ This macro is expanded by BOOST_PP_REPEAT_2ND with the next available repetition depth,
+ the current repetition number, and the auxiliary data argument.
+
+ The z value that is passed to macro represents the next available repetition dimension.
+ Other macros that have _Z suffix variants internally use BOOST_PP_REPEAT--for example, BOOST_PP_ENUM_PARAMS and BOOST_PP_ENUM_PARAMS_Z.
+ Using these _Z versions is not strictly necessary, but passing the z value (that is passed to macro) to these macros allows them to reenter BOOST_PP_REPEAT with maximum efficiency.
+
+
+ To directly use this z value, rather than simply passing it to another macro, see BOOST_PP_REPEAT_z.
+
+
+ This macro is deprecated.
+ It only exists for backward compatibility.
+ Use BOOST_PP_REPEAT instead.
+
+ The BOOST_PP_REPEAT_3RD macro represents the third dimension of BOOST_PP_REPEAT.
+
+
Usage
+
+ BOOST_PP_REPEAT_3RD(count, macro, data)
+
+
Arguments
+
+
count
+
+ The number of repetitious calls to macro.
+ Valid values range from 0 to BOOST_PP_LIMIT_REPEAT.
+
+
macro
+
+ A ternary operation of the form macro(z, n, data).
+ This macro is expanded by BOOST_PP_REPEAT_3RD with the next available repetition depth,
+ the current repetition number, and the auxiliary data argument.
+
+ The z value that is passed to macro represents the next available repetition dimension.
+ Other macros that have _Z suffix variants internally use BOOST_PP_REPEAT--for example, BOOST_PP_ENUM_PARAMS and BOOST_PP_ENUM_PARAMS_Z.
+ Using these _Z versions is not strictly necessary, but passing the z value (that is passed to macro) to these macros allows them to reenter BOOST_PP_REPEAT with maximum efficiency.
+
+
+ To directly use this z value, rather than simply passing it to another macro, see BOOST_PP_REPEAT_z.
+
+
+ This macro is deprecated.
+ It only exists for backward compatibility.
+ Use BOOST_PP_REPEAT instead.
+
+ The BOOST_PP_REPEAT_FROM_TO macro represents a fast horizontal repetition construct.
+
+
Usage
+
+ BOOST_PP_REPEAT_FROM_TO(first, last, macro, data)
+
+
Arguments
+
+
first
+
+ The lower bound of the repetition.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
last
+
+ The upper bound of the repetition.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
macro
+
+ A ternary operation of the form macro(z, n, data).
+ This macro is expanded by BOOST_PP_REPEAT with the next available repetition depth,
+ the current repetition number, and the auxiliary data argument.
+
+
data
+
+ Auxiliary data passed to macro.
+
+
+
Remarks
+
+ This macro expands to the sequence:
+
+ macro(z, first, data) macro(z, first + 1, data) ... macro(z, last - 1, data)
+
+
+
+ The number of repetitions (i.e. last - first) must not exceed BOOST_PP_LIMIT_REPEAT.
+
+
+ The z value that is passed to macro represents the next available repetition dimension.
+ Other macros that have _Z suffix variants internally use BOOST_PP_REPEAT--for example, BOOST_PP_ENUM_PARAMS and BOOST_PP_ENUM_PARAMS_Z.
+ Using these _Z versions is not strictly necessary, but passing the z value (that is passed to macro) to these macros allows them to reenter BOOST_PP_REPEAT with maximum efficiency.
+
+
+ To directly use this z value, rather than simply passing it to another macro, see BOOST_PP_REPEAT_FROM_TO_z.
+
+
+ Previously, this macro could not be used recursively inside BOOST_PP_REPEAT.
+ This limitation no longer exists, as the library can automatically detect the next available repetition depth.
+
+
+ This macro also uses BOOST_PP_WHILE.
+ Because of this, there are also two variants of this macro for ideal reentrance into BOOST_PP_WHILE,
+ BOOST_PP_REPEAT_FROM_TO_D and BOOST_PP_REPEAT_FROM_TO_D_z.
+
+ The BOOST_PP_REPEAT_FROM_TO_1ST macro represents the first dimension of BOOST_PP_REPEAT_FROM_TO.
+
+
Usage
+
+ BOOST_PP_REPEAT_FROM_TO_1ST(first, last, macro, data)
+
+
Arguments
+
+
first
+
+ The lower bound of the repetition.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
last
+
+ The upper bound of the repetition.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
macro
+
+ A ternary operation of the form macro(z, n, data).
+ This macro is expanded by BOOST_PP_REPEAT_FROM_TO_1ST with the next available repetition depth,
+ the current repetition number, and the auxiliary data argument.
+
+
data
+
+ Auxiliary data passed to macro.
+
+
+
Remarks
+
+ This macro expands to the sequence:
+
+ macro(z, first, data) macro(z, first + 1, data) ... macro(z, last - 1, data)
+
+
+
+ The number of repetitions (i.e. last - first) must not exceed BOOST_PP_LIMIT_REPEAT.
+
+
+ The z value that is passed to macro represents the next available repetition dimension.
+ Other macros that have _Z suffix variants internally use BOOST_PP_REPEAT--for example, BOOST_PP_ENUM_PARAMS and BOOST_PP_ENUM_PARAMS_Z.
+ Using these _Z versions is not strictly necessary, but passing the z value (that is passed to macro) to these macros allows them to reenter BOOST_PP_REPEAT with maximum efficiency.
+
+
+ To directly use this z value, rather than simply passing it to another macro, see BOOST_PP_REPEAT_FROM_TO_z.
+
+
+ This macro is deprecated.
+ It only exists for backward compatibility.
+ Use BOOST_PP_REPEAT_FROM_TO instead.
+
+ The BOOST_PP_REPEAT_FROM_TO_2ND macro represents the second dimension of BOOST_PP_REPEAT_FROM_TO.
+
+
Usage
+
+ BOOST_PP_REPEAT_FROM_TO_2ND(first, last, macro, data)
+
+
Arguments
+
+
first
+
+ The lower bound of the repetition.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
last
+
+ The upper bound of the repetition.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
macro
+
+ A ternary operation of the form macro(z, n, data).
+ This macro is expanded by BOOST_PP_REPEAT_FROM_TO_2ND with the next available repetition depth,
+ the current repetition number, and the auxiliary data argument.
+
+
data
+
+ Auxiliary data passed to macro.
+
+
+
Remarks
+
+ This macro expands to the sequence:
+
+ macro(z, first, data) macro(z, first + 1, data) ... macro(z, last - 1, data)
+
+
+
+ The number of repetitions (i.e. last - first) must not exceed BOOST_PP_LIMIT_REPEAT.
+
+
+ The z value that is passed to macro represents the next available repetition dimension.
+ Other macros that have _Z suffix variants internally use BOOST_PP_REPEAT--for example, BOOST_PP_ENUM_PARAMS and BOOST_PP_ENUM_PARAMS_Z.
+ Using these _Z versions is not strictly necessary, but passing the z value (that is passed to macro) to these macros allows them to reenter BOOST_PP_REPEAT with maximum efficiency.
+
+
+ To directly use this z value, rather than simply passing it to another macro, see BOOST_PP_REPEAT_FROM_TO_z.
+
+
+ This macro is deprecated.
+ It only exists for backward compatibility.
+ Use BOOST_PP_REPEAT_FROM_TO instead.
+
+ The BOOST_PP_REPEAT_FROM_TO_3RD macro represents the third dimension of BOOST_PP_REPEAT_FROM_TO.
+
+
Usage
+
+ BOOST_PP_REPEAT_FROM_TO_3RD(first, last, macro, data)
+
+
Arguments
+
+
first
+
+ The lower bound of the repetition.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
last
+
+ The upper bound of the repetition.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
macro
+
+ A ternary operation of the form macro(z, n, data).
+ This macro is expanded by BOOST_PP_REPEAT_FROM_TO_3RD with the next available repetition depth,
+ the current repetition number, and the auxiliary data argument.
+
+
data
+
+ Auxiliary data passed to macro.
+
+
+
Remarks
+
+ This macro expands to the sequence:
+
+ macro(z, first, data) macro(z, first + 1, data) ... macro(z, last - 1, data)
+
+
+
+ The number of repetitions (i.e. last - first) must not exceed BOOST_PP_LIMIT_REPEAT.
+
+
+ The z value that is passed to macro represents the next available repetition dimension.
+ Other macros that have _Z suffix variants internally use BOOST_PP_REPEAT--for example, BOOST_PP_ENUM_PARAMS and BOOST_PP_ENUM_PARAMS_Z.
+ Using these _Z versions is not strictly necessary, but passing the z value (that is passed to macro) to these macros allows them to reenter BOOST_PP_REPEAT with maximum efficiency.
+
+
+ To directly use this z value, rather than simply passing it to another macro, see BOOST_PP_REPEAT_FROM_TO_z.
+
+
+ This macro is deprecated.
+ It only exists for backward compatibility.
+ Use BOOST_PP_REPEAT_FROM_TO instead.
+
+ The BOOST_PP_REPEAT_FROM_TO_D macro represents a fast horizontal repetition construct.
+ It reenters BOOST_PP_WHILE with maximum efficiency.
+
+
Usage
+
+ BOOST_PP_REPEAT_FROM_TO_D(d, first, last, macro, data)
+
+
Arguments
+
+
d
+
+ The next available BOOST_PP_WHILE iteration.
+
+
first
+
+ The lower bound of the repetition.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
last
+
+ The upper bound of the repetition.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
macro
+
+ A ternary operation of the form macro(z, n, data).
+ This macro is expanded by BOOST_PP_REPEAT with the next available repetition depth,
+ the current repetition number, and the auxiliary data argument.
+
+
data
+
+ Auxiliary data passed to macro.
+
+
+
Remarks
+
+ This macro expands to the sequence:
+
+ macro(z, first, data) macro(z, first + 1, data) ... macro(z, last - 1, data)
+
+
+
+ The number of repetitions (i.e. last - first) must not exceed BOOST_PP_LIMIT_REPEAT.
+
+
+ The z value that is passed to macro represents the next available repetition dimension.
+ Other macros that have _Z suffix variants internally use BOOST_PP_REPEAT--for example, BOOST_PP_ENUM_PARAMS and BOOST_PP_ENUM_PARAMS_Z.
+ Using these _Z versions is not strictly necessary, but passing the z value (that is passed to macro) to these macros allows them to reenter BOOST_PP_REPEAT with maximum efficiency.
+
+
+ To directly use this z value, rather than simply passing it to another macro, see BOOST_PP_REPEAT_FROM_TO_D_z.
+
+ The BOOST_PP_REPEAT_FROM_TO_D_z macro represents a fast horizontal repetition construct.
+ It reenters both BOOST_PP_REPEAT and BOOST_PP_WHILE with maximum efficiency.
+
+
Usage
+
+ BOOST_PP_REPEAT_FROM_TO_D_z(d, first, last, macro, data)
+
+
Arguments
+
+
z
+
+ The next available BOOST_PP_REPEAT dimension.
+
+
d
+
+ The next available BOOST_PP_WHILE iteration.
+
+
first
+
+ The lower bound of the repetition.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
last
+
+ The upper bound of the repetition.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
macro
+
+ A ternary operation of the form macro(z, n, data).
+ This macro is expanded by BOOST_PP_REPEAT with the next available repetition depth,
+ the current repetition number, and the auxiliary data argument.
+
+
data
+
+ Auxiliary data passed to macro.
+
+
+
Remarks
+
+ This macro expands to the sequence:
+
+ macro(z, first, data) macro(z, first + 1, data) ... macro(z, last - 1, data)
+
+
+
+ The number of repetitions (i.e. last - first) must not exceed BOOST_PP_LIMIT_REPEAT.
+
+
+ The z value that is passed to macro represents the next available repetition dimension.
+ Other macros that have _Z suffix variants internally use BOOST_PP_REPEAT--for example, BOOST_PP_ENUM_PARAMS and BOOST_PP_ENUM_PARAMS_Z.
+ Using these _Z versions is not strictly necessary, but passing the z value (that is passed to macro) to these macros allows them to reenter BOOST_PP_REPEAT with maximum efficiency.
+
+ The BOOST_PP_REPEAT_FROM_TO_z macro represents a reentry into the BOOST_PP_REPEAT_FROM_TO repetition construct.
+
+
Usage
+
+ BOOST_PP_REPEAT_FROM_TO_ ## z(first, last, macro, data)
+
+
Arguments
+
+
z
+
+ The next available BOOST_PP_REPEAT dimension.
+
+
first
+
+ The lower bound of the repetition.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
last
+
+ The upper bound of the repetition.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
macro
+
+ A ternary operation of the form macro(z, n, data).
+ This macro is expanded by BOOST_PP_REPEAT with the next available repetition depth,
+ the current repetition number, and the auxiliary data argument.
+
+
data
+
+ Auxiliary data passed to macro.
+
+
+
Remarks
+
+ This macro expands to the sequence:
+
+ macro(z, first, data) macro(z, first + 1, data) ... macro(z, last - 1, data)
+
+
+
+ The number of repetitions (i.e. last - first) must not exceed BOOST_PP_LIMIT_REPEAT.
+
+
+ At certain times, it may be necessary to perform the concatenation with BOOST_PP_CAT rather than the preprocessor token-pasting operator.
+ This happens when the z value is a macro invocation itself.
+ It needs a delay to allow it to expand.
+ The syntax in such a scenario becomes:
+
+ The BOOST_PP_REPEAT_z macro represents a reentry into the BOOST_PP_REPEAT repetition construct.
+
+
Usage
+
+ BOOST_PP_REPEAT_ ## z(count, macro, data)
+
+
Arguments
+
+
z
+
+ The next available BOOST_PP_REPEAT dimension.
+
+
count
+
+ The number of repetitious calls to macro.
+ Valid values range from 0 to BOOST_PP_LIMIT_REPEAT.
+
+
macro
+
+ A ternary operation of the form macro(z, n, data).
+ This macro is expanded by BOOST_PP_REPEAT with the next available repetition depth,
+ the current repetition number, and the auxiliary data argument.
+
+ At certain times, it may be necessary to perform the concatenation with BOOST_PP_CAT rather than the preprocessor token-pasting operator.
+ This happens when the z value is a macro invocation itself.
+ It needs a delay to allow it to expand.
+ The syntax in such a scenario becomes:
+
+ The BOOST_PP_SUB macro expands to the difference between its arguments.
+
+
Usage
+
+ BOOST_PP_SUB(x, y)
+
+
Arguments
+
+
x
+
+ The minuend of the operation.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
y
+
+ The subtrahend of the operation.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
+
Remarks
+
+ If the difference between x and y is less than 0, the result is saturated to 0.
+
+
+ Previously, this macro could not be used inside BOOST_PP_WHILE.
+ There is no longer any such restriction.
+ It is more efficient, however, to use BOOST_PP_SUB_D in such a situation.
+
+ The BOOST_PP_WHILE macro represents a looping construct.
+
+
Usage
+
+ BOOST_PP_WHILE(pred, op, state)
+
+
Arguments
+
+
pred
+
+ A binary predicate of the form pred(d, state).
+ This predicate is expanded by BOOST_PP_WHILE with the next available
+ iteration d and the current state.
+ This predicate must expand to value in the range of 0 to BOOST_PP_LIMIT_MAG.
+ The construct continues to loop until this predicate returns 0.
+ When this predicate returns 0, BOOST_PP_WHILE returns the current state.
+
+
op
+
+ A binary operation of the form op(d, state).
+ This operation is expanded by BOOST_PP_WHILE with the next available
+ iteration d and the current state.
+ This macro is repeatedly applied to the state, each time producing a new state, until pred returns 0.
+
+
state
+
+ The initial state.
+ Often this argument is a tuple.
+
+
+
Remarks
+
+ This macro iterates op(d, state) while pred(d, state) is non-zero.
+ In other words expands to:
+
+ op(d, ... op(d, op(d, state)) ... ).
+
+
+
+ The d value that is passed to both pred and op represents the next available iteration.
+ Other macros that have _D suffix variants internally use BOOST_PP_WHILE--for example, BOOST_PP_ADD and BOOST_PP_ADD_D.
+ Using these _D versions is not strictly necessary, but passing the d value (that passed to pred or op) to these macros allows them to reenter BOOST_PP_WHILE with maximum efficiency.
+
+
+ To directly use this d value, rather than simply passing it to another macro, see BOOST_PP_WHILE_d.
+
+
+ Previously, this macro could not be used recursively inside BOOST_PP_WHILE.
+ This limitation no longer exists, as the library can automatically detect the next available iteration.
+
+ The BOOST_PP_WHILE_d macro represents a reentry into the BOOST_PP_WHILE looping construct.
+
+
Usage
+
+ BOOST_PP_WHILE_ ## d(pred, op, state)
+
+
Arguments
+
+
d
+
+ The next available BOOST_PP_WHILE iteration.
+
+
pred
+
+ A binary predicate of the form pred(d, state).
+ This predicate is expanded by BOOST_PP_WHILE with the next available
+ iteration d and the current state.
+ This predicate must expand to value in the range of 0 to BOOST_PP_LIMIT_MAG.
+ The construct continues to loop until this predicate returns 0.
+ When this predicate returns 0, BOOST_PP_WHILE returns the current state.
+
+
op
+
+ A binary operation of the form op(d, state).
+ This operation is expanded by BOOST_PP_WHILE with the next available
+ iteration d and the current state.
+ This macro is repeatedly applied to the state, each time producing a new state, until pred returns 0.
+
+
state
+
+ The initial state.
+ Often this argument is a tuple.
+
+
+
Remarks
+
+ This macro iterates op(d, state) while pred(d, state) is non-zero.
+ In other words expands to:
+
+ op(d, ... op(d, op(d, state)) ... ).
+
+
+
+ At certain times, it may be necessary to perform the concatenation with BOOST_PP_CAT rather than the preprocessor token-pasting operator.
+ This happens when the d value is a macro invocation itself.
+ It needs a delay to allow it to expand.
+ The syntax in such a scenario becomes:
+
+ The BOOST_PP_XOR macro expands to the logical XOR of its operands.
+
+
Usage
+
+ BOOST_PP_XOR(p, q)
+
+
Arguments
+
+
p
+
+ The left operand of the operation.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
q
+
+ The right operand of the operation.
+ Valid values range from 0 to BOOST_PP_LIMIT_MAG.
+
+
+
Remarks
+
+ If either p or q is non-zero exclusively, this macro expands to 1.
+ Otherwise, it expands to 0.
+
+
+ This macro performs a boolean conversion on each operand before performing the logical XOR operation.
+ If that conversion is not necessary, use BOOST_PP_BITXOR instead.
+
+ An evaluated parameter is a numeric value that is evaluated by the library as a constant expression.
+ This means that the expression can include simple arithmetic, logical, and condition expressions.
+ It also means that the value of the parameter no longer depends on the source of the parameter.
+ In other words, if the value is dependent on some macro, it will no longer be dependent on that macro after it is evaluated.
+ This disables the lazy-evaluation that the preprocessor normallly uses.
+
+
+
diff --git a/doc/terms/named_external.html b/doc/terms/named_external.html
new file mode 100644
index 0000000..e1faf39
--- /dev/null
+++ b/doc/terms/named_external.html
@@ -0,0 +1,14 @@
+
+
+ Named External Argument
+
+
+
+
Named External Argument
+
+ A named external argument is an argument to a macro that is included.
+ There is no way to pass arguments to a file directly, so they must be passed to files in the form of macros with known names that are defined by the user.
+ Every time that the library uses this idiom, the file that is included automatically undefines the macro in order to better simulate normal parameters.
+
+ The evaluated slot mechanism is a tool to fully evaluate a constant integral expression and avoid the lazy evaluation normally performed by the preprocessor.
+
+
Tutorial
+
+ In order to understand the use of such a mechanism, I will start with a simple file-iteration example.
+ Consider the following scenario....
+
+
+for (int i = 0; i < 10; ++i) {
+ for (int j = 0; j < i; ++j) {
+ // ... use i and j
+ }
+}
+
+
+ The above is a simple runtime model of the following multidimensional file-iteration....
+
+ There is a problem with the code above.
+ The writer expected I to refer the previous iteration frame.
+ However, that is not the case.
+ When the user refers to I, he is actually referring to BOOST_PP_ITERATION(),
+ not the value of BOOST_PP_ITERATION() at the point of definition.
+ Instead, it refers to exactly the same value to which J refers.
+
+
+ The problem is that the preprocessor always evaluates everything with lazy evaluation.
+ To solve the problem, we need I to be evaluated here:
+
+ Fortunately, the library offers a mechanism to do just that: evaluated slots.
+ The following code uses this mechanism to "fix" the example above...
+
+ There are two steps to the assignment of an evaluated slot.
+ First, the user must define the named external argumentBOOST_PP_VALUE.
+ This value must be an integral constant expression.
+ Second, the user must includeBOOST_PP_ASSIGN_SLOT(x), where x is the particular slot to be assigned to (1 to BOOST_PP_LIMIT_SLOT_COUNT).
+ This will evaluate BOOST_PP_VALUE and assign the result to the slot at index x.
+
+
+ To retrieve a slot's value, the user must use BOOST_PP_SLOT(x).
+
+
+ In the case above, I is still lazily evaluated.
+ However, it now evaluates to BOOST_PP_SLOT(1).
+ This value will not change unless there is a subsequent call to BOOST_PP_ASSIGN_SLOT(1).
+
+
Advanced Techniques
+
+ The slot mechanism can also be used to perform calculations:
+
+ File iteration is a complex, but powerful, vertical repetition construct.
+ It repeatedly includes a file for each number in a user-specified range.
+
+
Tutorial
+
+ This mechanism requires two pieces of information to operate:
+ a range to iterate over and a file to include on each iteration.
+ It can optionally take a third piece of information that represents flags used to discriminate between
+ different iterations of the same file.
+ This information is obtained by the mechanism through one or two named external arguments.
+ These arguments are specified as user-defined macros named BOOST_PP_ITERATION_PARAMS_x
+ or the combination of BOOST_PP_FILENAME_x and BOOST_PP_ITERATION_LIMITS.
+
+
+ BOOST_PP_ITERATION_LIMITS specifies the range of values to iterate over.
+ It must expand to a tuple containing two elements--a lower and upper bound.
+ Both the upper and lower bounds must be numeric values in the range of 0 to BOOST_PP_LIMIT_ITERATION.
+ For example, if the user wishes a file to be included for numbers ranging from 0 to 10,
+ BOOST_PP_ITERATION_LIMITS would be defined like this:
+
+
+#define BOOST_PP_ITERATION_LIMITS (0, 10)
+
+
+ Note that there is whitespace after the name of the macro.
+ The macro does not take two arguments.
+ In the case above, if there was no whitespace, a preprocessing error would occur because 0 and 10
+ are invalid identifiers.
+
+
+ Both the upper and lower bounds specified in the BOOST_PP_ITERATION_LIMITS macro are evaluated parameters.
+ This implies that they can include simple arithmetic or logical expressions.
+ For instance, the above definition could easily have been written like this:
+
+ Because of this, if the whitespace after the macro name is elided, it is possible for the
+ definition to be syntactically valid:
+
+
+#define A 0
+#define B 10
+#define BOOST_PP_ITERATION_LIMITS(A, B)
+ // note: no whitespace ^
+
+
+ If this happens, an error will occur inside the mechanism when it attempts to use this macro.
+ The error messages that result may be obscure, so always remember to include the whitespace.
+ A correct version of the above looks like this:
+
+
+#define A 0
+#define B 10
+#define BOOST_PP_ITERATION_LIMITS (A, B)
+ // note: has whitespace ^
+
+
+ BOOST_PP_FILENAME_x specifies the file to iterate over.
+ The x is a placeholder for the dimension of iteration.
+ (For now, we'll assume this is 1--i.e. the first dimension,
+ so we are actually dealing with BOOST_PP_FILENAME_1.)
+ This macro must expand to a valid filename--in quotes or in angle brackets depending on how the file is accessed:
+
+ All that we need now to perform a simple file iteration is to invoke the mechanism:
+
+
+??=include BOOST_PP_ITERATE()
+
+
+ (The ??= token is a trigraph for #.
+ I use the trigraph to make it clear that I am including a file rather than defining or expanding a macro, but it is not necessary.
+ Even the digraph version, %:, could be used.
+ Some compilers do not readily accept trigraphs and digraphs, so keep that in mind.
+ Other than that, use whichever one you prefer.)
+
+
+ So, if we wish to iterate "file.h" from 1 to 10, we just need to put the pieces together:
+
+ The above code has the effect of including "file.h" ten times in succession.
+
+
+ Alternately, both the range and the file to iterate over can be expressed in one macro, BOOST_PP_ITERATION_PARAMS_x.
+ Once again, the x is a placeholder for the dimension of iteration--which we'll assume is 1.
+ This macro must expand to an array that includes the lower bound, upper bound, filename, and optional flags (in that order).
+
+ This has the same effect as the previous version.
+ Only one of these two ways to specify the parameters can be used at a time.
+ (The reason that there are two different methods has to do with dimensional abstraction which I'll get to later.)
+
+
+ There is nothing particularly useful about including a file ten times.
+ The difference is that the current macro state changes each time.
+ For example, the current "iteration value" is available with BOOST_PP_ITERATION().
+ If "file.h" is defined like this...
+
+ There is no reason that a file can't iterate over itself.
+ This has the advantage of keeping the code together.
+ The problem is that you have to discriminate the "regular" section of the file from the iterated section of the file.
+ The library provides the BOOST_PP_IS_ITERATING macro to help in this regard.
+ This macro is defined as 1 if an iteration is in progress.
+ For example, to merge the contents of "file.h" into the file that iterates it:
+
+ Using the same file like this raises another issue.
+ What happens when a file performs two separate file iterations over itself?
+ This is the purpose of the optional flags parameter.
+ It is used to discriminate between separate iterations.
+
+ Notice the use of the "flags" parameter (which is accessed through BOOST_PP_ITERATION_FLAGS()).
+ It discriminates between our recurring sample iteration and a typelist linearization iteration.
+
+
+ The second iteration illustrates the power of the file iteration mechanism.
+ It generates typelist linearizations of the form typelist<3>::args<int, double, char>::type.
+
+
+ Actually, to continue the typelist example, with the help of another iteration we can fully linearize typelist creation....
+
+
+// extract.h
+#if !BOOST_PP_IS_ITERATING
+
+ #ifndef EXTRACT_H
+ #define EXTRACT_H
+
+ #include <boost/preprocessor/iteration/iterate.hpp>
+ #include <boost/preprocessor/repetition/enum.hpp>
+ #include <boost/preprocessor/repetition/enum_params.hpp>
+ #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
+
+ // certain types such as "void" can't be function argument types
+
+ template<class T> struct incomplete {
+ typedef T type;
+ };
+
+ template<class T> struct strip_incomplete {
+ typedef T type;
+ };
+
+ template<class T> struct strip_incomplete<incomplete<T> > {
+ typedef T type;
+ };
+
+ template<template<int> class output, class func_t> struct extract;
+
+ #ifndef EXTRACT_MAX
+ #define EXTRACT_MAX 50
+ #endif
+
+ #define BOOST_PP_ITERATION_PARAMS_1 (3, (1, EXTRACT_MAX, "extract.h"))
+ ??=include BOOST_PP_ITERATE()
+
+ #endif // EXTRACT_H
+
+#else
+
+ #define N BOOST_PP_ITERATION()
+ #define STRIP(z, n, _) \
+ typename strip_incomplete<T ## n>::type \
+ /**/
+
+ template<template<int> class output, class R BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)>
+ struct extract<R (BOOST_PP_ENUM_PARAMS(N, T))> {
+ typedef typename output<N>::template args<BOOST_PP_ENUM(N, STRIP, nil)>::type type;
+ };
+
+ #undef STRIP
+ #undef N
+
+#endif
+
+
+ Now we can define a helper macro to finish the job:
+
+ There are two minor caveats with this result.
+ First, certain types like void can't be the type of an argument, so they have to be
+ wrapped with incomplete<T>.
+ Second, the necessary double parenthesis is annoying.
+ If and when C++ gets C99's variadic macros, TYPELIST can be redefined:
+
+ Note also that both the lower and upper bounds of an iteration are also accessible inside an iteration with
+ BOOST_PP_ITERATION_START() and BOOST_PP_ITERATION_FINISH().
+
+
+ It is my hope that the explanation and examples presented here demonstrate the power of file iteration.
+ Even so, this is just the beginning.
+ The file iteration mechanism also defines a full suite of facilities to support multidimensional iteration.
+
+
Multiple Dimensions
+
+ The file iteration mechanism supports up to BOOST_PP_LIMIT_ITERATION_DIM dimensions.
+ The first dimension (i.e. the outermost) we have already used above.
+ In order to use the second dimension (inside the first), we simply have to replace the placeholder x
+ with 2 instead of 1.
+
+ Each dimension must be used in order starting with 1.
+ Therefore, the above can only be valid immediately inside the first dimension.
+
+
+ At this point, further explanation is necessary regarding BOOST_PP_ITERATION,
+ BOOST_PP_ITERATION_START, and BOOST_PP_ITERATION_FINISH.
+ BOOST_PP_ITERATION() expands to the iteration value of the current dimension--regardless
+ of what dimension that is.
+ Likewise, BOOST_PP_ITERATION_START() and BOOST_PP_ITERATION_FINISH() expand to the lower
+ and upper bounds of the current dimension.
+ Using the following pseudo-code as reference:
+
+
+for (int i = start(1); i <= finish(1); ++i) {
+ // A
+ for (int j = start(2); j <= finish(2); ++j) {
+ // B
+ }
+ // C
+}
+
+
+ At point A, BOOST_PP_ITERATION() refers to i.
+ BOOST_PP_ITERATION_START() and BOOST_PP_ITERATION_FINISH()
+ refer to start(1) and finish(1) respectively.
+ At point B, however, BOOST_PP_ITERATION() refers to j--the current
+ iteration value at point B.
+ The same is true for BOOST_PP_ITERATION_START() which refers to start(2), etc..
+
+
+ If separate files are used for each dimension, then there are no major problems, and using multiple dimensions is straightforward.
+ However, if more than one dimension is located in the same file, they need to be distinguished from one another.
+ The file iteration mechanism provides the macro BOOST_PP_ITERATION_DEPTH for this purpose:
+
+ Multiple dimensions raise another question.
+ How does one access the state of dimensions other than the current dimension?
+ In other words, how does one access i at point A?
+ Because of the preprocessor's lazy evaluation, this doesn't work....
+
+
+// ...
+
+#elif BOOST_PP_ITERATION_DEPTH() == 1
+
+ #define I BOOST_PP_ITERATION()
+
+ #define BOOST_PP_ITERATION_PARAMS_2 (3, (1, 2, "file.h"))
+ ??=include BOOST_PP_ITERATE()
+
+ #undef I
+
+#elif BOOST_PP_ITERATION_DEPTH() == 2
+
+ #define J BOOST_PP_ITERATION()
+
+ // use I and J
+
+ #undef I
+
+#endif
+
+
+ The problem here is that I refers to BOOST_PP_ITERATION(),
+ not to the value of BOOST_PP_ITERATION() at the point of I's definition.
+
+
+ The library provides macros to access these values in two ways--absolutely or relatively.
+ The first variety accesses a value of a specific iteration frame (i.e. dimension).
+ To access the iteration value of the first dimension--from any dimension--BOOST_PP_FRAME_ITERATION(1) is used.
+ To access the iteration value of the second dimension, BOOST_PP_FRAME_ITERATION(2) is used, and so on.
+
+
+ There are also frame versions to access the lower bound, the upper bound, and the flags of a dimension:
+ BOOST_PP_FRAME_START, BOOST_PP_FRAME_FINISH, and BOOST_PP_FRAME_FLAGS.
+
+
+ So, to fix the last example, we modify the definition of I....
+
+ The library also provides macros to access values in dimensions relative to the current dimension (e.g. the previous dimension).
+ These macros take an argument that is interpreted as an offset from the current frame.
+ For example, BOOST_PP_RELATIVE_ITERATION(1) always refers to the outer dimension immediately previous to the current dimension.
+ An argument of 0 is interpreted as an offset of 0 which causes
+ BOOST_PP_RELATIVE_ITERATION(0) to be equivalent to BOOST_PP_ITERATION().
+ BOOST_PP_RELATIVE_ITERATION(2) refers to the iteration value of the dimension immediately preceding
+ the dimension that precedes the current dimension.
+
+
+ The lower and upper bounds of a dimension can be accessed in this fashion as well
+ with BOOST_PP_RELATIVE_START and BOOST_PP_RELATIVE_FINISH.
+ The flags of a relative dimension can be accessed with BOOST_PP_RELATIVE_FLAGS.
+
+
Relativity
+
+ I mentioned earlier that there is a reason that there are two ways to parametize the mechanism.
+ The reason is dimensional abstraction.
+ In certain situations the dimension is unknown by the code that is being iterated--possibly
+ because the code is reused at multiple, different dimensions.
+ If that code needs to iterate again, it has to define the right parameters (based on the dimension) for the mechanism to consume.
+
+
+ All of the macro state maintained by the mechanism can be referred to in an indirect way relative to a dimension.
+ This is the purpose of the BOOST_PP_RELATIVE_ accessors.
+
+
+ Likewise, the user-defined named external arguments can be defined this way as well--except the name of the file to iterate.
+ Because the lower and upper boundaries are evaluated by the mechanism, the implementation no longer needs
+ the macro BOOST_PP_ITERATION_LIMITS, and the identifier can be reused for each dimension of iteration.
+
+
+ Unfortunately, the filename is a different story.
+ The library has no way to evaluate the quoted (or angle-bracketed) text.
+ Therefore, it has to use a different macro for each dimension.
+ That is the purpose of the BOOST_PP_FILENAME_x macros.
+ They exist to isolate the only non-abstractable piece of data required by the mechanism.
+
+
+ In order to define the filename in an abstract fashion, you need to do something like this:
+
+ The intent is to avoid having to do this for anything but the filename.
+ If this needs to be done more than once in a file
+ (BOOST_PP_FILENAME_x is undefined by the mechanism after it is used.),
+ consider using a separate file to make the proper definition:
+
+ With a little effort like this, it is possible to maintain the abstraction without the code bloat that would
+ otherwise be required.
+ Unfortunately, this is not a completely general solution as it would need to be done for each unique filename,
+ but it is better than nothing.
+
+
Conclusion
+
+ That about covers the facilities that are available from the mechanism.
+ Using these facilities, let's implement a function_traits template to demonstrate a full-fledge
+ use of the mechanism.
+
+
Function Traits - An Involved Example
+
+ Implementing a comprehensive function_traits template metafunction requires the use
+ of every major part of the file iteration mechanism.
+
+
+ (This example makes no attempt of work around compiler deficiencies and exists only to illustrate the mechanism.)
+
+
+ The result should have the following features:
+
+
+
return type
+
number and types of parameters
+
whether or not the type is a pointer-to-function, reference-to-function, pointer-to-member-function, or a plain function type
+
whether the type has an ellipsis
+
if not a pointer-to-member-function, the equivalent pointer-to-function, reference-to-function, and function type
+
otherwise, the pointer-to-member type, the class type to which it refers, and whether it is const and/or volatile qualified
+
+
+ There are a myriad of ways that this can be implemented.
+ I'll give a brief summary here of what is happening in the implementation below.
+
+
+ The implementation inherently has to deal with function arity.
+ Therefore, at minimum, we need to iterate over function arities and define partial specializations of
+ the primary template function_traits.
+ The situation is further complicated by variadic functions (i.e. functions with an ellipsis).
+ Therefore, for every arity, we need a variadic version as well.
+
+
+ We also need to handle pointers-to-member-functions.
+ This implies that we have to handle not just arity and variadics, but also cv-qualifications.
+
+
+ For the sake of clarity, the implementation below handles function types and pointers-to-member-functions
+ separately.
+ They could be merged, but the result would be significantly messier.
+
+
+ To handle function types, the implementation below iterates over function arities.
+ For each arity, it iterates over each parameter to provide access to each individually.
+ It then re-includes itself to define a variadic specialization of the same arity.
+ It performs the rough equivalent of the following pseudo-code:
+
+ The implementation of pointers-to-member-functions is a bit different.
+ First, it iterates over cv-qualifiers.
+ For each cv-qualifier, it iterates over function arities.
+ For each function arity, it iterates again over each parameter.
+ It then re-includes itself to define a variadic specialization of the same arity....
+
+ Here is the complete implementation.
+ This example represents the power of the file iteration mechanism as well as the library in general,
+ so follow it carefully if you wish to fully understand what the mechanism does....
+
+ One problem that still exists is the lack of support for throw specifications.
+ There is no way that we can completely handle it anyway because we cannot partially specialize
+ on throw specifications.
+ However, we could accurately report the "actual" function type, etc., including the throw
+ specification (which the above implementation doesn't do, as it reconstructs those types).
+ If you like, you can figure out how to do that on your own as an exercise.
+
+ There are several incompatibilities with the previous Boost release (1.28).
+ These fall into roughly three categories:
+
+
+
the horizontal repetition primitives based on BOOST_PP_REPEAT
+
the reentrancy syntax
+
list folding
+
+
Repetition Targets
+
+ First, and probably the most commonly used, is the target macros passed into BOOST_PP_REPEAT and the horizontal repetition contructs that use BOOST_PP_REPEAT.
+ This includes all of the BOOST_PP_REPEAT_* primitives and all of the BOOST_PP_ENUM_* primitives that require a target macro.
+
+
+ The incompatiblity is trivial, but it will require that the source be updated.
+
+
+ These target macros must now except a third parameter.
+ This extra parameter becomes the first parameter in every target macro.
+ It represents the next repetition dimension and brings BOOST_PP_REPEAT inline with rest of the library.
+
+ This parameter can be used for highly efficient reentrance into the BOOST_PP_REPEAT mechanism.
+ However, it is not necessary to use it as the library can automatically detect the next available repetition dimension.
+
+
Dimensional Ordering
+
+ Because of this detection, however, it is unsafe to use BOOST_PP_REPEAT_1ST, BOOST_PP_REPEAT_2ND, and BOOST_PP_REPEAT_3RD out of order.
+ These macros bypass the automatic-recursion mechanism, and the automatic-recursion mechanism relies on macros being used in the proper order.
+ To clarify, if you use these bypass macros, the outer-most repetition must be BOOST_PP_REPEAT_1ST, then BOOST_PP_REPEAT_2ND, and finally BOOST_PP_REPEAT_3RD.
+ Any other usage is not supported by the library.
+ Sometimes it may work, and other times it won't.
+
+
Reentrancy Syntax
+
+ Automatic-recursion brings with it another issue as well. Previously, the reentrancy syntax for BOOST_PP_WHILE (and similarly for BOOST_PP_FOR) was:
+
+ Under the automatic-recursion model, the BOOST_PP_CAT version breaks.
+ This is because BOOST_PP_CAT allows its arguments to expand prior to concatenation,
+ and BOOST_PP_WHILE is a macro that expands without arguments.
+ The library makes it appear that it takes three parameters, but that is the trick of automatic-recursion.
+ It works similarly to the following:
+
+
+ #define A(x, y) ...
+ #define B A
+ // ...
+ B(2, 3)
+
+
+ The syntax makes it look like the B macro above takes two arguments, but it doesn't.
+ The automatic-recursion mechanism works in this fashion, except that the "B" macro deduces the next available "A" macro.
+
+
+ Because some preprocessors are still slow, direct reentrancy (sans automatic-recursion) is still necessary in non-trivial cases.
+ Consequently, the library uses a new syntax to handle reentrancy:
+
+ Previously, the BOOST_PP_LIST_FOLD_RIGHT macros' arguments were the reverse of BOOST_PP_LIST_FOLD_LEFT.
+ Also, the accumulation macro passed into BOOST_PP_LIST_FOLD_RIGHT was called with reversed parameters as well.
+ This discrepancy has been eliminated.
+
+
+ To illustrate, BOOST_PP_LIST_FOLD_RIGHT used to be used like this:
+
+ The library has many new features not present in the 1.28 release, and this list does not attempt to enumerate them.
+ This is simply a list of things that must change for code to be compatible with this new release.
+
+ Local iteration is a simple vertical repetition construct.
+ It expands a macro with each number in a user-specified range.
+ Each expansion is on a separate line.
+
+
Tutorial
+
+ This mechanism requires two pieces of information to operate:
+ a range to iterate over and a macro to expand on each iteration.
+ This information is obtained by the mechanism through two named external arguments.
+ These arguments are specified as user-defined macros named BOOST_PP_LOCAL_LIMITS and BOOST_PP_LOCAL_MACRO.
+
+
+ BOOST_PP_LOCAL_LIMITS specifies a range of values to iterate over.
+ It must expand to a tuple containing two elements--a lower and upper bound.
+ Both the upper and lower bounds must be numeric values in the range of 0 to BOOST_PP_LIMIT_ITERATION.
+ For example, if the user wishes a macro to be expanded with numbers ranging from 0 to 10,
+ BOOST_PP_LOCAL_LIMITS would be defined like this:
+
+
+#define BOOST_PP_LOCAL_LIMITS (0, 10)
+
+
+ Note that there is whitespace after the name of the macro.
+ The macro does not take two arguments.
+ In the case above, if there was no whitespace, a preprocessing error would occur because 0 and 10 are invalid identifiers.
+
+
+ Both the upper and lower bounds specified in the BOOST_PP_LOCAL_LIMITS macro are evaluated parameters.
+ This implies that they can include simple arithmetic or logical expressions.
+ For instance, the above definition could easily have been written like this:
+
+ Because of this, if the whitespace after the macro name is elided, it is possible for the definition to be syntactically valid:
+
+
+#define A 0
+#define B 10
+#define BOOST_PP_LOCAL_LIMITS(A, B)
+ // note: no whitespace ^
+
+
+ If this happens, an error will occur inside the mechanism when it attempts to use this macro.
+ The error messages that result may be obscure, so always remember to include the whitespace.
+ A correct version of the above looks like this:
+
+
+#define A 0
+#define B 10
+#define BOOST_PP_LOCAL_LIMITS (A, B)
+ // note: has whitespace ^
+
+
+ BOOST_PP_LOCAL_MACRO is the macro that is expanded by the mechanism.
+ This macro is expanded on each iteration with the current number of the iteration.
+ It must defined as a unary macro or result in a macro that can be called with one argument:
+
+ Once these two macros are defined, the local iteration is initiated by includingBOOST_PP_LOCAL_ITERATE().
+
+
+??=include BOOST_PP_LOCAL_ITERATE()
+
+
+ (The ??= token is a trigraph for #.
+ I use the trigraph to make it clear that I am including a file rather than defining or expanding a macro, but it is not necessary.
+ Even the digraph version, %:, could be used.
+ Some compilers do not readily accept trigraphs and digraphs, so keep that in mind.
+ Other than that, use whichever one you prefer.)
+
+
+ In order to repeat the sample specialization, the pieces must be put together....
+
+ After the local-iteration is complete, both BOOST_PP_LOCAL_LIMITS and BOOST_PP_LOCAL_MACRO are automatically undefined.
+ If the values need to be retained for a future local-iteration, they must be defined indirectly:
+
+
+
\ No newline at end of file
diff --git a/doc/topics/motivation.html b/doc/topics/motivation.html
new file mode 100644
index 0000000..e4e38f0
--- /dev/null
+++ b/doc/topics/motivation.html
@@ -0,0 +1,100 @@
+
+
+ motivation.html
+
+
+
+
Motivation
+
+ 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.
+
+
+ Consider the implementation of the is_function<> metafunction is Boost.
+ The implementation uses an overloaded is_function_tester() function that is used for testing if a type is convertible
+ to a 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.
+ For example:
+
+
+template<class R>
+yes_type is_function_tester(R (*)());
+
+template<class R, class A0>
+yes_type is_function_tester(R (*)(A0));
+
+template<class R, class A0, class A1>
+yes_type is_function_tester(R (*)(A0, A1));
+
+template<class R, class A0, class A1, class A2>
+yes_type is_function_tester(R (*)(A0, A1, A2));
+
+// ...
+
+
+ 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.
+
+
Typical Solutions
+
+ Typically the repetition is done manually.
+ Manual code repetition is highly unproductive, but sometimes more readable to the untrained eye.
+
+
+ Another solution is to write an external program for generating the repeated code or use some other extra linguistic means such as a smart editor.
+ Unfortunately, using external code generators has many disadvantages:
+
+
Writing the generator takes time. (This could be helped by using a standard generator.)
+
It is no longer productive to manipulate C++ code directly.
+
Invoking the generator may be difficult.
+
Automating the invocation of the generator can be difficult in certain environments. (Automatic invocation is desirable for active libraries.)
+
Porting and distributing the generator may be difficult or simply takes precious time.
+
+
+
What about the preprocessor?
+
+ Because C++ comes with a preprocessor, one would assume that it would support these kinds of needs directly.
+ Using the preprocessor in this case is highly desirable because:
+
+
The preprocessor is highly portable.
+
The preprocessor is automatically invoked as part of the compilation process.
+
Preprocessor metacode can be directly embedded into the C++ source code.
+
Compilers generally allow viewing or outputting the preprocessed code, which can be used for debugging or to copy and paste the generated code.
+
+
+
+ Most unfortunately, the preprocessor is a very low level preprocessor that specifically does not support repetition or recursive macros.
+ Library support is needed!
+
+
+ For detailed information on the capabilities and limitations of the preprocessor, please refer to the C++ standard [Std].
+
+
The Motivation Example Revisited
+
+ Using the primitives of the preprocessor library, the is_function_tester()'s could be implemented like this:
+
+
+#define IS_FUNCTION_TESTER(Z, N, _) \
+ template<class R BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_PARAMS(N, class A)> \
+ 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
+
+
+ In order to change the maximum number of function parameters supported, you now simply change the MAX_IS_FUNCTION_TESTER_PARAMS definition and recompile.
+
+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.
+
+ 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 the preprocessor, then you should do it that way.
+
+
+ Let's survey some of the widely known problems of the preprocessor in a problem/solution format.
+
+
Problem #1
+
+ The preprocessor does not respect scope, therefore macros can accidentally and sometimes silently replace code.
+
+
+ Solution A
+
+ Use all caps identifiers for macros and only macros.
+ This practically eliminates the possibility that a macro might replace other kinds of code accidentally.
+
+
+
+ Solution B
+
+ Use the local macro idiom:
+
+
+#define MACRO ...
+// use MACRO
+#undef MACRO
+
+
+ This makes sure that a macro cannot accidentally replace code outside of the scope of the local macro.
+
+
+ A problem with this solution is that the #undef cannot be automated and may be forgotten.
+ Experienced programmers generally write the #undef either immediately before (in time)
+ or immediately after writing the macro definition.
+
+
+
+ Solution C
+
+ Use the unique macro prefix idiom.
+
+
+#define UMP_MACRO
+// use UMP_MACRO
+
+
+ This makes accidental substitution and collisions highly unlikely.
+ Problems with this solution include:
+
+
+
There can still be naming collisions inside a large project.
+
Macros still pollute the global namespace.
+
+ By combining all solutions, whenever possible, the scope problem can be largely avoided.
+
+
Problem #2
+
+ Preprocessor code is difficult to read.
+ It requires an understanding of the basic process of how the preprocessor recursively expands macros,
+ finding macro definitions, and mentally substituting the parameters of the macro.
+
+
+ Solution
+
+ Any kind of programming requires a basic understanding of how the code is executed.
+ Any parameterization technique, including simple functions and templates requires finding
+ the definition and mentally substituting parameters.
+
+
+ However, it is good to know a few techniques:
+
+
+
By using as many local macros as reasonable, the bulk of the searching process can be eliminated.
+
Code browsers and text search tools make it easier to find the definitions.
+
The compiler can be used for generating the preprocessed source code in order to look for bugs.
+
+ Before turning something into a preprocessor metaprogram, first implement a small scale version
+ of it without the preprocessor.
+ The work bottom-up, replacing hand-written constructs by using the 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.
+
+
+ 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.
+
+
+ An especially important thing to remember is to limit the use of the preprocessor to
+ structured, well-understood, and safe methods.
+ Structure helps to understand complex systems [McConnell].
+
+
Problem #3
+
+ "I'd like to see Cpp abolished." - Bjarne Stroustrup in [Stroustrup].
+
+
+ Solution
+
+ The C/C++ preprocessor will be here for a long time.
+
+ In practice, preprocessor metaprogramming is far simpler and more portable than template metaprogramming [Czarnecki].
+
+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.
+
+ Macro expansion in the preprocessor is entirely functional.
+ Therefore, there is no iteration.
+ Unfortunately, the preprocessor also disallows recursion.
+ This means that the library must fake iteration or recursion by
+ defining sets of macros that are implemented similarly.
+
+
+ To illustrate, here is a simple concatenation macro:
+
+
+#define CONCAT(a, b) CONCAT_D(a, b)
+#define CONCAT_D(a, b) a ## b
+
+CONCAT(a, CONCAT(b, c)) // abc
+
+
+ This is fine for a simple case like the above, but what happens in a scenario like the following:
+
+ Because there is no recursion, the example above expands to CONCAT(p, q) rather than pq.
+
+
+ There are only two ways to "fix" the above.
+ First, it can be documented that AB uses CONCAT and disallow usage similar to the above.
+ Second, multiple concatenation macros can be provided....
+
+
+#define CONCAT_1(a, b) CONCAT_1_D(a, b)
+#define CONCAT_1_D(a, b) a ## b
+
+#define CONCAT_2(a, b) CONCAT_2_D(a, b)
+#define CONCAT_2_D(a, b) a ## b
+
+#define AB(x, y) CONCAT_2(x, y)
+
+CONCAT_1(A, B(p, q)) // pq
+
+
+ This solves the problem.
+ However, it is now necessary to know that AB uses, not only a concatenation macro,
+ but CONCAT_2 specifically.
+
+
+ A better solution is to abstract which concatenation macro is used....
+
+ This is an example of generic reentrance, in this case, into a fictional set of concatenation macros.
+ The c parameter represents the "state" of the concatenation construct,
+ and as long as the user keeps track of this state, AB can be used inside of a concatenation macro.
+
+
+ The library has the same choices.
+ It either has to disallow a construct being inside itself or provide multiple, equivalent definitions of a construct
+ and provide a uniform way to reenter that construct.
+ There are several contructs that require recursion (such as BOOST_PP_WHILE).
+ Consequently, the library chooses to provide several sets of macros with mechanisms to reenter the set at a macro
+ that has not already been used.
+
+
+ In particular, the library must provide reentrance for BOOST_PP_FOR, BOOST_PP_REPEAT, and BOOST_PP_WHILE.
+ There are two mechanisms that are used to accomplish this: state parameters (like the above concatenation example) and automatic recursion.
+
+
State Parameters
+
+ Each of the above constructs (BOOST_PP_FOR, BOOST_PP_REPEAT, and BOOST_PP_WHILE) has an associated state.
+ This state provides the means to reenter the respective construct.
+
+
+ Several user-defined macros are passed to each of these constructs (for use as predicates, operations, etc.).
+ Every time a user-defined macro is invoked, it is passed the current state of the construct that invoked it so that the macro can reenter
+ the respective set if necessary.
+
+
+ These states are used in one of two ways--either by concatenating to or passing to another macro.
+
+
+ There are three types of macros that use these state parameters.
+ First, the set itself which is reentered through concatenation.
+ Second, corresponding sets that act like they are a part of the the primary set.
+ These are also reentered through concatenation.
+ And third, macros that internally use the first or second type of macro.
+ These macros take the state as an additional argument.
+
+
+ The state of BOOST_PP_WHILE is symbolized by the letter D.
+ Two user-defined macros are passed to BOOST_PP_WHILE--a predicate and an operation.
+ When BOOST_PP_WHILE expands these macros, it passes along its state so that these macros
+ can reenter the BOOST_PP_WHILE set.
+
+
+ Consider the following multiplication implementation that illustrates this technique:
+
+
+// The addition interface macro.
+// The _D signifies that it reenters
+// BOOST_PP_WHILE with concatenation.
+
+#define ADD_D(d, x, y) \
+ BOOST_PP_TUPLE_ELEM( \
+ 2, 0, \
+ BOOST_PP_WHILE_ ## d(ADD_P, ADD_O, (x, y)) \
+ ) \
+ /**/
+
+// The predicate that is passed to BOOST_PP_WHILE.
+// It returns "true" until "y" becomes zero.
+
+#define ADD_P(d, xy) BOOST_PP_TUPLE_ELEM(2, 1, xy)
+
+// The operation that is passed to BOOST_PP_WHILE.
+// It increments "x" and decrements "y" which will
+// eventually cause "y" to equal zero and therefore
+// cause the predicate to return "false."
+
+#define ADD_O(d, xy) \
+ ( \
+ BOOST_PP_INC( \
+ BOOST_PP_TUPLE_ELEM(2, 0, xy) \
+ ), \
+ BOOST_PP_DEC( \
+ BOOST_PP_TUPLE_ELEM(2, 1, xy) \
+ ) \
+ ) \
+ /**/
+
+// The multiplication interface macro.
+
+#define MUL(x, y) \
+ BOOST_PP_TUPLE_ELEM( \
+ 3, 0, \
+ BOOST_PP_WHILE(MUL_P, MUL_O, (0, x, y)) \
+ ) \
+ /**/
+
+// The predicate that is passed to BOOST_PP_WHILE.
+// It returns "true" until "y" becomes zero.
+
+#define MUL_P(d, rxy) BOOST_PP_TUPLE_ELEM(3, 2, rxy)
+
+// The operation that is passed to BOOST_PP_WHILE.
+// It adds "x" to "r" and decrements "y" which will
+// eventually cause "y" to equal zero and therefore
+// cause the predicate to return "false."
+
+#define MUL_O(d, rxy) \
+ ( \
+ ADD_D( \
+ d, /* pass the state on to ADD_D */ \
+ BOOST_PP_TUPLE_ELEM(3, 0, rxy), \
+ BOOST_PP_TUPLE_ELEM(3, 1, rxy) \
+ ), \
+ BOOST_PP_TUPLE_ELEM(3, 1, rxy), \
+ BOOST_PP_DEC( \
+ BOOST_PP_TUPLE_ELEM(3, 2, rxy) \
+ ) \
+ ) \
+ /**/
+
+MUL(3, 2) // expands to 6
+
+
+ There are a couple things to note in the above implementation.
+ First, note how ADD_D reenters BOOST_PP_WHILE using the d state parameter.
+ Second, note how MUL's operation, which is expanded by BOOST_PP_WHILE, passes the state
+ on to ADD_D.
+ This illustrates state reentrance by both argument and concatenation.
+
+
+ For every macro in the library that uses BOOST_PP_WHILE,
+ there is a state reentrant variant.
+ If that variant uses an argument rather than concatenation, it is suffixed by _D to symbolize its
+ method of reentrance.
+ Examples or this include the library's own BOOST_PP_ADD_D and BOOST_PP_MUL_D.
+ If the variant uses concatenation, it is suffixed by an underscore.
+ It is completed by concatenation of the state.
+ This includes BOOST_PP_WHILE itself with BOOST_PP_WHILE_ ## d and, for example,
+ BOOST_PP_LIST_FOLD_LEFT with BOOST_PP_LIST_FOLD_LEFT_ ## d.
+
+
+ The same set of conventions are used for BOOST_PP_FOR and BOOST_PP_REPEAT, but with the letters
+ R and Z, respectively, to symbolize their states.
+
+
+ Also note that the above MUL implementation, though not immediately obvious, is using all three
+ types of reentrance.
+ Not only is it using both types of state reentrance, it is also using automatic recursion....
+
+
Automatic Recursion
+
+ Automatic recursion is a technique that vastly simplifies the use of reentrant constructs.
+ It is used by simply not using any state parameters at all.
+
+
+ The MUL example above uses automatic recursion when it uses BOOST_PP_WHILE by itself.
+ In other words, MUL can still be used inside BOOST_PP_WHILE even though it doesn't
+ reenter BOOST_PP_WHILE by concatenating the state to BOOST_PP_WHILE_.
+
+
+ To accomplish this, the library uses a "trick."
+ Despite what it looks like, the macro BOOST_PP_WHILE does not take three arguments.
+ In fact, it takes no arguments at all.
+ Instead, the BOOST_PP_WHILE macro expands to a macro that takes three arguments.
+ It simply detects what the next available BOOST_PP_WHILE_ ## d macro is and returns it.
+ This detection process is somewhat involved, so I won't go into how it works here,
+ but suffice to say it does work.
+
+
+ Using automatic recursion to reenter various sets of macros is obviously much simpler.
+ It completely hides the underlying implementation details.
+ So, if it is so much easier to use, why do the state parameters still exist?
+ The reason is simple as well.
+ When state parameters are used, the state is known at all times.
+ This is not the case when automatic recursion is used.
+ The automatic recursion mechanism has to deduce the state at each point that it is used.
+ This implies a cost in macro complexity that in some situations--notably at deep macro depths--will slow
+ some preprocessors to a crawl.
+
+
Conclusion
+
+ It is really a tradeoff whether to use state parameters or automatic recursion for reentrancy.
+ The strengths of automatic recursion are ease of use and implementation encapsulation.
+ These come at a performance cost on some preprocessors in some situations.
+ The primary strength of state parameters, on the other hand, is efficiency.
+ Use of the state parameters is the only way to achieve maximum efficiency.
+ This efficiency comes at the cost of both code complexity and exposition of implementation.
+
+ Tip: 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.
+
+
+ Tip: It is easier to verify proper use of the line continuation operator when they are aligned.
+
+
+ Notes: You can extend this example by defining more and different kinds of operators.
+ Before doing so, consider using the algebraic categories technique introduced in [Barton]
+ or a layered architecture (see for instance [Czarnecki]).
+ However, at some point you must type the operator tokens *, /, +, -, etc.,
+ because it is impossible to generate them using templates.
+ The resulting categorical repetition of tokens can be eliminated by using preprocessor metaprogramming.
+
+
+
Example - Use BOOST_PP_EMPTY as an unused parameter in local macro instantiations.
+ How: BOOST_PP_EMPTY() expands to nothing and can be used as an unused parameter.
+
+
+ Note: BOOST_PP_EMPTY with the () never gets expanded.
+ The () is necessary to invoke a function-like macro.
+
+
+ Caveat: You cannot safely use concatenation while using BOOST_PP_EMPTY().
+
+
+ Tip: Occasionally, one or two lines are considerably longer than the rest.
+ It can often save some work to not align all the line continuation operators without making the code too unreadable.
+
+
+ Tip: Use syntax highlighting on preprocessor metaprogramming macro identifiers such as:
+
+
BOOST_PP_DEF
+
BOOST_PP_EMPTY
+
BOOST_PP_REPEAT
+
...
+
+ It can greatly improve readability.
+
+
+
Example - Use BOOST_PP_CAT instead of ## when necessary.
+ Why: Macro expansion proceeds recursively in "layers."
+ Token pasting prevents the preprocessor from performing macro expansion,
+ therefore it is often necessary to delay token concatenation.
+
+
+
Example - Use BOOST_PP_STRINGIZE instead of # whenever necessary.
+ Why: Macro expansion proceeds recursively in "layers."
+ Stringization prevents the preprocessor from performing macro expansion, therefore it is often necessary to delay stringization.
+
+
+
Example - Use BOOST_PP_ENUM_PARAMS (and its variants) or BOOST_PP_REPEAT and BOOST_PP_COMMA_IF to avoid O(n) repetition on lists in general.
+ Note: This is no longer how BOOST_PP_REPEAT is implemented, so the code above is illustrative only!
+
+
+ BOOST_PP_ENUM_PARAMS and its variations use BOOST_PP_REPEAT.
+ BOOST_PP_COMMA_IF(I) expands to a comma if I != 0.
+ BOOST_PP_INC(I) essentially expands to "I+1," and BOOST_PP_DEC(I) essentially expands to "I-1.".
+
+
+
Example - Use a conditional macro definition to enable user configuration of code repetition based on need rather than some "reasonable" upper limit.
+ Now the user can configure the make_type_list primitive without modifying library code.
+
+
+
Example - Use BOOST_PP_REPEAT and a token look-up function to eliminate categorical repetition.
+
+// 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(z, 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
+
+
+ Note: The repetition of the above example can be eliminated using template metaprogramming [Czarnecki] as well.
+ However categorical repetition of operator tokens cannot be completely eliminated by using template metaprogramming.
+
+
+
Example - Use BOOST_PP_REPEAT to avoid O(n*n) repetition.
+
+#ifndef MAX_VEC_ARG_CNT
+#define MAX_VEC_ARG_CNT 8
+#endif
+
+// ...
+
+#define ARG_FUN(z, i, _) BOOST_PP_COMMA_IF(i) T a ## i
+#define ASSIGN_FUN(z, i, ) (*this)[i] = a ## i;
+
+#define DEF_VEC_CTOR_FUN(z, 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
+
+// ...
+
+
+ How: BOOST_PP_REPEAT is implemented is a special way to enable automatic recursion.
+
+
+
Example - Use BOOST_PP_IF to implement special case for the first element.
+ BOOST_PP_IF enables convenient generation of lists using BOOST_PP_REPEAT.
+
+
+ Note: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 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):
+
+ Note: Like in the above implementation of COMMA_IF, the result of BOOST_PP_IF is often invoked and not the THEN and ELSE parameters.
+ If the parameters were invoked, the code would not expand correctly, because the BOOST_PP_EMPTY parameter would get expanded
+ to nothing before the BOOST_PP_IF would be properly expanded.
+
+
+ How: BOOST_PP_IF is defined for the entire repeat range (psuedo code):
+
+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.
+