When
Description
An arm of a Match, in one of two forms (selected by argument count). The last argument is always a name you choose; the matched value is bound to it for the arm body (there is no implicit binding – the reader sees where the variable comes from):
When(T, bind)– static: runs iff no earlier arm matched and the
subject’s static type is T; binds bind to the value.
When(N, T, bind)– variant: runs iff no earlier arm matched and the
subject’s runtime tag is Variant(N, ...)’s T; binds bind to the T-typed payload.
Success
Body runs at most once, only on a match, with bind in scope.
Failure
Macro cannot fail. Usable only inside a Match. Forgetting the bind name (When(T) / When(N, T)) is a compile error – in particular a variant arm missing its name does NOT silently become a static match. When(N, T, bind) for a T the variant cannot hold is a compile error (no as_T member).
Usage example (Cross-references)
Usage examples (Cross-references)
- In
Variant.c:21:
bool hit = false;
Match(n) {
When(Number, int, v) hit = (v == 42);
When(Number, double, v) hit = false;
}- In
Variant.c:22:
Match(n) {
When(Number, int, v) hit = (v == 42);
When(Number, double, v) hit = false;
}- In
Variant.c:28:
bool hd = false;
Match(m) {
When(Number, int, v) hd = false;
When(Number, double, v) hd = (v == 2.5);
}- In
Variant.c:29:
Match(m) {
When(Number, int, v) hd = false;
When(Number, double, v) hd = (v == 2.5);
}
return hit && hd;- In
Variant.c:40:
double bd = 0.0;
Match(a) {
When(Number, int, n) ai = n * 2; // n : int
When(Number, double, r) bd = r;
}- In
Variant.c:41:
Match(a) {
When(Number, int, n) ai = n * 2; // n : int
When(Number, double, r) bd = r;
}
Match(b) {- In
Variant.c:44:
}
Match(b) {
When(Number, int, n) ai = n;
When(Number, double, r) bd = r * 2.0; // r : double
}- In
Variant.c:45:
Match(b) {
When(Number, int, n) ai = n;
When(Number, double, r) bd = r * 2.0; // r : double
}
return ai == 20 && bd == 3.0;- In
Variant.c:53:
static Number twice(Number n) {
Match(n) {
When(Number, int, v) return Number_from_int(v * 2);
When(Number, double, v) return Number_from_double(v * 2.0);
}- In
Variant.c:54:
Match(n) {
When(Number, int, v) return Number_from_int(v * 2);
When(Number, double, v) return Number_from_double(v * 2.0);
}
return n;- In
Variant.c:63:
bool ok = false;
Match(r) {
When(Number, int, v) ok = (v == 42);
When(Number, double, v) ok = false;
}- In
Variant.c:64:
Match(r) {
When(Number, int, v) ok = (v == 42);
When(Number, double, v) ok = false;
}
return ok;- In
Variant.c:73:
// Match directly on a function-return rvalue.
Match(twice(Number_from_double(1.5))) {
When(Number, int, v) ok = false;
When(Number, double, v) ok = (v == 3.0);
Otherwise ok = false;- In
Variant.c:74:
Match(twice(Number_from_double(1.5))) {
When(Number, int, v) ok = false;
When(Number, double, v) ok = (v == 3.0);
Otherwise ok = false;
}- In
Variant.c:84:
bool ok = false;
Match(c) {
When(Cell, int, v) ok = false;
When(Cell, char, v) ok = (v == 'Z');
}- In
Variant.c:85:
Match(c) {
When(Cell, int, v) ok = false;
When(Cell, char, v) ok = (v == 'Z');
}
return ok;- In
Variant.c:96:
for (int k = 0; k < 3; k++) {
Match(vals[k]) {
When(Tri, int, v) ok = ok && (v == 7), seen |= 1;
When(Tri, float, v) ok = ok && (v == 1.5f), seen |= 2;
When(Tri, char, v) ok = ok && (v == 'A'), seen |= 4;- In
Variant.c:97:
Match(vals[k]) {
When(Tri, int, v) ok = ok && (v == 7), seen |= 1;
When(Tri, float, v) ok = ok && (v == 1.5f), seen |= 2;
When(Tri, char, v) ok = ok && (v == 'A'), seen |= 4;
}- In
Variant.c:98:
When(Tri, int, v) ok = ok && (v == 7), seen |= 1;
When(Tri, float, v) ok = ok && (v == 1.5f), seen |= 2;
When(Tri, char, v) ok = ok && (v == 'A'), seen |= 4;
}
}- In
Variant.c:108:
int count = 0;
Match(n) {
When(Number, int, v) count++;
When(Number, double, v) count++;
Otherwise count++;- In
Variant.c:109:
Match(n) {
When(Number, int, v) count++;
When(Number, double, v) count++;
Otherwise count++;
}- In
Variant.c:119:
Number n = Number_from_double(9.0); // holds double, only int handled, no Otherwise
Match(n) {
When(Number, int, v)(void) v;
}
return true; // unreachable -- the match aborts first
- In
TypeMatch.c:22:
int tag = -1;
Match(i) {
When(int, v) tag = 0;
When(double, v) tag = 1;
Otherwise tag = 9;- In
TypeMatch.c:23:
Match(i) {
When(int, v) tag = 0;
When(double, v) tag = 1;
Otherwise tag = 9;
}- In
TypeMatch.c:29:
Match(d) {
When(int, v) tag = 0;
When(double, v) tag = 1;
Otherwise tag = 9;- In
TypeMatch.c:30:
Match(d) {
When(int, v) tag = 0;
When(double, v) tag = 1;
Otherwise tag = 9;
}- In
TypeMatch.c:37:
// Unlisted type falls to Otherwise.
Match(p) {
When(int, v) tag = 0;
When(double, v) tag = 1;
Otherwise tag = 9;- In
TypeMatch.c:38:
Match(p) {
When(int, v) tag = 0;
When(double, v) tag = 1;
Otherwise tag = 9;
}- In
TypeMatch.c:51:
double rd = 0.0;
Match(i) {
When(int, n) ri = n * 2;
When(double, x) rd = x;
}- In
TypeMatch.c:52:
Match(i) {
When(int, n) ri = n * 2;
When(double, x) rd = x;
}
Match(d) {- In
TypeMatch.c:55:
}
Match(d) {
When(int, n) ri = n;
When(double, x) rd = x * 2.0;
}- In
TypeMatch.c:56:
Match(d) {
When(int, n) ri = n;
When(double, x) rd = x * 2.0;
}
return ri == 42 && rd == 3.0;- In
TypeMatch.c:66:
// Scrutinee is an rvalue; copied by value, then bound to `n`.
Match(i + 1) {
When(int, n) hit = (n == 5);
When(double, x) hit = false;
}- In
TypeMatch.c:67:
Match(i + 1) {
When(int, n) hit = (n == 5);
When(double, x) hit = false;
}
return hit;- In
TypeMatch.c:76:
int count = 0;
Match(i) {
When(int, v) count++;
When(double, v) count++;
Otherwise count++;- In
TypeMatch.c:77:
Match(i) {
When(int, v) count++;
When(double, v) count++;
Otherwise count++;
}- In
TypeMatch.c:87:
bool hit = false;
Match(p) {
When(int, v) hit = false;
When(double, v) hit = false;
Otherwise hit = true;- In
TypeMatch.c:88:
Match(p) {
When(int, v) hit = false;
When(double, v) hit = false;
Otherwise hit = true;
}- In
TypeMatch.c:100:
double id = 0.0;
Match(i) {
When(int, outer) {
Match(d) {
When(int, x) id = -1.0;- In
TypeMatch.c:102:
When(int, outer) {
Match(d) {
When(int, x) id = -1.0;
When(double, x) id = x; // inner bind : double
}- In
TypeMatch.c:103:
Match(d) {
When(int, x) id = -1.0;
When(double, x) id = x; // inner bind : double
}
oi = outer; // outer bind : int
- In
TypeMatch.c:107:
oi = outer; // outer bind : int
}
When(double, v) oi = -1;
}
return oi == 10 && id == 3.5;- In
TypeMatch.c:122:
Position2D p = {1.0f, 2.0f};
Match(p) {
When(int, v)(void) v; // never matches Position2D, and there is no Otherwise
}
return true; // unreachable -- the match aborts first
Last updated on