Wrap one of two values in a SuperStruct that encompasses both types.
Wrap one of two values in a SuperStruct that encompasses both types.
A Variant which exposes members that are common across all SubTypes.
It's a struct! It's a class! No, its ... SuperStruct!
This bastard child of wrap and variant works like an Algebraic, but exposes members that are common across the source types.
import std.math, std.algorithm; struct Vector { float x, y; } struct Square { float size; Vector topLeft; auto area() { return size * size; } auto center() { return Vector(topLeft.x + size / 2, topLeft.y + size / 2); } auto center(Vector c) { return topLeft = Vector(c.x - size / 2, c.y - size / 2); } } struct Circle { float radius; Vector center; float area() { return radius * radius * PI; } } // Shape may look like a class, but its actually a struct alias Shape = SuperStruct!(Square, Circle); Shape sqr = Square(2, Vector(0,0)); Shape cir = Circle(4, Vector(0,0)); Shape[] shapes = [ sqr, cir ]; // call functions that are shared between the source types: assert(shapes.map!(x => x.area).sum.approxEqual(2 * 2 + 4 * 4 * PI)); // It doesn't matter that `center` is a field of `Circle`, but a property of Square. // They can be used in the same way: cir.center = Vector(4, 2); sqr.center = cir.center; assert(sqr.center == Vector(4,2));
SuperStruct forwards operators too:
import std.range, std.algorithm, std.container; alias Container(T) = SuperStruct!(SList!T, Array!T); Container!int slist = SList!int(); // We can call any members that are common among containers slist.insert([1,2,3,4]); assert(slist.front == 1); // opSlice is supported on all the subtypes, but each returns a different type // Container.opSlice will return a SuperStruct of these types auto slice = slist[]; // [1,2,3,4] assert(slice.front == 1); slice.popFront(); // [2,3,4] assert(slice.front == 2); // as slice is a SuperStruct of range types, it still works as a range slist.insert(slice); // [2,3,4] ~ [1,2,3,4] assert(slist[].equal([2,3,4,1,2,3,4]));
MIT
© 2015, Ryan Roden-Corrent
This module provides a single type, SuperStruct.