The OpenD Programming Language

visit

Applies a delegate or function to the given Variant depending on the held type, ensuring that all types are handled by the visiting functions.

import mir.algebraic;
alias visit(visitors...) = visitImpl!(naryFun!visitors, Exhaustive.compileTime, false)

Examples

alias Number = Variant!(int, double);

Number x = 23;
Number y = 1.0;

assert(x.visit!((int v) => true, (float v) => false));
assert(y.visit!((int v) => false, (float v) => true));
alias Number = Nullable!(int, double);

Number z = null; // default
Number x = 23;
Number y = 1.0;

() nothrow {
    assert(x.visit!((int v) => true, (float v) => false));
    assert(y.visit!((int v) => false, (v) => true));
    assert(z.visit!((typeof(null) v) => true, (v) => false));
} ();

auto xx = x.get;
static assert (is(typeof(xx) == Variant!(int, double)));
assert(xx.visit!((int v) => v, (float v) => 0) == 23);
assert(xx.visit!((ref v) => v) == 23);

x = null;
y.nullify;

assert(x.isNull);
assert(y.isNull);
assert(z.isNull);
assert(z == y);

Array primitives propagation

Variant!(long[], double[]) array;
array = new long[3];
array[2] = 100;
assert(array == [0L, 0, 100]);
assert(array.length == 3);
assert(array[2] == 100);
array.length = 4;
assert(array == [0L, 0, 100, 0]);
array = array[2 .. 3];
assert(array.length == 1);
assert(array[0] == 100);
array[0] = 10.Variant!(long, double);
assert(array[0] == 10);

Checks .Algebraic.toString and void Algerbraic.toString requries mir-algorithm package

import mir.conv: to;
enum MIR_ALGORITHM = __traits(compiles, { import mir.format; });

alias visitorHandler = visit!(
    (typeof(null)) => "NULL",
    () => "VOID",
    (ref r) {r += 1;}, // returns void
);

alias secondOrderVisitorHandler = visit!(
    () => "SO VOID", // void => to "RV VOID"
    (str) => str, // string to => it self
);

alias V = Nullable!(void, int);
static assert(is(V == Variant!(typeof(null), void, int)));

V variant;

assert(secondOrderVisitorHandler(visitorHandler(variant)) == "NULL");
assert(variant.toString == "null");

variant = V._void;
assert(variant._is!void);
assert(is(typeof(variant.get!void()) == void));

assert(secondOrderVisitorHandler(visitorHandler(variant)) == "VOID");
assert(variant.toString == "void");

variant = 5;

assert(secondOrderVisitorHandler(visitorHandler(variant)) == "SO VOID");
assert(variant == 6);
assert(variant.toString == (MIR_ALGORITHM ? "6" : "int"));

Meta