It's a class! It's a struct! It's ... SuperStruct!
rcorre via Digitalmars-d-announce
digitalmars-d-announce at puremagic.com
Sun Oct 18 12:00:10 PDT 2015
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.
More information about the Digitalmars-d-announce
mailing list