We've seen how the is
expression lets us match simple types, and how Phobos used it to extract function details previously. What about more complex types such as arrays or template instantiations? How do we break them down into details?
Let's define a concrete goal to accomplish. We'll make an arithmetic wrapper that should follow the same type conversion rules as built-in types, but only work with other members of the same wrapped family.
Such a type might be useful when creating a scientific units library, for example, where you want to use the type system to decorate the otherwise plain numbers with maximum flexibility. The following is an example of a complex type:
struct Number(T) if(__traits(isArithmetic, T)) { T value; this(T t) { value = t; } this(N)(N n) if(isSomeNumber!N) { this.value = cast(T) n.value; } } // convenience constructor auto number(T)(T t) { return Number!T(t); } template isSomeNumber(N) { // what's the...