Hello all. In my application I came across a desire to store an ordered array of handles that could point to one of several different objects, and it seems like the tool I want for that is SumType.
I started with something like (simplified of course):
class Foo {}
class Bar {}
alias Item = SumType!(Foo, Bar);
And then I could do:
Item[] items;
items ~= Item(new Foo());
But, I found I wanted while iterating through my items to sometimes only operate on those of a certain type. Rather than having to call SumType.match! and specify patterns to test if they had the type I wanted, I wanted a more concise syntax, and also the ability to just directly extract the handle, or null if the item kind wasn't what I was asking for.
So I came up with:
struct Item
{
SumType!(Foo, Bar) item;
alias item this;
this(T)(T v)
{
item = v;
}
bool is_a(T)()
{
return item.match!(
(T v) => true,
_ => false);
}
T get(T)()
{
return item.match!(
(T v) => v,
_ => null);
}
}
This seems to give me the syntax that I want, so I can do things like:
foreach (item; items)
{
if (Foo foo = item.get!Foo)
{
/* do something with foo */
}
}
I realized that I could stick with defining Item
as an alias
and use UFCS to define global is_a
or get
, but I prefer having is_a
and get
scoped to the Item
struct instead of globally defined.
Questions:
- Would there be something more appropriate than SumType for what I'm trying to do?
- Am I missing anything with a short syntax like my is_a() or get() that already exists in SumType so I wouldn't need to define my own struct to wrap it?
- If not, could something like these two be added to SumType for more direct access?
- Any other general improvements to my solution?