I just discovered that instead of __FUNCTION__ giving, e.g.:
[font="Courier New"]TypeName<std::pair<std::vector<int>, std::string>>::get[/font]
Some compilers give you:
[font="Courier New"]TypeName<T>::get [with T = std::pair<std::vector<int>, std::string>][/font]
which is still parsable, but it seems the parsing routing is going to be quite different depending on the compiler.
Light weight in what sense? If you're interested in reducing the number of compiler generated structures added to your binary, on MSVC you may also have to disable exception handling because MSVC uses many of the same internal structures to support both.
Lightweight in the sense that I can check that a type is what I expect it to be with a predictable/low amount of storage and a predictable/low amount of work. I also only need to check for exact type matches, not inheritance/interface matches.
The standard RTTI implementation is unpredictable, depending on the compiler's implementation, and MSVC's implementation of type-comparison is extremely slow.
Also, type_info objects are non-copyable, which is usually worked around by wrapping them in a PIMPL class. However, predictable memory access patterns are important for this library (
e.g. for NUMA support), which makes the default RTTI implementation quite expensive/unusable from a memory-access perspective.
e.g. when I invoke [font="Courier New"]operator==[/font] on two [font="Courier New"]type_info[/font]s, which memory locations are read from? If I can't answer/control that, then I can't use them.
I'm using the assumption that many users of a game-oriented library will likely have RTTI and exceptions disabled, so I need to support that.
Most of the game projects I've been involved with professionally have had both exceptions and RTTI disabled, so I would like to design this system in a way where people can use it without being forced to change their compiler settings.