Skip to content

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)
        bool   hit = false;
        Match(n) {
            When(Number, int, v) hit    = (v == 42);
            When(Number, double, v) hit = false;
        }
        Match(n) {
            When(Number, int, v) hit    = (v == 42);
            When(Number, double, v) hit = false;
        }
        bool   hd = false;
        Match(m) {
            When(Number, int, v) hd    = false;
            When(Number, double, v) hd = (v == 2.5);
        }
        Match(m) {
            When(Number, int, v) hd    = false;
            When(Number, double, v) hd = (v == 2.5);
        }
        return hit && hd;
        double bd = 0.0;
        Match(a) {
            When(Number, int, n) ai    = n * 2; // n : int
            When(Number, double, r) bd = r;
        }
        Match(a) {
            When(Number, int, n) ai    = n * 2; // n : int
            When(Number, double, r) bd = r;
        }
        Match(b) {
        }
        Match(b) {
            When(Number, int, n) ai    = n;
            When(Number, double, r) bd = r * 2.0; // r : double
        }
        Match(b) {
            When(Number, int, n) ai    = n;
            When(Number, double, r) bd = r * 2.0; // r : double
        }
        return ai == 20 && bd == 3.0;
    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);
        }
        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;
        bool   ok = false;
        Match(r) {
            When(Number, int, v) ok    = (v == 42);
            When(Number, double, v) ok = false;
        }
        Match(r) {
            When(Number, int, v) ok    = (v == 42);
            When(Number, double, v) ok = false;
        }
        return ok;
        // 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;
        Match(twice(Number_from_double(1.5))) {
            When(Number, int, v) ok    = false;
            When(Number, double, v) ok = (v == 3.0);
            Otherwise ok               = false;
        }
        bool ok = false;
        Match(c) {
            When(Cell, int, v) ok  = false;
            When(Cell, char, v) ok = (v == 'Z');
        }
        Match(c) {
            When(Cell, int, v) ok  = false;
            When(Cell, char, v) ok = (v == 'Z');
        }
        return ok;
        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;
            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;
            }
                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;
            }
        }
        int    count = 0;
        Match(n) {
            When(Number, int, v) count++;
            When(Number, double, v) count++;
            Otherwise count++;
        Match(n) {
            When(Number, int, v) count++;
            When(Number, double, v) count++;
            Otherwise count++;
        }
        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
        int tag = -1;
        Match(i) {
            When(int, v) tag    = 0;
            When(double, v) tag = 1;
            Otherwise tag       = 9;
        Match(i) {
            When(int, v) tag    = 0;
            When(double, v) tag = 1;
            Otherwise tag       = 9;
        }
    
        Match(d) {
            When(int, v) tag    = 0;
            When(double, v) tag = 1;
            Otherwise tag       = 9;
        Match(d) {
            When(int, v) tag    = 0;
            When(double, v) tag = 1;
            Otherwise tag       = 9;
        }
        // Unlisted type falls to Otherwise.
        Match(p) {
            When(int, v) tag    = 0;
            When(double, v) tag = 1;
            Otherwise tag       = 9;
        Match(p) {
            When(int, v) tag    = 0;
            When(double, v) tag = 1;
            Otherwise tag       = 9;
        }
        double rd = 0.0;
        Match(i) {
            When(int, n) ri    = n * 2;
            When(double, x) rd = x;
        }
        Match(i) {
            When(int, n) ri    = n * 2;
            When(double, x) rd = x;
        }
        Match(d) {
        }
        Match(d) {
            When(int, n) ri    = n;
            When(double, x) rd = x * 2.0;
        }
        Match(d) {
            When(int, n) ri    = n;
            When(double, x) rd = x * 2.0;
        }
        return ri == 42 && rd == 3.0;
        // 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;
        }
        Match(i + 1) {
            When(int, n) hit    = (n == 5);
            When(double, x) hit = false;
        }
        return hit;
        int count = 0;
        Match(i) {
            When(int, v) count++;
            When(double, v) count++;
            Otherwise count++;
        Match(i) {
            When(int, v) count++;
            When(double, v) count++;
            Otherwise count++;
        }
        bool       hit = false;
        Match(p) {
            When(int, v) hit    = false;
            When(double, v) hit = false;
            Otherwise hit       = true;
        Match(p) {
            When(int, v) hit    = false;
            When(double, v) hit = false;
            Otherwise hit       = true;
        }
        double id = 0.0;
        Match(i) {
            When(int, outer) {
                Match(d) {
                    When(int, x) id    = -1.0;
            When(int, outer) {
                Match(d) {
                    When(int, x) id    = -1.0;
                    When(double, x) id = x; // inner bind : double
                }
                Match(d) {
                    When(int, x) id    = -1.0;
                    When(double, x) id = x; // inner bind : double
                }
                oi = outer;                 // outer bind : int
                oi = outer;                 // outer bind : int
            }
            When(double, v) oi = -1;
        }
        return oi == 10 && id == 3.5;
        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