alias, alias this, opDispatch and Advanced Type Tricks

30.1 alias

alias Integer = int;                          // type alias
alias StrMap = string[string];
alias print = writeln;                        // symbol alias
alias Callback = void delegate(int);
alias Vec = Vector!(float, 3);

30.2 alias this (Subtyping and Implicit Conversion)

struct Meters
{
    double value;
    alias value this;                 // Meters implicitly converts to double
}
Meters m = Meters(5);
double d = m + 2.5;                   // works via alias this

struct LoggedArray(T)
{
    T[] data;
    alias data this;                  // forward everything to the array
    void opOpAssign(string op : "~")(T x) { writeln("append ", x); data ~= x; }
}

30.3 opDispatch (Dynamic-Like Members)

struct Dynamic
{
    string[string] fields;
    auto opDispatch(string name)() { return fields[name]; }               // d.anything
    void opDispatch(string name)(string v) { fields[name] = v; }          // d.anything = v
}
Dynamic d;
d.color = "red";
writeln(d.color);

struct Swizzle
{
    float x, y, z;
    auto opDispatch(string s)() if (s.length > 1)    // v.xy, v.zyx
    {
        float[s.length] r;
        static foreach (i, c; s) r[i] = mixin("this." ~ c);
        return r;
    }
}

30.4 Typedefs and Strong Types

import std.typecons : Typedef, Flag, Yes, No;
alias UserId = Typedef!(int, 0, "UserId");     // distinct type
void open(string path, Flag!"readOnly" ro = No.readOnly) {}
open("x", Yes.readOnly);                       // self-documenting boolean flags

30.5 std.typecons Utilities

Tuple/tuple, Nullable, RefCounted/SafeRefCounted, Unique, scoped, Rebindable, BlackHole/WhiteHole/AutoImplement, wrap/unwrap (structural interface casting), Proxy, Ternary, Typedef, Flag, BitFlags, apply (for Nullable).