namespace plugin {
    template< class Base >
    class Creator;
}

Defined in <plugin/PluginCreator.hh>. This is PluginCatalog<Base>::mapped_type.

A Creator<Base> holds up to two type-erased factory callables and a flag.

Member types

TypeDefinition
DefaultFactorystd::function<Base*()>
ConfigFactorystd::function<Base*(std::any const&)>

Constructors

Creator();                                                     // (1) empty alias
Creator( DefaultFactory f, bool isAlias = false );             // (2) default only
Creator( DefaultFactory f, ConfigFactory g, bool isAlias = false ); // (3) both
  1. Default-constructs to an empty state with isAlias() == true and no factories. operator()() returns nullptr.
  2. Stores a default factory. This is what REGISTER builds.
  3. Stores both. This is what REGISTER_WITH_CONFIG builds.

Copy and move are defaulted.

operator()

Base* operator()();                    // default factory, or nullptr if none
Base* operator()( std::any const& c ); // config factory
  • operator()() — returns defaultFactory_ ? defaultFactory_() : nullptr.
  • operator()(c)throws std::runtime_error if there is no config factory; otherwise returns configFactory_(c), which may throw std::bad_any_cast if c's type does not match.

The returned raw Base* is owned by the caller — PluginCatalog::create wraps it in std::unique_ptr<Base>.

Observers

bool hasConfigFactory() const;   // a config factory is set
bool isAlias() const;            // registered as an alias

isAlias() feeds PluginCatalog::names(includeAliases).

Building one by hand

plugin::Creator<Shape> c(
    []{ return new Circle; },                                   // default
    []( std::any const& a ){ return new Circle( std::any_cast<Circle::Config const&>(a) ); }, // config
    false );                                                    // not an alias

Shape::catalog().insert( "Circle", c );

The macros generate exactly this. Do it manually only for an in-process plugin or a test.