Module superstruct

This module provides a single type, SuperStruct.

Example

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));

Example

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]));

Functions

Name Description
pick Wrap one of two values in a SuperStruct that encompasses both types.
pickAmong Wrap one of two values in a SuperStruct that encompasses both types.

Structs

Name Description
SuperStruct A Variant which exposes members that are common across all SubTypes.

Authors

Ryan Roden-Corrent (rcorre)

Copyright

© 2015, Ryan Roden-Corrent

License

MIT