.. _basics_RegisteredClass: Derived class discovery at compile time ======================================= The ``RuntimeSelectionFactory`` class is a template class that allows to register derived classes for creation at runtime via a factory class by its name. This mechanism is similar to OpenFOAM's runtime selection mechanism. The classes are registered at compile time via static member initialization. Additional explanation can be found in the following two posts on Stack OverFlow: `Derived class discovery at compile time `_ and `How to automatically register a class on creation `_ . This approach allows to create a plugin architecture where a derived class can be loaded at runtime. Additionally, it simplifies the runtime selection of a specific class. The derived classes can be created by providing its name, as shown below: .. code-block:: cpp std::unique_ptr derivedClass = baseClass::create("Name of derivedClass", "Additional arguments",...); The ``RuntimeSelectionFactory`` class is a template class that manages the registration of the derived classes and stores the map of the registered classes. The map associates a function with a string that is used to create the derived class. Further details `RuntimeSelectionFactory `_. Usage ^^^^^ The following example shows how to use the ``RuntimeSelectionFactory`` and ``RuntimeSelectionFactory::Register`` to automatically register derived classes. (check ``registerClass.cpp`` for details). The static function ``create`` returns a ``std::unique_ptr`` to its base class and takes an argument list specified inside the template class ``NeoFOAM::Parameters<>``. .. code-block:: cpp template class RuntimeSelectionFactory> : public RegisterDocumentation { static std::unique_ptr create(const std::string& key, Args... args) { keyExistsOrError(key); auto ptr = table().at(key)(std::forward(args)...); return ptr; } }; To register a class, derive from the BaseClass::Register class and pass the derived class as a template argument. The derived class must implement the static functions ``name``, ``doc``, and ``schema``. .. code-block:: cpp class DerivedClass : public BaseClass::Register { public: DerivedClass() {} static std::string name() { return "DerivedClass"; } static std::string doc() { return "DerivedClass documentation"; } static std::string schema() { return "DerivedClass schema"; } }; After the classes have been defined, the ``create`` function can be used to instantiate the derived classes based on the name provided. .. code-block:: cpp std::unique_ptr testDerived = BaseClass::create("DerivedClass"); All base classes are also registered in the ``NeoFOAM::BaseClassDocumentation`` map and the documentation and the schema retrieved as followed: .. code-block:: cpp std::string baseClassName = "BaseClass"; std::string derivedClass = "DerivedClass"; NeoFOAM::BaseClassDocumentation::doc(baseClassName, derivedClass) NeoFOAM::BaseClassDocumentation::schema(baseClassName, derivedClass) This mechanism should simplify the creation of tooling around NeoFOAM