-
Notifications
You must be signed in to change notification settings - Fork 21
Class template reflection
When a class template is reflected, the class template itself as well as all its instantiations within the program are actually reflected.
template <typename T, typename U>
class CLASS() ExampleClassTemplate
{
ExampleClassTemplate_GENERATED
};
Reflecting a class template is slightly different than reflecting a simple class: if the template parameters include different template parameter types (at least 2 of type template parameters, non-type template parameters and template template parameters), the user must manually define the base getArchetype overload for that template configuration in the rfk namespace BEFORE declaring the template class.
namespace rfk
{
template <template <typename, std::size_t> typename>
rfk::Archetype const* getArchetype() noexcept { return nullptr; }
}
//T is a type template parameter and Size is a non-type template parameter
//Must define the getArchetype beforehand
template <typename T, std::size_t Size>
class CLASS() Array
{
Array_GENERATED
};
Note: The auto keyword for non-type template parameters is not supported and will lead to compilation errors.
rfk::Class const* c = rfk::getDatabase().getFileLevelClassByName("Array");
rfk::ClassTemplate const* ct = rfk::classTemplateCast(c);
rfk::ClassTemplate const* ct = rfk::classTemplateCast(rfk::getDatabase().getClassById(classTemplateId));
rfk::ClassTemplate const* ct = rfk::classTemplateCast(rfk::getArchetype<Array>());
Note: Variables and methods of class templates do not exist (they have no address) until they are instantiated, so the rfk::ClassTemplate do not reference them.
All instantiations of a reflected class template within the program are automatically reflected, whether the instantiation happened in a header or a source file. Say we have this statement written somewhere:
Array<int, 42u> array;
rfk::ClassTemplate const* ct = rfk::classTemplateCast(rfk::getDatabase().getFileLevelClassByName("Array"));
//Build a list of template arguments
rfk::TypeTemplateArgument arg1(rfk::getDatabase().getFundamentalArchetypeByName("int"));
std::size_t arg2Value = 42u;
rfk::NonTypeTemplateArgument arg2(arg2Value);
rfk::TemplateArgument const* templateArgs[] = { &arg1, &arg2 };
//Find the instantiation
rfk::ClassTemplateInstantiation const* inst = ct->getTemplateInstantiation(templateArgs);
rfk::ClassTemplateInstantiation const* inst = rfk::classTemplateInstantiationCast(rfk::getDatabase().getClassById(classTemplateInstantiationId));
rfk::ClassTemplateInstantiation const* inst = rfk::getArchetype<Array<int, 42u>>();