- 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.
-
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.
+
With variadic macro support a tuple has all of the
+ functionality as an array, knows its own size, and is easier
+ syntactically to use. Because of that an array should be used, as
+ opposed to a tuple, only if your compiler does not support
+ variadic macros.
+
+ 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 tuple is a simple comma-separated list of elements inside
+ parenthesis. For example,
+
(a, b, c)
+
...is a tuple of 3 elements--a, b, and
+ c.
+
Tuples are fast and easy to use. With variadic macro
+ support it is not necessary to know the size of a tuple; without
+ variadic macro support all access to tuples requires
+ knowledge of its size. Use a tuple instead of an array if
+ your compiler supports variadic macros, since a tuple has all of
+ the functionality as an array and is easier syntactically to use.
+
Elements of a tuple can be extracted with BOOST_PP_TUPLE_ELEM.
+
Variadic macros are supported by a number of compilers.
-They are
-macros of the form:
-
-
-
#define SOME_MACRO(ZeroOrMoreParameters,...) macro expansion possible specifying __VA_ARGS__
-
-
The '...' in the parameter list represents the variadic
-data when the macro is invoked and the __VA_ARGS__ in the expansion
-represents the variadic data in the expansion of the macro. Variadic
-data is of the form of 1 or more preprocessor tokens separated by
-commas.
-
-The '...' must be the last parameter in the macro definition and there
-may be 0 or more non-variadic parameters preceding it.
-
-In the expansion of the macro __VA_ARGS__ may be specified 0 or more
-times to represent the variadic data. The variadic data in the
-expansion is a comma separated list of preprocessor tokens representing
-the variadic data which the invoker of the macro enters as the last
-arguments to the macro.
-
The library offers support for variadic macros for those
-compilers
-which support the feature. The library can automatically detect whether
-a compiler supports variadic macros and sets the macro
-BOOST_PP_VARIADICS accordingly to 1 if the compiler supports variadic
-macros or 0 if the compiler does not support variadic macros.
-
-The end-user can #define BOOST_PP_VARIADICS to 1 or 0 himself in a
-translation unit, before including any preprocessor header files, to
-prevent the library from attempting to detect whether the compiler
-supports variadic macros. This has the effect of manually turning on or
-off variadic macro support in the library. Of course if one manually
-turns on variadic macro support in the library, and one's compiler does
-not support variadic macros, functionality in the library which uses
-variadic macros will fail with error messages from the compiler.
-
-When BOOST_PP_VARIADICS is 1, the library offers some extended
-functionality
-by using variadic macros, and also offers extended support for working
-with variadic data.
-
-Support for working with variadic
-data is largely centered on being able to convert variadic data to
-other library data types, since the
-functionality for working with those Boost preprocessor library data
-types is much greater than that for working with variadic data directly.
-
-
-
Notation For Variadic Macros
-
-
In the documentation, headers which have variadic macros,
-and
-variadic macros themselves, have a notation of '(v)' appended to them.
-For the variadic macros themselves this signifies that
-BOOST_PP_VARIADICS must be 1 for those variadic macros to be usable.
-For variadic macros which have a non-variadic equivalent, the
-non-variadic equivalent will be used if BOOST_PP_VARIADICS is set to 0.
-
-
Extended Functionality Using Variadic Macros
-
-
Some macros in the library offer extended
-functionality through the use of variadic macros.
-
-The variadic macro version offers the same functionality
-as the non-variadic version, but because of the ability of the variadic
-parameters to encompass a variable number of arguments, it also offers
-an enhanced syntax using the same macro name.
-
-The macros in the library which offer this enhanced functionality are
-all
-centered on tuple manipulation. With variadic
-macros it is
-possible to
-manipulate tuples without having to know the size of the tuple. So
-while the invoker can still specify the size when using tuple macro
-functionality, there are variadic versions of each of the tuple macros,
-with the exact same name as the non-variadic macro, where the size need
-not be specified.
-
-
Extended Support For Variadic Data
-
The library offers extended support for working with
-variadic data
-which goes beyond the functionality offered by the C++ specification
-for variadic macros. It does this through preprocessor programming and
-by using some of the other functionality in the library itself. Header
-and macro names
-in the library which offer extended support for working with variadic
-data, and need the compiler to support variadic macros, are marked with
-a (v)to indicate a variadic macro.
-
-The form of the functionality which the library offers is centered on
-two macros which work with variadic data itself, and a set of macros
-which convert between variadic data and other library data
-types.
-
-The two macros are BOOST_PP_VARIADIC_ELEM and BOOST_PP_VARIADIC_SIZE,
-which respectively return a particular token of variadic data and the
-number of tokens of variadic data.
-
-The macros for converting variadic data to the library's data types are
-BOOST_PP_VARIADIC_TO_ARRAY, BOOST_PP_VARIADIC_TO_LIST,
-BOOST_PP_VARIADIC_TO_SEQ, and BOOST_PP_VARIADIC_TO_TUPLE.
-
-All of these macros need compiler support for variadic data and only
-exist if BOOST_PP_VARIADICS is 1.
-
-The remaining four macros, which convert from a library data type
-to comma-separated preprocessor tokens, which is the form of
-variadic data, do not need compiler support for variadic
-macros. These functions are BOOST_PP_ARRAY_ENUM, BOOST_PP_LIST_ENUM,
-BOOST_PP_SEQ_ENUM, and BOOST_PP_TUPLE_ENUM. However if one wishes to
-use this variadic data reliably as arguments to other macros, one needs
-variadic macro support.
-
- Using Variadic Data
-
Variadic data exists in the
-form of comma-separated preprocessor tokens. This is the case whether
-the variadic data comes from the __VA_ARGS__ of a variadic macro, from
-the conversion of a library's data type to variadic data, or the
-manual construction of comma-separated preprocessing tokens by the
-programmer writing a macro.
-
-The easiest way to work with
-variadic data internally is to convert it to a library data type.
-Library data types, whether an array, list,
-sequence,
-or tuple, have a rich set of functionality for
-manipulating
-data whereas
-variadic data functionality in the library only allows one to access
-the variadic data as a whole or to access a single token of the
-variadic data at a time.
-
-The user of the library still may
-choose to pass variadic data back into internal macros rather than
-convert it to other library data types. There is no problem passing
-variadic data as a whole to variadic macros as the last parameter of
-the macro. However:
-
-Attempting to pass
-variadic data as a
-whole directly into a non-variadic macro is not guaranteed to work and
-may fail.
-
-This occurs because of a preprocessor weakness in a number
-of compilers, currently most notably Visual C++. Even passing variadic
-data as arguments to a non-variadic macro, when it is not represented
-in
-the form of __VA_ARGS__, may fail with certain compilers.
-
-What follows are very simple examples, showing how variadic data can be
-passed to a non-variadic macro.
-
-First an example of what NOT to do.
-
-
Example - Passing variadic data as a whole to a
-non-variadic
-macro. DO NOT DO.
/* The following should not be done and is not guaranteed to work with compilers. */
int xx = MACRO_ARG_2(VAR_MACRO(2,3));
-
-
There are two ways to pass variadic data to a non-variadic
-macro.
-The
-first of these is to pass the individual tokens of the variadic data
-separately to the non-variadic macro using the BOOST_PP_VARIADIC_ELEM
-macro in the library.
-
-
Example - Passing individual variadic data tokens to
-a
-non-variadic macro.
-
int xx = MACRO_ARG_2 ( BOOST_PP_VARIADIC_ELEM(0,VAR_MACRO(2,3)), BOOST_PP_VARIADIC_ELEM(1,VAR_MACRO(2,3)) );
-
-
The second way is to use a macro in the library called
-BOOST_PP_OVERLOAD.
-This macro allows one to "overload" a variadic macro to non-variadic
-macros of different numbers of parameters, using a common prefix.
-
-
Example - Passing variadic data as a whole to
-BOOST_PP_OVERLOAD
-and on to a non-variadic macro.
-
int xx = BOOST_PP_OVERLOAD(MACRO_ARG_,VAR_MACRO(2,3))(VAR_MACRO(2,3));
/* For Visual C++ it is necessary to do this */
int xx = BOOST_PP_CAT(BOOST_PP_OVERLOAD(MACRO_ARG_,VAR_MACRO(2,3))(VAR_MACRO(2,3)),BOOST_PP_EMPTY());
-
-
Although these techniques will work when passing variadic
-data to
-non-variadic macros, it is much better and less problematical to
-work internally with the existing library data types and to only use
-variadic
-macros as an interface for end-users when there is a need to have a
-macro which takes a
-variable number of parameters.
-
Variadic macros are supported by a number of compilers.
+ They are
+ macros of the form:
+
+
+
#define SOME_MACRO(ZeroOrMoreParameters,...) macro expansion possible specifying __VA_ARGS__
+
+
The '...' in the parameter list represents the variadic
+ data when the macro is invoked and the __VA_ARGS__ in the expansion
+ represents the variadic data in the expansion of the macro. Variadic
+ data is of the form of 1 or more preprocessor tokens separated by
+ commas.
+
+ The '...' must be the last parameter in the macro definition and there
+ may be 0 or more non-variadic parameters preceding it.
+
+ In the expansion of the macro __VA_ARGS__ may be specified 0 or more
+ times to represent the variadic data. The variadic data in the
+ expansion is a comma separated list of preprocessor tokens representing
+ the variadic data which the invoker of the macro enters as the last
+ arguments to the macro.
+
The library offers support for variadic macros for those
+ compilers
+ which support the feature. The library can automatically detect whether
+ a compiler supports variadic macros and sets the macro
+ BOOST_PP_VARIADICS accordingly to 1 if the compiler supports variadic
+ macros or 0 if the compiler does not support variadic macros.
+
+ The end-user can #define BOOST_PP_VARIADICS to 1 or 0 himself in a
+ translation unit, before including any preprocessor header files, to
+ prevent the library from attempting to detect whether the compiler
+ supports variadic macros. This has the effect of manually turning on or
+ off variadic macro support in the library. Of course if one manually
+ turns on variadic macro support in the library, and one's compiler does
+ not support variadic macros, functionality in the library which uses
+ variadic macros will fail with error messages from the compiler.
+
+ When BOOST_PP_VARIADICS is 1, the library offers some extended
+ functionality
+ by using variadic macros, and also offers extended support for working
+ with variadic data.
+
+ Support for working with variadic
+ data is largely centered on being able to convert variadic data to
+ other library data types, since the
+ functionality for working with those Boost preprocessor library data
+ types is much greater than that for working with variadic data directly.
+
+
+
Notation For Variadic Macros
+
+
In the documentation, headers which have variadic macros,
+ and
+ variadic macros themselves, have a notation of '(v)' appended to them.
+ For the variadic macros themselves this signifies that
+ BOOST_PP_VARIADICS must be 1 for those variadic macros to be usable.
+ For variadic macros which have a non-variadic equivalent, the
+ non-variadic equivalent will be used if BOOST_PP_VARIADICS is set to 0.
+
+
Extended Functionality Using Variadic Macros
+
+
Some macros in the library offer extended
+ functionality through the use of variadic macros.
+
+ The variadic macro version offers the same functionality
+ as the non-variadic version, but because of the ability of the variadic
+ parameters to encompass a variable number of arguments, it also offers
+ an enhanced syntax using the same macro name.
+
+ The macros in the library which offer this enhanced functionality are
+ all
+ centered on tuple manipulation. With variadic
+ macros it is
+ possible to
+ manipulate tuples without having to know the size of the tuple. So
+ while the invoker can still specify the size when using tuple macro
+ functionality, there are variadic versions of each of the tuple macros,
+ with the exact same name as the non-variadic macro, where the size need
+ not be specified.
+
+
Extended Support For Variadic Data
+
The library offers extended support for working with
+ variadic data
+ which goes beyond the functionality offered by the C++ specification
+ for variadic macros. It does this through preprocessor programming and
+ by using some of the other functionality in the library itself. Header
+ and macro names
+ in the library which offer extended support for working with variadic
+ data, and need the compiler to support variadic macros, are marked with
+ a (v)to indicate a variadic macro.
+
+ The form of the functionality which the library offers is centered on
+ two macros which work with variadic data itself, and a set of macros
+ which convert between variadic data and other library data
+ types.
+
+ The two macros are BOOST_PP_VARIADIC_ELEM and BOOST_PP_VARIADIC_SIZE,
+ which respectively return a particular token of variadic data and the
+ number of tokens of variadic data.
+
+ The macros for converting variadic data to the library's data types are
+ BOOST_PP_VARIADIC_TO_ARRAY, BOOST_PP_VARIADIC_TO_LIST,
+ BOOST_PP_VARIADIC_TO_SEQ, and BOOST_PP_VARIADIC_TO_TUPLE.
+
+ All of these macros need compiler support for variadic data and only
+ exist if BOOST_PP_VARIADICS is 1.
+
+ The remaining four macros, which convert from a library data type
+ to comma-separated preprocessor tokens, which is the form of
+ variadic data, do not need compiler support for variadic
+ macros. These functions are BOOST_PP_ARRAY_ENUM, BOOST_PP_LIST_ENUM,
+ BOOST_PP_SEQ_ENUM, and BOOST_PP_TUPLE_ENUM. However if one wishes to
+ use this variadic data reliably as arguments to other macros, one needs
+ variadic macro support.
+
+ Using a Tuple Instead of an Array
+
+
An array as a preprocessor data type is a two-element tuple where the
+ first element is the array size and the second element is a tuple which
+ constitutes the array data. Because a tuple knows its own size when the
+ compiler supports variadic macros, there is no reason to use the array preprocessor
+ data type as opposed to the tuple preprocessor data type; the tuple data
+ type now has all of the functionality which the array data type has and is
+ syntactically easier to use. With variadic macro support, which is now
+ officially part of the latest C++ standard, the preprocessor array data
+ type is essentially obsolete for conforming C++ compilers. Only if your
+ compiler does not support variadic macros is the preprocessor array data
+ type still useful.
+ Using Variadic Data
+
Variadic data exists in the
+ form of comma-separated preprocessor tokens. This is the case whether
+ the variadic data comes from the __VA_ARGS__ of a variadic macro, from
+ the conversion of a library's data type to variadic data, or the
+ manual construction of comma-separated preprocessing tokens by the
+ programmer writing a macro.
+
+ The easiest way to work with
+ variadic data internally is to convert it to a library data type.
+ Library data types, whether an array, list,
+ sequence,
+ or tuple, have a rich set of functionality for
+ manipulating
+ data whereas
+ variadic data functionality in the library only allows one to access
+ the variadic data as a whole or to access a single token of the
+ variadic data at a time.
+
+ The user of the library still may
+ choose to pass variadic data back into internal macros rather than
+ convert it to other library data types. There is no problem passing
+ variadic data as a whole to variadic macros as the last parameter of
+ the macro. However:
+
+ Attempting to pass
+ variadic data as a
+ whole directly into a non-variadic macro is not guaranteed to work and
+ may fail.
+
+ This occurs because of a preprocessor weakness in a number
+ of compilers, currently most notably Visual C++. Even passing variadic
+ data as arguments to a non-variadic macro, when it is not represented
+ in
+ the form of __VA_ARGS__, may fail with certain compilers.
+
+ What follows are very simple examples, showing how variadic data can be
+ passed to a non-variadic macro.
+
+ First an example of what NOT to do.
+
+
Example - Passing variadic data as a whole to a
+ non-variadic
+ macro. DO NOT DO.
/* The following should not be done and is not guaranteed to work with compilers. */
int xx = MACRO_ARG_2(VAR_MACRO(2,3));
+
+
There are two ways to pass variadic data to a non-variadic
+ macro.
+ The
+ first of these is to pass the individual tokens of the variadic data
+ separately to the non-variadic macro using the BOOST_PP_VARIADIC_ELEM
+ macro in the library.
+
+
Example - Passing individual variadic data tokens to
+ a
+ non-variadic macro.
+
int xx = MACRO_ARG_2 ( BOOST_PP_VARIADIC_ELEM(0,VAR_MACRO(2,3)), BOOST_PP_VARIADIC_ELEM(1,VAR_MACRO(2,3)) );
+
+
The second way is to use a macro in the library called
+ BOOST_PP_OVERLOAD.
+ This macro allows one to "overload" a variadic macro to non-variadic
+ macros of different numbers of parameters, using a common prefix.
+
+
Example - Passing variadic data as a whole to
+ BOOST_PP_OVERLOAD
+ and on to a non-variadic macro.
+
int xx = BOOST_PP_OVERLOAD(MACRO_ARG_,VAR_MACRO(2,3))(VAR_MACRO(2,3));
/* For Visual C++ it is necessary to do this */
int xx = BOOST_PP_CAT(BOOST_PP_OVERLOAD(MACRO_ARG_,VAR_MACRO(2,3))(VAR_MACRO(2,3)),BOOST_PP_EMPTY());
+
+
+
Although these techniques will work when passing variadic
+ data to
+ non-variadic macros, it is much better and less problematical to
+ work internally with the existing library data types and to only use
+ variadic
+ macros as an interface for end-users when there is a need to have a
+ macro which takes a
+ variable number of parameters.
+