SuperStruct is a struct that acts like a class:

---
struct Square {
  float size;
  float area() { return size * size; }
}

struct Circle {
  float r;
  float area() { return r * r * PI; }
}

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

SuperStruct is basically a Variant that exposes the common members of its source
types. You can check it out here:

https://github.com/rcorre/superstruct

I'm not quite sure if this is a good idea (or if it already exists in some form that I haven't seen), but it was fun to work on. There's a lot more info on
the README if you're curious. Let me know what you think!



If you're wondering why I even wanted to do something like this:

I had this Variant that stored either a SpriteBatch, a TextBatch, or a Primitive batch. The thing is, I had a group of them that had to be sorted by depth. Each one of those types _had_ a depth, but it just wasn't accessible through the
variant. Not a big deal, of course:

---
struct Batch {
  Algebraic!(SpriteBatch, TextBatch, PrimitiveBatch) _batch;
  auto depth() {
    return _batch.visit!(
        (SpriteBatch    b) => b.depth,
        (TextBatch      b) => b.depth,
        (PrimitiveBatch b) => b.depth);
  }
}
---

And that worked fine for a bit. Then each of them got a blender too:

---
  auto blender() {
    return _batch.visit!(
        (SpriteBatch    b) => b.blender,
        (TextBatch      b) => b.blender,
        (PrimitiveBatch b) => b.blender);
  }
---

Later, I thought it might be nice if a batch had a global transform.
You can probably guess what that looked like...

I started to think maybe Batch should be a class ... but these were value types, dammit! All I wanted was a little polymorphism! Sure, theres std.typecons.wrap, but that doesn't (yet) work on structs, and besides, it's really a class on the
inside!

Instead of (logically?) just using classes, I decided to go nuts with templates,
and so SuperStruct was born.

Reply via email to