This is the first "thing" I've made in C++, so writing the code is mostly just an execercise. If you things I'm doing that are just bad, let it rip - I want to know.
I don't think this is the best solution for most problems - but I think it's maybe the right solution for this problem. What do y'all think:
A while back, I was using a C# SDK for a database connection. When you execute a query, it gives you back a row object that basically is a dictionary accessed by the string-name of the fields. row["plant"] gave you the 'plant' attribute at the row cursor. Since the row used a string as a key, there's no way to statically check for issues like typos. This lead to a lot of errors. I remember one typo with a space at the end: row["plant "] took me a whole day to find. Now, I'm (sort-of) making an entity-component-system framework that will have similar use - The UnordredTuple is my solution to this problem.
The UnorderedTuple is a static associative table. It's supposed to feel like a structure or tuple but have better semantics for transforming them. An UnorderedTuple<Name, Age, Address> is guaranteed to have a field for a name, age and address. Name, Age and Address are also the types of the fields name and and address respectively.
Since the field name is also the return type and key for the table, you can't have duplicates. The intention is that if Name is an integer, you can typedef(int, Name). If Name and Age are integers, there will be a collision, but boost::serialization has a STRONG_TYPEDEF macro that creates distinct types.
Unsurprisingly, the UnorderedTuple uses a tuple. But, you can add to, remove from, and permute the elements in the UnorderedTuple. UnorderedTuple<A, B, C> can be used interchangeably with UnorderedTuple<C, A, B>. Casting is free, you could just cast a pointer to it and it would behave identically.