summaryrefslogtreecommitdiffstats
path: root/mfbt/MacroForEach.h
blob: c3067e3620048e7ef7626f3778aeeaac280dffae (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/*
 * Implements a higher-order macro for iteratively calling another macro with
 * fixed leading arguments, plus a trailing element picked from a second list
 * of arguments.
 */

#ifndef mozilla_MacroForEach_h
#define mozilla_MacroForEach_h

#include "mozilla/MacroArgs.h"

/*
 * MOZ_FOR_EACH(aMacro, aFixedArgs, aArgs) expands to N calls to the macro
 * |aMacro| where N is equal the number of items in the list |aArgs|. The
 * arguments for each |aMacro| call are composed of *all* arguments in the list
 * |aFixedArgs| as well as a single argument in the list |aArgs|. For example:
 *
 *   #define MACRO_A(x) x +
 *   int a = MOZ_FOR_EACH(MACRO_A, (), (1, 2, 3)) 0;
 *   // Expands to:     MACRO_A(1) MACRO_A(2) MACRO_A(3) 0;
 *   // And further to: 1 + 2 + 3 + 0;
 *
 *   #define MACRO_B(k, x) (k + x) +
 *   int b = MOZ_FOR_EACH(MACRO_B, (5,), (1, 2)) 0;
 *   // Expands to: MACRO_B(5, 1) MACRO_B(5, 2) 0;
 *
 *   #define MACRO_C(k1, k2, x) (k1 + k2 + x) +
 *   int c = MOZ_FOR_EACH(MACRO_C, (5, 8,), (1, 2)) 0;
 *   // Expands to: MACRO_B(5, 8, 1) MACRO_B(5, 8, 2) 0;
 *
 * MOZ_FOR_EACH_SEPARATED(aMacro, aSeparator, aFixedArgs, aArgs) is identical
 * to MOZ_FOR_EACH except that it inserts |aSeparator| between each call to
 * the macro. |aSeparator| must be wrapped by parens. For example:
 *
 *   #define MACRO_A(x) x
 *   int a = MOZ_FOR_EACH_SEPARATED(MACRO_A, (+), (), (1, 2, 3));
 *   // Expands to: MACRO_A(1) + MACRO_A(2) + MACRO_A(3);
 *   // And further to: 1 + 2 + 3
 *
 *   #define MACRO_B(t, n) t n
 *   void test(MOZ_FOR_EACH_SEPARATED(MACRO_B, (,), (int,), (a, b)));
 *   // Expands to: void test(MACRO_B(int, a) , MACRO_B(int, b));
 *   // And further to: void test(int a , int b);
 *
 * If the |aFixedArgs| list is not empty, a trailing comma must be included.
 *
 * The |aArgs| list may be up to 50 items long.
 */
#define MOZ_FOR_EACH_EXPAND_HELPER(...) __VA_ARGS__
#define MOZ_FOR_EACH_GLUE(a, b) a b
#define MOZ_FOR_EACH_SEPARATED(aMacro, aSeparator, aFixedArgs, aArgs)     \
  MOZ_FOR_EACH_GLUE(MOZ_PASTE_PREFIX_AND_ARG_COUNT(                       \
                        MOZ_FOR_EACH_, MOZ_FOR_EACH_EXPAND_HELPER aArgs), \
                    (aMacro, aSeparator, aFixedArgs, aArgs))
#define MOZ_FOR_EACH(aMacro, aFixedArgs, aArgs) \
  MOZ_FOR_EACH_SEPARATED(aMacro, (), aFixedArgs, aArgs)

#define MOZ_FOR_EACH_HELPER_GLUE(a, b) a b
#define MOZ_FOR_EACH_HELPER(aMacro, aFixedArgs, aArgs) \
  MOZ_FOR_EACH_HELPER_GLUE(                            \
      aMacro, (MOZ_FOR_EACH_EXPAND_HELPER aFixedArgs MOZ_ARG_1 aArgs))

#define MOZ_FOR_EACH_0(m, s, fa, a)
#define MOZ_FOR_EACH_1(m, s, fa, a) MOZ_FOR_EACH_HELPER(m, fa, a)
#define MOZ_FOR_EACH_2(m, s, fa, a) \
  MOZ_FOR_EACH_HELPER(m, fa, a)     \
  MOZ_FOR_EACH_EXPAND_HELPER s MOZ_FOR_EACH_1(m, s, fa, (MOZ_ARGS_AFTER_1 a))
#define MOZ_FOR_EACH_3(m, s, fa, a) \
  MOZ_FOR_EACH_HELPER(m, fa, a)     \
  MOZ_FOR_EACH_EXPAND_HELPER s MOZ_FOR_EACH_2(m, s, fa, (MOZ_ARGS_AFTER_1 a))
#define MOZ_FOR_EACH_4(m, s, fa, a) \
  MOZ_FOR_EACH_HELPER(m, fa, a)     \
  MOZ_FOR_EACH_EXPAND_HELPER s MOZ_FOR_EACH_3(m, s, fa, (MOZ_ARGS_AFTER_1 a))
#define MOZ_FOR_EACH_5(m, s, fa, a) \
  MOZ_FOR_EACH_HELPER(m, fa, a)     \
  MOZ_FOR_EACH_EXPAND_HELPER s MOZ_FOR_EACH_4(m, s, fa, (MOZ_ARGS_AFTER_1 a))
#define MOZ_FOR_EACH_6(m, s, fa, a) \
  MOZ_FOR_EACH_HELPER(m, fa, a)     \
  MOZ_FOR_EACH_EXPAND_HELPER s MOZ_FOR_EACH_5(m, s, fa, (MOZ_ARGS_AFTER_1 a))
#define MOZ_FOR_EACH_7(m, s, fa, a) \
  MOZ_FOR_EACH_HELPER(m, fa, a)     \
  MOZ_FOR_EACH_EXPAND_HELPER s MOZ_FOR_EACH_6(m, s, fa, (MOZ_ARGS_AFTER_1 a))
#define MOZ_FOR_EACH_8(m, s, fa, a) \
  MOZ_FOR_EACH_HELPER(m, fa, a)     \
  MOZ_FOR_EACH_EXPAND_HELPER s MOZ_FOR_EACH_7(m, s, fa, (MOZ_ARGS_AFTER_1 a))
#define MOZ_FOR_EACH_9(m, s, fa, a) \
  MOZ_FOR_EACH_HELPER(m, fa, a)     \
  MOZ_FOR_EACH_EXPAND_HELPER s MOZ_FOR_EACH_8(m, s, fa, (MOZ_ARGS_AFTER_1 a))
#define MOZ_FOR_EACH_10(m, s, fa, a) \
  MOZ_FOR_EACH_HELPER(m, fa, a)      \
  MOZ_FOR_EACH_EXPAND_HELPER s MOZ_FOR_EACH_9(m, s, fa, (MOZ_ARGS_AFTER_1 a))
#define MOZ_FOR_EACH_11(m, s, fa, a) \
  MOZ_FOR_EACH_HELPER(m, fa, a)      \
  MOZ_FOR_EACH_EXPAND_HELPER s MOZ_FOR_EACH_10(m, s, fa, (MOZ_ARGS_AFTER_1 a))
#define MOZ_FOR_EACH_12(m, s, fa, a) \
  MOZ_FOR_EACH_HELPER(m, fa, a)      \
  MOZ_FOR_EACH_EXPAND_HELPER s MOZ_FOR_EACH_11(m, s, fa, (MOZ_ARGS_AFTER_1 a))
#define MOZ_FOR_EACH_13(m, s, fa, a) \
  MOZ_FOR_EACH_HELPER(m, fa, a)      \
  MOZ_FOR_EACH_EXPAND_HELPER s MOZ_FOR_EACH_12(m, s, fa, (MOZ_ARGS_AFTER_1 a))
#define MOZ_FOR_EACH_14(m, s, fa, a) \
  MOZ_FOR_EACH_HELPER(m, fa, a)      \
  MOZ_FOR_EACH_EXPAND_HELPER s MOZ_FOR_EACH_13(m, s, fa, (MOZ_ARGS_AFTER_1 a))
#define MOZ_FOR_EACH_15(m, s, fa, a) \
  MOZ_FOR_EACH_HELPER(m, fa, a)      \
  MOZ_FOR_EACH_EXPAND_HELPER s MOZ_FOR_EACH_14(m, s, fa, (MOZ_ARGS_AFTER_1 a))
#define MOZ_FOR_EACH_16(m, s, fa, a) \
  MOZ_FOR_EACH_HELPER(m, fa, a)      \
  MOZ_FOR_EACH_EXPAND_HELPER s MOZ_FOR_EACH_15(m, s, fa, (MOZ_ARGS_AFTER_1 a))
#define MOZ_FOR_EACH_17(m, s, fa, a) \
  MOZ_FOR_EACH_HELPER(m, fa, a)      \
  MOZ_FOR_EACH_EXPAND_HELPER s MOZ_FOR_EACH_16(m, s, fa, (MOZ_ARGS_AFTER_1 a))
#define MOZ_FOR_EACH_18(m, s, fa, a) \
  MOZ_FOR_EACH_HELPER(m, fa, a)      \
  MOZ_FOR_EACH_EXPAND_HELPER s MOZ_FOR_EACH_17(m, s, fa, (MOZ_ARGS_AFTER_1 a))
#define MOZ_FOR_EACH_19(m, s, fa, a) \
  MOZ_FOR_EACH_HELPER(m, fa, a)      \
  MOZ_FOR_EACH_EXPAND_HELPER s MOZ_FOR_EACH_18(m, s, fa, (MOZ_ARGS_AFTER_1 a))
#define MOZ_FOR_EACH_20(m, s, fa, a) \
  MOZ_FOR_EACH_HELPER(m, fa, a)      \
  MOZ_FOR_EACH_EXPAND_HELPER s MOZ_FOR_EACH_19(m, s, fa, (MOZ_ARGS_AFTER_1 a))
#define MOZ_FOR_EACH_21(m, s, fa, a) \
  MOZ_FOR_EACH_HELPER(m, fa, a)      \
  MOZ_FOR_EACH_EXPAND_HELPER s MOZ_FOR_EACH_20(m, s, fa, (MOZ_ARGS_AFTER_1 a))
#define MOZ_FOR_EACH_22(m, s, fa, a) \
  MOZ_FOR_EACH_HELPER(m, fa, a)      \
  MOZ_FOR_EACH_EXPAND_HELPER s MOZ_FOR_EACH_21(m, s, fa, (MOZ_ARGS_AFTER_1 a))
#define MOZ_FOR_EACH_23(m, s, fa, a) \
  MOZ_FOR_EACH_HELPER(m, fa, a)      \
  MOZ_FOR_EACH_EXPAND_HELPER s MOZ_FOR_EACH_22(m, s, fa, (MOZ_ARGS_AFTER_1 a))
#define MOZ_FOR_EACH_24(m, s, fa, a) \
  MOZ_FOR_EACH_HELPER(m, fa, a)      \
  MOZ_FOR_EACH_EXPAND_HELPER s MOZ_FOR_EACH_23(m, s, fa, (MOZ_ARGS_AFTER_1 a))
#define MOZ_FOR_EACH_25(m, s, fa, a) \
  MOZ_FOR_EACH_HELPER(m, fa, a)      \
  MOZ_FOR_EACH_EXPAND_HELPER s MOZ_FOR_EACH_24(m, s, fa, (MOZ_ARGS_AFTER_1 a))
#define MOZ_FOR_EACH_26(m, s, fa, a) \
  MOZ_FOR_EACH_HELPER(m, fa, a)      \
  MOZ_FOR_EACH_EXPAND_HELPER s MOZ_FOR_EACH_25(m, s, fa, (MOZ_ARGS_AFTER_1 a))
#define MOZ_FOR_EACH_27(m, s, fa, a) \
  MOZ_FOR_EACH_HELPER(m, fa, a)      \
  MOZ_FOR_EACH_EXPAND_HELPER s MOZ_FOR_EACH_26(m, s, fa, (MOZ_ARGS_AFTER_1 a))
#define MOZ_FOR_EACH_28(m, s, fa, a) \
  MOZ_FOR_EACH_HELPER(m, fa, a)      \
  MOZ_FOR_EACH_EXPAND_HELPER s MOZ_FOR_EACH_27(m, s, fa, (MOZ_ARGS_AFTER_1 a))
#define MOZ_FOR_EACH_29(m, s, fa, a) \
  MOZ_FOR_EACH_HELPER(m, fa, a)      \
  MOZ_FOR_EACH_EXPAND_HELPER s MOZ_FOR_EACH_28(m, s, fa, (MOZ_ARGS_AFTER_1 a))
#define MOZ_FOR_EACH_30(m, s, fa, a) \
  MOZ_FOR_EACH_HELPER(m, fa, a)      \
  MOZ_FOR_EACH_EXPAND_HELPER s MOZ_FOR_EACH_29(m, s, fa, (MOZ_ARGS_AFTER_1 a))
#define MOZ_FOR_EACH_31(m, s, fa, a) \
  MOZ_FOR_EACH_HELPER(m, fa, a)      \
  MOZ_FOR_EACH_EXPAND_HELPER s MOZ_FOR_EACH_30(m, s, fa, (MOZ_ARGS_AFTER_1 a))
#define MOZ_FOR_EACH_32(m, s, fa, a) \
  MOZ_FOR_EACH_HELPER(m, fa, a)      \
  MOZ_FOR_EACH_EXPAND_HELPER s MOZ_FOR_EACH_31(m, s, fa, (MOZ_ARGS_AFTER_1 a))
#define MOZ_FOR_EACH_33(m, s, fa, a) \
  MOZ_FOR_EACH_HELPER(m, fa, a)      \
  MOZ_FOR_EACH_EXPAND_HELPER s MOZ_FOR_EACH_32(m, s, fa, (MOZ_ARGS_AFTER_1 a))
#define MOZ_FOR_EACH_34(m, s, fa, a) \
  MOZ_FOR_EACH_HELPER(m, fa, a)      \
  MOZ_FOR_EACH_EXPAND_HELPER s MOZ_FOR_EACH_33(m, s, fa, (MOZ_ARGS_AFTER_1 a))
#define MOZ_FOR_EACH_35(m, s, fa, a) \
  MOZ_FOR_EACH_HELPER(m, fa, a)      \
  MOZ_FOR_EACH_EXPAND_HELPER s MOZ_FOR_EACH_34(m, s, fa, (MOZ_ARGS_AFTER_1 a))
#define MOZ_FOR_EACH_36(m, s, fa, a) \
  MOZ_FOR_EACH_HELPER(m, fa, a)      \
  MOZ_FOR_EACH_EXPAND_HELPER s MOZ_FOR_EACH_35(m, s, fa, (MOZ_ARGS_AFTER_1 a))
#define MOZ_FOR_EACH_37(m, s, fa, a) \
  MOZ_FOR_EACH_HELPER(m, fa, a)      \
  MOZ_FOR_EACH_EXPAND_HELPER s MOZ_FOR_EACH_36(m, s, fa, (MOZ_ARGS_AFTER_1 a))
#define MOZ_FOR_EACH_38(m, s, fa, a) \
  MOZ_FOR_EACH_HELPER(m, fa, a)      \
  MOZ_FOR_EACH_EXPAND_HELPER s MOZ_FOR_EACH_37(m, s, fa, (MOZ_ARGS_AFTER_1 a))
#define MOZ_FOR_EACH_39(m, s, fa, a) \
  MOZ_FOR_EACH_HELPER(m, fa, a)      \
  MOZ_FOR_EACH_EXPAND_HELPER s MOZ_FOR_EACH_38(m, s, fa, (MOZ_ARGS_AFTER_1 a))
#define MOZ_FOR_EACH_40(m, s, fa, a) \
  MOZ_FOR_EACH_HELPER(m, fa, a)      \
  MOZ_FOR_EACH_EXPAND_HELPER s MOZ_FOR_EACH_39(m, s, fa, (MOZ_ARGS_AFTER_1 a))
#define MOZ_FOR_EACH_41(m, s, fa, a) \
  MOZ_FOR_EACH_HELPER(m, fa, a)      \
  MOZ_FOR_EACH_EXPAND_HELPER s MOZ_FOR_EACH_40(m, s, fa, (MOZ_ARGS_AFTER_1 a))
#define MOZ_FOR_EACH_42(m, s, fa, a) \
  MOZ_FOR_EACH_HELPER(m, fa, a)      \
  MOZ_FOR_EACH_EXPAND_HELPER s MOZ_FOR_EACH_41(m, s, fa, (MOZ_ARGS_AFTER_1 a))
#define MOZ_FOR_EACH_43(m, s, fa, a) \
  MOZ_FOR_EACH_HELPER(m, fa, a)      \
  MOZ_FOR_EACH_EXPAND_HELPER s MOZ_FOR_EACH_42(m, s, fa, (MOZ_ARGS_AFTER_1 a))
#define MOZ_FOR_EACH_44(m, s, fa, a) \
  MOZ_FOR_EACH_HELPER(m, fa, a)      \
  MOZ_FOR_EACH_EXPAND_HELPER s MOZ_FOR_EACH_43(m, s, fa, (MOZ_ARGS_AFTER_1 a))
#define MOZ_FOR_EACH_45(m, s, fa, a) \
  MOZ_FOR_EACH_HELPER(m, fa, a)      \
  MOZ_FOR_EACH_EXPAND_HELPER s MOZ_FOR_EACH_44(m, s, fa, (MOZ_ARGS_AFTER_1 a))
#define MOZ_FOR_EACH_46(m, s, fa, a) \
  MOZ_FOR_EACH_HELPER(m, fa, a)      \
  MOZ_FOR_EACH_EXPAND_HELPER s MOZ_FOR_EACH_45(m, s, fa, (MOZ_ARGS_AFTER_1 a))
#define MOZ_FOR_EACH_47(m, s, fa, a) \
  MOZ_FOR_EACH_HELPER(m, fa, a)      \
  MOZ_FOR_EACH_EXPAND_HELPER s MOZ_FOR_EACH_46(m, s, fa, (MOZ_ARGS_AFTER_1 a))
#define MOZ_FOR_EACH_48(m, s, fa, a) \
  MOZ_FOR_EACH_HELPER(m, fa, a)      \
  MOZ_FOR_EACH_EXPAND_HELPER s MOZ_FOR_EACH_47(m, s, fa, (MOZ_ARGS_AFTER_1 a))
#define MOZ_FOR_EACH_49(m, s, fa, a) \
  MOZ_FOR_EACH_HELPER(m, fa, a)      \
  MOZ_FOR_EACH_EXPAND_HELPER s MOZ_FOR_EACH_48(m, s, fa, (MOZ_ARGS_AFTER_1 a))
#define MOZ_FOR_EACH_50(m, s, fa, a) \
  MOZ_FOR_EACH_HELPER(m, fa, a)      \
  MOZ_FOR_EACH_EXPAND_HELPER s MOZ_FOR_EACH_49(m, s, fa, (MOZ_ARGS_AFTER_1 a))

#endif /* mozilla_MacroForEach_h */