BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bsls_macrorepeat.h
Go to the documentation of this file.
1/// @file bsls_macrorepeat.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bsls_macrorepeat.h -*-C++-*-
8#ifndef INCLUDED_BSLS_MACROREPEAT
9#define INCLUDED_BSLS_MACROREPEAT
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bsls_macrorepeat bsls_macrorepeat
15/// @brief repeat a macro invocation with different numeric arguments.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bsls
19/// @{
20/// @addtogroup bsls_macrorepeat
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bsls_macrorepeat-purpose"> Purpose</a>
25/// * <a href="#bsls_macrorepeat-classes"> Classes </a>
26/// * <a href="#bsls_macrorepeat-macros"> Macros </a>
27/// * <a href="#bsls_macrorepeat-description"> Description </a>
28/// * <a href="#bsls_macrorepeat-usage"> Usage </a>
29/// * <a href="#bsls_macrorepeat-example-1-repeated-template-instantiation"> Example 1: Repeated Template Instantiation </a>
30/// * <a href="#bsls_macrorepeat-example-2-repeated-function-arguments"> Example 2: Repeated Function Arguments </a>
31/// * <a href="#bsls_macrorepeat-example-3-bitmask-computation"> Example 3: Bitmask Computation </a>
32///
33/// # Purpose {#bsls_macrorepeat-purpose}
34/// repeat a macro invocation with different numeric arguments.
35///
36/// # Classes {#bsls_macrorepeat-classes}
37///
38///
39/// # Macros {#bsls_macrorepeat-macros}
40///
41/// - BSLS_MACROREPEAT(N, MACRO): Invoke `MACRO(1) MACRO(2) ... MACRO(N)`
42/// - BSLS_MACROREPEAT_COMMA(N, MACRO): `N` comma-separated invocations of `MACRO`
43/// - BSLS_MACROREPEAT_SEP(N, MACRO, S): `N` invocations of `MACRO` separated by S
44///
45/// @see
46///
47/// # Description {#bsls_macrorepeat-description}
48/// This component provides a set of macros that expand to multiple
49/// repetitions of a user-specified "repetition phrase". The repetition phrase
50/// is specified as macro that is invoked multiple times in each invocation of a
51/// `BSLS_MACROREPEAT*` macro. For example:
52/// @code
53/// #define FOO(n) foo ## n
54/// doit(BSLS_MACROREPEAT_COMMA(5, FOO));
55/// @endcode
56/// will expand FOO(n) with arguments 1 through 5, inserting commas between the
57/// expansions, resulting in:
58/// @code
59/// doit(foo1, foo2, foo3, foo4, foo5);
60/// @endcode
61/// Use of these macros is less error-prone and often more compact than manually
62/// repeating the specified pattern. In addition, it is sometimes more readable
63/// than the cut-and-paste alternative because the reader does not need to
64/// examine each argument to verify that it forms a linear sequence.
65///
66/// Each of these macros can appear within the repetition phrase of another of
67/// these macros but, because of limitations in the C proprocessor language,
68/// none of these macros can appear (directly or indirectly) within its own
69/// repetition phrase.
70///
71/// ## Usage {#bsls_macrorepeat-usage}
72///
73///
74/// The following examples demonstrate potential uses of the macros in this
75/// component.
76///
77/// ### Example 1: Repeated Template Instantiation {#bsls_macrorepeat-example-1-repeated-template-instantiation}
78///
79///
80/// In this example, we wish to explicitly instantiate a template with a
81/// sequence of integer values. First, assume a function template `foo<V>` that
82/// adds the (compile-time) value `V` to a global `total` each time it is
83/// called:
84/// @code
85/// int total = 0;
86/// template <int V> void foo() { total += V; }
87/// @endcode
88/// Now, if we instantiate and call `foo<X>()` once for each `X` in the range
89/// `2` to `6`. To do that, we create a macro, `FOO_STMNT(X)` which and calls
90/// `foo<X+1>` (i.e., `FOO_STMNT(1)` will call `foo<2>()`). Then we invoke
91/// `FOO_STMNT` 5 times with arguments 1, 2, 3, 4, and 5 using the
92/// `BSLS_MACROREPEAT` macro:
93/// @code
94/// int main() {
95///
96/// #define FOO_STMNT(X) foo<X+1>(); // Semicolon at end of each statement
97/// BSLS_MACROREPEAT(5, FOO_STMNT)
98/// assert(20 == total);
99/// return 0;
100/// }
101/// @endcode
102///
103/// ### Example 2: Repeated Function Arguments {#bsls_macrorepeat-example-2-repeated-function-arguments}
104///
105///
106/// In this example, we supply as series of identical arguments to a function
107/// invocation, using `BSLS_MACROREPEAT_COMMA`. First, assume a function,
108/// `fmtQuartet` that takes four integer arguments and formats them into a
109/// string:
110/// @code
111/// #include <cstring>
112/// #include <cstdio>
113///
114/// void fmtQuartet(char *result, int a, int b, int c, int d) {
115/// std::sprintf(result, "%d %d %d %d", a, b, c, d);
116/// }
117/// @endcode
118/// Now we wish to invoke this function, but in a context where the last three
119/// arguments are always the same as each other. For this situation we define a
120/// macro `X(x)` that ignores its argument and simply expands to an unchanging
121/// set of tokens. If the repeated argument is named `i`, then the expansion of
122/// `X(x)` is simply `(i)`:
123/// @code
124/// int main() {
125/// char buffer[20];
126/// int i = 8;
127/// #define X(x) (i)
128/// @endcode
129/// Finally, we invoke macro `X(x)` three times within the argument list of
130/// `fmtQuart`. We use `BSLS_MACROREPEAT_COMMA` for these invocations, as it
131/// inserts a comma between each repetition:
132/// @code
133/// fmtQuartet(buffer, "%d %d %d %d", 7, BSLS_MACROREPEAT_COMMA(3, X));
134/// assert(0 == std::strcmp(buffer, "7 8 8 8"));
135/// return 0;
136/// }
137/// @endcode
138///
139/// ### Example 3: Bitmask Computation {#bsls_macrorepeat-example-3-bitmask-computation}
140///
141///
142/// In this example, we Compute (at compile time) a 7-bit mask. First, we
143/// defined a macro `BITVAL` that computes the value of a single bit `B` in the
144/// mask:
145/// @code
146/// #define BITVAL(B) (1 << (B - 1))
147/// @endcode
148/// Then we use the `BSLS_MACROREPEAT_SEP` to invoke `BITVAL` 7 times,
149/// separating the repetitions with the bitwise OR operator:
150/// @code
151/// const unsigned mask = BSLS_MACROREPEAT_SEP(7, BITVAL, |);
152///
153/// int main() {
154/// assert(127 == mask);
155/// return 0;
156/// }
157/// @endcode
158/// @}
159/** @} */
160/** @} */
161
162/** @addtogroup bsl
163 * @{
164 */
165/** @addtogroup bsls
166 * @{
167 */
168/** @addtogroup bsls_macrorepeat
169 * @{
170 */
171
172/// Expand to `N` invocations of `MACRO(x)`, where `x` in each invocation is
173/// the next number in the sequence from `1` to `N`. If `N` is `0`, then
174/// the expansion is empty. For example `BSLS_MACROREPEAT(3, XYZ)` expands
175/// to `XYZ(1) XYZ(2) XYZ(3)`. The behavior is undefined unless `N` is a
176/// decimal integer (or is a macro that expands to a decimal integer) in the
177/// range 0 to 20. Note that `MACRO` is typically a macro with one
178/// argument, but may also be a function or functor.
179#define BSLS_MACROREPEAT(N, MACRO) BSLS_MACROREPEAT_##N(MACRO)
180
181/// Expand to `N` comma-separated invocations of `MACRO(x)`, where `x` in
182/// each invocation is the next number in the sequence from `1` to `N`. If
183/// `N` is `0`, then the expansion is empty. For example
184/// `BSLS_MACROREPEAT_COMMA(3, XYZ)` expands to `XYZ(1), XYZ(2), XYZ(3)`.
185/// The behavior is undefined unless `N` is a decimal integer (or is a macro
186/// that expands to a decimal integer) in the range 0 to 20. Note that
187/// `MACRO` is typically a macro with one argument, but may also be a
188/// function or functor.
189#define BSLS_MACROREPEAT_COMMA(N, MACRO) BSLS_MACROREPEAT_C##N(MACRO)
190
191/// Expand to `N` invocations of `MACRO(x)` separated by the token sequence
192/// `S`, where `x` in each invocation is the next number in the sequence
193/// from `1` to `N`. If `N` is `0`, then the expansion is empty. For
194/// example `BSLS_MACROREPEAT_SEP(3, XYZ, ;)` expands to 'XYZ(1) ; XYZ(2) ;
195/// XYZ(3)`. The behavior is undefined unless `N' is a decimal integer (or
196/// is a macro that expands to a decimal integer) in the range 0 to 20.
197/// Note that `MACRO` is typically a macro with one argument, but may also
198/// be a function or functor.
199#define BSLS_MACROREPEAT_SEP(N, MACRO, S) BSLS_MACROREPEAT_S##N(MACRO, S)
200
201// ============================================================================
202// IMPLEMENTATION MACROS
203// ============================================================================
204
205#define BSLS_MACROREPEAT_0(MACRO)
206#define BSLS_MACROREPEAT_1(MACRO) MACRO(1)
207#define BSLS_MACROREPEAT_2(MACRO) BSLS_MACROREPEAT_1(MACRO) MACRO(2)
208#define BSLS_MACROREPEAT_3(MACRO) BSLS_MACROREPEAT_2(MACRO) MACRO(3)
209#define BSLS_MACROREPEAT_4(MACRO) BSLS_MACROREPEAT_3(MACRO) MACRO(4)
210#define BSLS_MACROREPEAT_5(MACRO) BSLS_MACROREPEAT_4(MACRO) MACRO(5)
211#define BSLS_MACROREPEAT_6(MACRO) BSLS_MACROREPEAT_5(MACRO) MACRO(6)
212#define BSLS_MACROREPEAT_7(MACRO) BSLS_MACROREPEAT_6(MACRO) MACRO(7)
213#define BSLS_MACROREPEAT_8(MACRO) BSLS_MACROREPEAT_7(MACRO) MACRO(8)
214#define BSLS_MACROREPEAT_9(MACRO) BSLS_MACROREPEAT_8(MACRO) MACRO(9)
215#define BSLS_MACROREPEAT_10(MACRO) BSLS_MACROREPEAT_9(MACRO) MACRO(10)
216#define BSLS_MACROREPEAT_11(MACRO) BSLS_MACROREPEAT_10(MACRO) MACRO(11)
217#define BSLS_MACROREPEAT_12(MACRO) BSLS_MACROREPEAT_11(MACRO) MACRO(12)
218#define BSLS_MACROREPEAT_13(MACRO) BSLS_MACROREPEAT_12(MACRO) MACRO(13)
219#define BSLS_MACROREPEAT_14(MACRO) BSLS_MACROREPEAT_13(MACRO) MACRO(14)
220#define BSLS_MACROREPEAT_15(MACRO) BSLS_MACROREPEAT_14(MACRO) MACRO(15)
221#define BSLS_MACROREPEAT_16(MACRO) BSLS_MACROREPEAT_15(MACRO) MACRO(16)
222#define BSLS_MACROREPEAT_17(MACRO) BSLS_MACROREPEAT_16(MACRO) MACRO(17)
223#define BSLS_MACROREPEAT_18(MACRO) BSLS_MACROREPEAT_17(MACRO) MACRO(18)
224#define BSLS_MACROREPEAT_19(MACRO) BSLS_MACROREPEAT_18(MACRO) MACRO(19)
225#define BSLS_MACROREPEAT_20(MACRO) BSLS_MACROREPEAT_19(MACRO) MACRO(20)
226
227#define BSLS_MACROREPEAT_C0(MACRO)
228#define BSLS_MACROREPEAT_C1(MACRO) MACRO(1)
229#define BSLS_MACROREPEAT_C2(MACRO) BSLS_MACROREPEAT_C1(MACRO), MACRO(2)
230#define BSLS_MACROREPEAT_C3(MACRO) BSLS_MACROREPEAT_C2(MACRO), MACRO(3)
231#define BSLS_MACROREPEAT_C4(MACRO) BSLS_MACROREPEAT_C3(MACRO), MACRO(4)
232#define BSLS_MACROREPEAT_C5(MACRO) BSLS_MACROREPEAT_C4(MACRO), MACRO(5)
233#define BSLS_MACROREPEAT_C6(MACRO) BSLS_MACROREPEAT_C5(MACRO), MACRO(6)
234#define BSLS_MACROREPEAT_C7(MACRO) BSLS_MACROREPEAT_C6(MACRO), MACRO(7)
235#define BSLS_MACROREPEAT_C8(MACRO) BSLS_MACROREPEAT_C7(MACRO), MACRO(8)
236#define BSLS_MACROREPEAT_C9(MACRO) BSLS_MACROREPEAT_C8(MACRO), MACRO(9)
237#define BSLS_MACROREPEAT_C10(MACRO) BSLS_MACROREPEAT_C9(MACRO), MACRO(10)
238#define BSLS_MACROREPEAT_C11(MACRO) BSLS_MACROREPEAT_C10(MACRO), MACRO(11)
239#define BSLS_MACROREPEAT_C12(MACRO) BSLS_MACROREPEAT_C11(MACRO), MACRO(12)
240#define BSLS_MACROREPEAT_C13(MACRO) BSLS_MACROREPEAT_C12(MACRO), MACRO(13)
241#define BSLS_MACROREPEAT_C14(MACRO) BSLS_MACROREPEAT_C13(MACRO), MACRO(14)
242#define BSLS_MACROREPEAT_C15(MACRO) BSLS_MACROREPEAT_C14(MACRO), MACRO(15)
243#define BSLS_MACROREPEAT_C16(MACRO) BSLS_MACROREPEAT_C15(MACRO), MACRO(16)
244#define BSLS_MACROREPEAT_C17(MACRO) BSLS_MACROREPEAT_C16(MACRO), MACRO(17)
245#define BSLS_MACROREPEAT_C18(MACRO) BSLS_MACROREPEAT_C17(MACRO), MACRO(18)
246#define BSLS_MACROREPEAT_C19(MACRO) BSLS_MACROREPEAT_C18(MACRO), MACRO(19)
247#define BSLS_MACROREPEAT_C20(MACRO) BSLS_MACROREPEAT_C19(MACRO), MACRO(20)
248
249#define BSLS_MACROREPEAT_S0(MACRO,S)
250#define BSLS_MACROREPEAT_S1(MACRO,S) MACRO(1)
251#define BSLS_MACROREPEAT_S2(MACRO,S) BSLS_MACROREPEAT_S1(MACRO,S) S MACRO(2)
252#define BSLS_MACROREPEAT_S3(MACRO,S) BSLS_MACROREPEAT_S2(MACRO,S) S MACRO(3)
253#define BSLS_MACROREPEAT_S4(MACRO,S) BSLS_MACROREPEAT_S3(MACRO,S) S MACRO(4)
254#define BSLS_MACROREPEAT_S5(MACRO,S) BSLS_MACROREPEAT_S4(MACRO,S) S MACRO(5)
255#define BSLS_MACROREPEAT_S6(MACRO,S) BSLS_MACROREPEAT_S5(MACRO,S) S MACRO(6)
256#define BSLS_MACROREPEAT_S7(MACRO,S) BSLS_MACROREPEAT_S6(MACRO,S) S MACRO(7)
257#define BSLS_MACROREPEAT_S8(MACRO,S) BSLS_MACROREPEAT_S7(MACRO,S) S MACRO(8)
258#define BSLS_MACROREPEAT_S9(MACRO,S) BSLS_MACROREPEAT_S8(MACRO,S) S MACRO(9)
259#define BSLS_MACROREPEAT_S10(MACRO,S) BSLS_MACROREPEAT_S9(MACRO,S) S MACRO(10)
260#define BSLS_MACROREPEAT_S11(MACRO,S) BSLS_MACROREPEAT_S10(MACRO,S) S MACRO(11)
261#define BSLS_MACROREPEAT_S12(MACRO,S) BSLS_MACROREPEAT_S11(MACRO,S) S MACRO(12)
262#define BSLS_MACROREPEAT_S13(MACRO,S) BSLS_MACROREPEAT_S12(MACRO,S) S MACRO(13)
263#define BSLS_MACROREPEAT_S14(MACRO,S) BSLS_MACROREPEAT_S13(MACRO,S) S MACRO(14)
264#define BSLS_MACROREPEAT_S15(MACRO,S) BSLS_MACROREPEAT_S14(MACRO,S) S MACRO(15)
265#define BSLS_MACROREPEAT_S16(MACRO,S) BSLS_MACROREPEAT_S15(MACRO,S) S MACRO(16)
266#define BSLS_MACROREPEAT_S17(MACRO,S) BSLS_MACROREPEAT_S16(MACRO,S) S MACRO(17)
267#define BSLS_MACROREPEAT_S18(MACRO,S) BSLS_MACROREPEAT_S17(MACRO,S) S MACRO(18)
268#define BSLS_MACROREPEAT_S19(MACRO,S) BSLS_MACROREPEAT_S18(MACRO,S) S MACRO(19)
269#define BSLS_MACROREPEAT_S20(MACRO,S) BSLS_MACROREPEAT_S19(MACRO,S) S MACRO(20)
270
271#endif // ! defined(INCLUDED_BSLS_MACROREPEAT)
272
273// ----------------------------------------------------------------------------
274// Copyright 2013 Bloomberg Finance L.P.
275//
276// Licensed under the Apache License, Version 2.0 (the "License");
277// you may not use this file except in compliance with the License.
278// You may obtain a copy of the License at
279//
280// http://www.apache.org/licenses/LICENSE-2.0
281//
282// Unless required by applicable law or agreed to in writing, software
283// distributed under the License is distributed on an "AS IS" BASIS,
284// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
285// See the License for the specific language governing permissions and
286// limitations under the License.
287// ----------------------------- END-OF-FILE ----------------------------------
288
289/** @} */
290/** @} */
291/** @} */
#define BSLS_IDENT(str)
Definition bsls_ident.h:195