Members of plugin::PluginCatalog<Base>.
void insert( key_type const& key, mapped_type const& creator );
void erase ( key_type const& key );
insert
Stores creator under key, overwriting any existing entry (it is entries_[key] = creator). Takes the exclusive lock.
creator is a Creator<Base> — a wrapper around one or two factory callables, plus an isAlias flag.
erase
Removes the entry for key if present; a no-op if not. Takes the exclusive lock.
Who calls these
The PluginRegisterer templates:
- constructor →
Base::catalog().insert( key, Creator<Base>( ... ) ) - destructor →
Base::catalog().erase( key )
So in normal use you never call insert / erase directly — you write REGISTER(Circle, Shape) and the DSO's load/unload drives them.
Calling them directly
Valid for a host that constructs a plugin type in-process (no DSO) or for tests:
Shape::catalog().insert(
"InlineTriangle",
plugin::Creator<Shape>( []{ return new Triangle; } ) );
auto t = Shape::create( "InlineTriangle" );
Shape::catalog().erase( "InlineTriangle" );
The lambda must return Base* (owned by the caller — create wraps it in unique_ptr). For a config factory, pass a second std::function<Base*(std::any const&)> to the Creator constructor.
Notes
insertoverwrites silently. Two plugins registering the same key means the last DSO loaded wins; there is no diagnostic. Choose keys carefully, or useREGISTERBYNAMEwith a namespaced key.eraseduringcreatefrom another thread is safe (the locks serialise them) but semantically racy — don't unregister a plugin that might be in the middle of being instantiated.

