On 9/06/2015 13:16, Anton Bachin wrote:
(As an aside, it was quite a handy data structure. It was mainly intended for string-to-enum conversions but because of the way it was templated it could be abused to do string-to-member-pointer conversions as well, which enabled all sorts of interesting reflection scenarios.)
I am curious to know what this was, it sounds interesting.
It wasn't really all that interesting. It was just a "data table class"
with some helper macros that let you define a static const structure
private to a .cpp file (and initialised at compile time) to contain the
string and value, plus a "lookup class" that was declared in the .h (as
a static global) that was initialised with the address of the table.
All the actual searching was done at runtime by the lookup class, with
the table class basically just POD.
The table was normally declared using some macro helpers, so:
EnumLookup::Table FooStatusTable =
{
ELT_ENTRY(Normal),
ELT_ENTRY(Warning),
ELT_ENTRY(Error),
ELT_TERMINATOR
};
EnumLookup Foo::StatusLookup(&FooStatusTable);
But you could do weirder things with it, such as giving alternate names
(occasionally useful for serialisation upgrade scenarios or alternate
output formats):
EnumLookup::Table Foo::StatusTable =
{
ELT_NAMED_ENTRY(Normal, "Ok"),
ELT_NAMED_ENTRY(Warning, "Warn"),
ELT_ENTRY(Error),
ELT_TERMINATOR
};
And it had support to let you round-trip enum -> string -> enum values
that weren't listed in the table.
Because it was based on a template, you could also use member pointers
as the value to look up, for basic reflection support:
BarPropertyMapping::Table Bar::PropertyTable =
{
{ &Bar::Count, "Count" },
{ &Bar::Min, "Minimum" },
{ &Bar::Max, "Maximum" },
{ 0, NULL }
};
(You could use anything else as the value too, but these two seemed to
be the most useful in practice. This particular case only helped when
there were many members with the same type, of course, but it let them
be accessed "nicer" than just using a runtime map