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
@@ -196,6 +196,220 @@ compiler knows how to expand them properly:
196
196
not have the same number. This requirement applies to every layer of nested
197
197
repetitions.
198
198
199
+
## Metavariable expressions
200
+
201
+
Gives access to additional information about metavariables that otherwise would be difficult or even impossible to obtain manually.
202
+
203
+
### count($ident, depth)
204
+
205
+
Expands to an unsuffixed integer literal representing the number of times a ***metavariable*** repeats in total.
206
+
207
+
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.
208
+
209
+
```rust
210
+
macro_rules!count_idents {
211
+
( $( $i:ident ),* ) => {
212
+
${count($i)}
213
+
};
214
+
}
215
+
216
+
fnmain() {
217
+
assert_eq!(count_idents!(a, b, c), 3);
218
+
}
219
+
```
220
+
221
+
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 metavariable repeats but without actually expanding the metavariable. It may be possible to work around this by expanding the metavariable 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.
274
+
275
+
The `ignore` metavariable acts as if the ident was used for the purposes of repetition, but expands to nothing.
276
+
277
+
### index(depth)
278
+
279
+
Expands to an unsuffixed integer literal representing the current iteration index of a ***repetition*** at the given depth.
280
+
281
+
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.
356
+
357
+
The output of `len` 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.
358
+
359
+
```rust
360
+
macro_rules!array {
361
+
( $( $i:ident ),* ) => {
362
+
[${len()}, )*]
363
+
};
364
+
}
365
+
366
+
fnmain() {
367
+
assert_eq!(array!(A, B, C), [3, 3, 3]);
368
+
}
369
+
```
370
+
371
+
If repetitions are nested, then the optional depth parameter can be used to limit the number of nested repetitions that are counted.
372
+
373
+
```rust
374
+
macro_rules!innermost0 {
375
+
( $( $a:ident:$( $b:literal ),* );+ ) => {
376
+
[$( $( ${ignore($b)} ${len()}, )* )+]
377
+
};
378
+
}
379
+
380
+
macro_rules!innermost1 {
381
+
( $( $a:ident:$( $b:literal ),* );+ ) => {
382
+
[$( $( ${ignore($b)} ${len(1)}, )* )+]
383
+
};
384
+
}
385
+
386
+
macro_rules!outermost {
387
+
( $( $a:ident:$( $b:literal ),* );+ ) => {
388
+
[$( ${ignore($a)} ${len()}, )+]
389
+
};
390
+
}
391
+
392
+
fnmain() {
393
+
// 1 2 3 = 3 elements
394
+
// 4 5 = 2 elements
395
+
//
396
+
// 3 and 2 elements repeating 3 and 2 times in the innermost loop
0 commit comments