Lambda capture pattern matching
To find and replace a lambda capture, create a struct that inherits publicly
from bronto::rewrite_lambda_capture and use the BRONTO_BEFORE() and
BRONTO_AFTER() annotations to identify captures and define their
replacements.
struct RewriteCapture : bronto::rewrite_lambda_capture {
// Matches any capture of a variable of type `int` by value.
BRONTO_BEFORE()
void before(int x) { [x] {}; }
// Rewrites it to capture by reference.
BRONTO_AFTER()
void after(int x) { [&x] {}; }
};BRONTO_BEFORE
Requirements
Each struct inheriting from bronto::rewrite_lambda_capture must have one
member function marked BRONTO_BEFORE(). This function must contain a single
lambda expression with exactly one capture.
Semantics
The capture in the lambda expression defines the pattern to be matched. This
includes the capture kind (by value [x] or by reference [&x]) and the type
of the captured variable.
Both explicit and implicit captures (from a capture-default) can be matched.
For example, if the pattern specifies a capture by value [x], it will match:
- Explicit captures by value:
[x] { ... } - Implicit captures by value when
[=]is used:[=] { ... x; }
Parameters
The function parameters are used to match the type of the captured variable. If a parameter name is used in the capture list, it acts as a "hole" that binds to the captured variable.
BRONTO_AFTER
Requirements
Each struct inheriting from bronto::rewrite_lambda_capture may have one
member function marked BRONTO_AFTER(). This function must contain a single
lambda expression with exactly one capture representing how a matching capture
should be transformed.
Semantics
The capture in the BRONTO_AFTER lambda defines the replacement for the
matched capture. The captured variable name will remain unchanged, but its
capture kind can be modified (e.g., from [x] to [&x]) or initialization
added (e.g. from [&x] to [x = expr]).
Limitations
- Rewriting
thisor*thiscaptures is not supported. - Matching init-captures (e.g.,
[x = expr]) is not presently supported.
Use as a Usage Constraint
bronto::rewrite_lambda_capture can also be used as a nested struct within
a bronto::rewrite_decl rule using BRONTO_USAGE. This allows you to
specifically target and rewrite how a particular variable is captured when it
is used within a lambda.
struct Rule : bronto::rewrite_decl {
BRONTO_BEFORE()
void before(auto expr) { int x = expr; }
struct BRONTO_USAGE(allowed) Capture : bronto::rewrite_lambda_capture {
// Match any time this specific variable `x` is captured by value.
BRONTO_BEFORE()
void before(int x) { [x] {}; }
// And rewrite it to be captured by reference.
BRONTO_AFTER()
void after(int x) { [&x] {}; }
};
};See it in action on compiler explorer