Skip to content

Class template reflection

Julien SOYSOUVANH edited this page Oct 26, 2021 · 2 revisions

Index

Reflect a class template

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.

Retrieve a class template

By name

rfk::Class const* c = rfk::getDatabase().getFileLevelClassByName("Array");

rfk::ClassTemplate const* ct = rfk::classTemplateCast(c);

By Id

rfk::ClassTemplate const* ct = rfk::classTemplateCast(rfk::getDatabase().getClassById(classTemplateId));

By static type

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.

Retrieve a class template instantiation

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;

By Name

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);

By Id

rfk::ClassTemplateInstantiation const* inst = rfk::classTemplateInstantiationCast(rfk::getDatabase().getClassById(classTemplateInstantiationId));

By static type

rfk::ClassTemplateInstantiation const* inst = rfk::getArchetype<Array<int, 42u>>();