HOWTO migrate a template model to an option-driven model

OK you have a template based model such as:

/// generic test bed for different types of membrane models with one inlet and two outlets
template <class T> class Test : public FlowSheet {
...
template<> std::string Test<Membrane12Rtsc>::type_("Test<Membrane12Rtsc>");
template class Test<Membrane12Rtsc>;
...
nodeFactory.registerType<Test<Membrane12Rtsc> >("Test<Membrane12Rtsc>");

and you want to migrate it to an option-based model. Here is the HOWTO.

Make the class non-template

Remove the template <type T> stuff from the header and the source file.

Make the type_ static member public (required by registerAlias) and set it to the unparameterized name of the class:

std::string Test::type_("Test");

Document the option

In the header file, add something like:

/// generic test bed for different types of membrane models with one inlet and two outlets
/// Options:
///  - typeT the type of the model to test
class Test : virtual public Model, public FlowSheet<ZeroZero> {

Add the String / Integer options

In the header file, add the required String / Integer options:

String typeT; ///< the type of the model to test

and initialize it in the constructor:

DEFINE(typeT, "the type of the model to test")
...
addVariable(typeT);

Parse the option at the beginning of the constructor

typeT.set(retrieveString(defaults, id, persistency, "typeT", "Membrane12Rtsc"));

BTW, here is where we provide the default value.

Use the option where you need it

Change this:

makeVertex("T", "GM", "Gas membrane unit", options);

to this:

makeVertex(typeT.val(), "GM", "Gas membrane unit", options);

Register types

In the driver, register the new types and aliases, replacing this:

nodeFactory.registerType<Test<Membrane12Rtsc> >("Test<Membrane12Rtsc>");
nodeFactory.registerType<Test<Membrane12Cstr> >("Test<Membrane12Cstr>");
nodeFactory.registerType<Test<MembraneMulti12<Membrane12Rtsc> > >("Test<MembraneMulti12<Membrane12Rtsc>>");
nodeFactory.registerType<Test<MembraneMulti12<Membrane12Cstr> > >("Test<MembraneMulti12<Membrane12Cstr>>");

with this:

nodeFactory.register<Test>("Test");
nodeFactory.registerAlias<Test>("Test<Membrane12Rtsc>", "test Membrane12Rtsc", Libpf::User::Defaults()("typeT", "Membrane12Rtsc"));
nodeFactory.registerAlias<Test>("Test<Membrane12Cstr>", "test Membrane12Cstr", Libpf::User::Defaults()("typeT", "Membrane12Cstr"));
nodeFactory.registerAlias("Test", "Test<MembraneMulti12<Membrane12Rtsc>>", "test MembraneMulti12<Membrane12Rtsc>", Libpf::User::Defaults()("typeT", "MembraneMulti12<Membrane12Rtsc>"));
nodeFactory.registerAlias("Test", "Test<MembraneMulti12<Membrane12Cstr>>", "test MembraneMulti12<Membrane12Cstr>", Libpf::User::Defaults()("typeT", "MembraneMulti12<Membrane12Cstr>"));

Compile

The compiler is your best friend ;-)