Wrap one of several values in a SuperStruct.
A Variant which exposes members that are common across all SubTypes.
Two disparate structs ... they can't be used interchangeably, right?
import std.math, std.algorithm; struct Square { float size; float area() { return size * size; } } struct Circle { float r; float area() { return r * r * PI; } } // Or can they? alias Shape = SuperStruct!(Square, Circle); // look! polymorphism! Shape sqr = Square(2); Shape cir = Circle(4); 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));
Want to access fields of the underlying types? Not a problem! Are some of them properties? Not a problem!
struct Square { int top, left, width, height; } struct Circle { int radius; int x, y; auto top() { return y - radius; } auto top(int val) { return y = val + radius; } } alias Shape = SuperStruct!(Square, Circle); // if a Shape is a Circle, `top` forwards to Circle's top property Shape someShape = Circle(4, 0, 0); someShape.top = 6; assert(someShape.top == 6); // if a Shape is a Square, `top` forwards to Squares's top field someShape = Square(0, 0, 4, 4); someShape.top = 6; assert(someShape.top == 6); // Square.left is hidden, as Circle has no such member static assert(!is(typeof(someShape.left)));
SuperStruct could be used, for example, for a generic container type:
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.