You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/macros-by-example.md
+214
Original file line number
Diff line number
Diff line change
@@ -195,6 +195,220 @@ compiler knows how to expand them properly:
195
195
not have the same number. This requirement applies to every layer of nested
196
196
repetitions.
197
197
198
+
## Meta variable expressions
199
+
200
+
Give access to additional metadata about meta variables that otherwise would be difficult or even impossible to get through elements such as `count` or `index`.
201
+
202
+
### count($ident, depth)
203
+
204
+
Expands to an unsuffixed integer literal representing the number of times a ***meta variable*** repeats in total.
205
+
206
+
The output of `count` depends on where it is placed as well the provided index. If no index is provided, then it will always start at the innermost level.
207
+
208
+
```rust
209
+
macro_rules!count_idents {
210
+
( $( $i:ident ),* ) => {
211
+
${count($i)}
212
+
};
213
+
}
214
+
215
+
fnmain() {
216
+
assert_eq!(count_idents!(a, b, c), 3);
217
+
}
218
+
```
219
+
220
+
If repetitions are nested, then the optional depth parameter can be used to limit the number of nested repetitions that are counted.
Sometimes it is desired to repeat an expansion the same number of times as a meta variable repeats but without actually expanding the meta variable. It may be possible to work around this by expanding the meta variable in an expression like `{ let _ = $x; 1 }`, where the expanded value of `$x` is ignored, but this is only possible if what `$x` expands to is valid in this kind of expression.
273
+
274
+
The `ignore` meta variable acts as if ident was used for the purposes of repetition, but expands to nothing.
275
+
276
+
### index(depth)
277
+
278
+
Expands to an unsuffixed integer literal representing the current iteration index of a ***repetition*** at the given depth.
279
+
280
+
The output of `index` depends on where it is placed as well the provided index. If no index is provided, then it will always start at the innermost level.
Expands to an unsuffixed integer literal representing the sum or length of a ***repetition*** at a given depth.
355
+
356
+
The output of `length` depends on where it is placed as well the provided index. If no index is provided, then it will always start at the innermost level.
357
+
358
+
```rust
359
+
macro_rules!array {
360
+
( $( $i:ident ),* ) => {
361
+
[${length()}, )*]
362
+
};
363
+
}
364
+
365
+
fnmain() {
366
+
assert_eq!(array!(A, B, C), [3, 3, 3]);
367
+
}
368
+
```
369
+
370
+
If repetitions are nested, then the optional depth parameter can be used to limit the number of nested repetitions that are counted.
371
+
372
+
```rust
373
+
macro_rules!innermost0 {
374
+
( $( $a:ident:$( $b:literal ),* );+ ) => {
375
+
[$( $( ${ignore($b)} ${length()}, )* )+]
376
+
};
377
+
}
378
+
379
+
macro_rules!innermost1 {
380
+
( $( $a:ident:$( $b:literal ),* );+ ) => {
381
+
[$( $( ${ignore($b)} ${length(1)}, )* )+]
382
+
};
383
+
}
384
+
385
+
macro_rules!outermost {
386
+
( $( $a:ident:$( $b:literal ),* );+ ) => {
387
+
[$( ${ignore($a)} ${length()}, )+]
388
+
};
389
+
}
390
+
391
+
fnmain() {
392
+
// 1 2 3 = 3 elements
393
+
// 4 5 = 2 elements
394
+
//
395
+
// 3 and 2 elements repeating 3 and 2 times in the innermost loop
0 commit comments