repeat a macro invocation with different numeric arguments.
Outline
Purpose
repeat a macro invocation with different numeric arguments.
Classes
Macros
- See also
Description
This component provides a set of macros that expand to multiple repetitions of a user-specified "repetition phrase". The repetition phrase is specified as macro that is invoked multiple times in each invocation of a BSLS_MACROREPEAT* macro. For example:
#define FOO(n) foo ## n
#define BSLS_MACROREPEAT_COMMA(N, MACRO)
Definition bsls_macrorepeat.h:193
will expand FOO(n) with arguments 1 through 5, inserting commas between the expansions, resulting in:
doit(foo1, foo2, foo3, foo4, foo5);
Use of these macros is less error-prone and often more compact than manually repeating the specified pattern. In addition, it is sometimes more readable than the cut-and-paste alternative because the reader does not need to examine each argument to verify that it forms a linear sequence.
Each of these macros can appear within the repetition phrase of another of these macros but, because of limitations in the C proprocessor language, none of these macros can appear (directly or indirectly) within its own repetition phrase.
Usage
The following examples demonstrate potential uses of the macros in this component.
Example 1: Repeated Template Instantiation
In this example, we wish to explicitly instantiate a template with a sequence of integer values. First, assume a function template foo<V> that adds the (compile-time) value V to a global total each time it is called:
int total = 0;
template <int V> void foo() { total += V; }
Now, if we instantiate and call foo<X>() once for each X in the range 2 to 6. To do that, we create a macro, FOO_STMNT(X) which and calls foo<X+1> (i.e., FOO_STMNT(1) will call foo<2>()). Then we invoke FOO_STMNT 5 times with arguments 1, 2, 3, 4, and 5 using the BSLS_MACROREPEAT macro:
int main() {
#define FOO_STMNT(X) foo<X+1>();
assert(20 == total);
return 0;
}
#define BSLS_MACROREPEAT(N, MACRO)
Definition bsls_macrorepeat.h:181
Example 2: Repeated Function Arguments
In this example, we supply as series of identical arguments to a function invocation, using BSLS_MACROREPEAT_COMMA. First, assume a function, fmtQuartet that takes four integer arguments and formats them into a string:
#include <cstring>
#include <cstdio>
void fmtQuartet(char *result, int length, int a, int b, int c, int d) {
snprintf(result, length, "%d %d %d %d", a, b, c, d);
}
Now we wish to invoke this function, but in a context where the last three arguments are always the same as each other. For this situation we define a macro X(x) that ignores its argument and simply expands to an unchanging set of tokens. If the repeated argument is named i, then the expansion of X(x) is simply (i):
int main() {
char buffer[20];
int i = 8;
#define X(x) (i)
Finally, we invoke macro X(x) three times within the argument list of fmtQuart. We use BSLS_MACROREPEAT_COMMA for these invocations, as it inserts a comma between each repetition:
assert(0 == std::strcmp(buffer, "7 8 8 8"));
return 0;
}
Example 3: Bitmask Computation
In this example, we Compute (at compile time) a 7-bit mask. First, we defined a macro BITVAL that computes the value of a single bit B in the mask:
#define BITVAL(B) (1 << (B - 1))
Then we use the BSLS_MACROREPEAT_SEP to invoke BITVAL 7 times, separating the repetitions with the bitwise OR operator:
int main() {
assert(127 == mask);
return 0;
}
#define BSLS_MACROREPEAT_SEP(N, MACRO, S)
Definition bsls_macrorepeat.h:205
◆ BSLS_MACROREPEAT
| #define BSLS_MACROREPEAT |
( |
|
N, |
|
|
|
MACRO |
|
) |
| BSLS_MACROREPEAT_##N(MACRO) |
Expand to N invocations of MACRO(x), where x in each invocation is the next number in the sequence from 1 to N. If N is 0, then the expansion is empty. For example BSLS_MACROREPEAT(3, XYZ) expands to XYZ(1) XYZ(2) XYZ(3).
- Precondition
- The behavior is undefined unless
N is a decimal integer (or is a macro that expands to a decimal integer) in the range 0 to 20.
- Note
- Note that
MACRO is typically a macro with one argument, but may also be a function or functor.
◆ BSLS_MACROREPEAT_0
| #define BSLS_MACROREPEAT_0 |
( |
|
MACRO | ) |
|
◆ BSLS_MACROREPEAT_1
| #define BSLS_MACROREPEAT_1 |
( |
|
MACRO | ) |
MACRO(1) |
◆ BSLS_MACROREPEAT_10
◆ BSLS_MACROREPEAT_11
◆ BSLS_MACROREPEAT_12
◆ BSLS_MACROREPEAT_13
◆ BSLS_MACROREPEAT_14
◆ BSLS_MACROREPEAT_15
◆ BSLS_MACROREPEAT_16
◆ BSLS_MACROREPEAT_17
◆ BSLS_MACROREPEAT_18
◆ BSLS_MACROREPEAT_19
◆ BSLS_MACROREPEAT_2
◆ BSLS_MACROREPEAT_20
◆ BSLS_MACROREPEAT_3
◆ BSLS_MACROREPEAT_4
◆ BSLS_MACROREPEAT_5
◆ BSLS_MACROREPEAT_6
◆ BSLS_MACROREPEAT_7
◆ BSLS_MACROREPEAT_8
◆ BSLS_MACROREPEAT_9
◆ BSLS_MACROREPEAT_C0
| #define BSLS_MACROREPEAT_C0 |
( |
|
MACRO | ) |
|
◆ BSLS_MACROREPEAT_C1
| #define BSLS_MACROREPEAT_C1 |
( |
|
MACRO | ) |
MACRO(1) |
◆ BSLS_MACROREPEAT_C10
◆ BSLS_MACROREPEAT_C11
◆ BSLS_MACROREPEAT_C12
◆ BSLS_MACROREPEAT_C13
◆ BSLS_MACROREPEAT_C14
◆ BSLS_MACROREPEAT_C15
◆ BSLS_MACROREPEAT_C16
◆ BSLS_MACROREPEAT_C17
◆ BSLS_MACROREPEAT_C18
◆ BSLS_MACROREPEAT_C19
◆ BSLS_MACROREPEAT_C2
◆ BSLS_MACROREPEAT_C20
◆ BSLS_MACROREPEAT_C3
◆ BSLS_MACROREPEAT_C4
◆ BSLS_MACROREPEAT_C5
◆ BSLS_MACROREPEAT_C6
◆ BSLS_MACROREPEAT_C7
◆ BSLS_MACROREPEAT_C8
◆ BSLS_MACROREPEAT_C9
◆ BSLS_MACROREPEAT_COMMA
| #define BSLS_MACROREPEAT_COMMA |
( |
|
N, |
|
|
|
MACRO |
|
) |
| BSLS_MACROREPEAT_C##N(MACRO) |
Expand to N comma-separated invocations of MACRO(x), where x in each invocation is the next number in the sequence from 1 to N. If N is 0, then the expansion is empty. For example BSLS_MACROREPEAT_COMMA(3, XYZ) expands to XYZ(1), XYZ(2), XYZ(3).
- Precondition
- The behavior is undefined unless
N is a decimal integer (or is a macro that expands to a decimal integer) in the range 0 to 20.
- Note
- Note that
MACRO is typically a macro with one argument, but may also be a function or functor.
◆ BSLS_MACROREPEAT_S0
| #define BSLS_MACROREPEAT_S0 |
( |
|
MACRO, |
|
|
|
S |
|
) |
| |
◆ BSLS_MACROREPEAT_S1
| #define BSLS_MACROREPEAT_S1 |
( |
|
MACRO, |
|
|
|
S |
|
) |
| MACRO(1) |
◆ BSLS_MACROREPEAT_S10
◆ BSLS_MACROREPEAT_S11
◆ BSLS_MACROREPEAT_S12
◆ BSLS_MACROREPEAT_S13
◆ BSLS_MACROREPEAT_S14
◆ BSLS_MACROREPEAT_S15
◆ BSLS_MACROREPEAT_S16
◆ BSLS_MACROREPEAT_S17
◆ BSLS_MACROREPEAT_S18
◆ BSLS_MACROREPEAT_S19
◆ BSLS_MACROREPEAT_S2
◆ BSLS_MACROREPEAT_S20
◆ BSLS_MACROREPEAT_S3
◆ BSLS_MACROREPEAT_S4
◆ BSLS_MACROREPEAT_S5
◆ BSLS_MACROREPEAT_S6
◆ BSLS_MACROREPEAT_S7
◆ BSLS_MACROREPEAT_S8
◆ BSLS_MACROREPEAT_S9
◆ BSLS_MACROREPEAT_SEP
| #define BSLS_MACROREPEAT_SEP |
( |
|
N, |
|
|
|
MACRO, |
|
|
|
S |
|
) |
| BSLS_MACROREPEAT_S##N(MACRO, S) |
Expand to N invocations of MACRO(x) separated by the token sequence S, where x in each invocation is the next number in the sequence from 1 to N. If N is 0, then the expansion is empty. For example BSLS_MACROREPEAT_SEP(3, XYZ, ;) expands to 'XYZ(1) ; XYZ(2) ; XYZ(3)`.
- Precondition
- The behavior is undefined unless ‘N’ is a decimal integer (or is a macro that expands to a decimal integer) in the range 0 to 20.
- Note
- Note that
MACRO is typically a macro with one argument, but may also be a function or functor.