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

Defined in <plugin/PluginCatalog.hh>.

One PluginCatalog<Base> exists per plugin hierarchy. It maps a std::string key to a Creator<Base> and is safe to read and mutate concurrently.

Member types

TypeDefinition
key_typestd::string
mapped_typeCreator<Base>
container_typestd::map<key_type, mapped_type, std::less<key_type>>

Member functions

GroupFunctionsLockPage
mutatorsinsert, eraseexclusiveinsert, erase
createcreate(key), create(key, std::any)sharedcreate
observersnames, contains, empty, sizesharednames, contains, size

Copy and move are provided and lock both operands (std::scoped_lock / std::lock with a deferred shared_lock), but a catalog is almost always a singleton reached through CREATECATALOG and never copied in practice.

Thread safety

A mutable std::shared_mutex guards entries_:

  • create, contains, empty, size, names take a shared (read) lock — they run concurrently with each other.
  • insert, erase take an exclusive (write) lock.

Registration (insert) happens during DSO static initialisation, which is single-threaded, so writes rarely contend with anything.

Direct use

You normally go through Plugin<Base>::create, but the catalog is a plain object:

auto& cat = Shape::catalog();           // PluginCatalog<Shape>&

cat.size();                             // how many keys (aliases excluded from names())
cat.contains( "Circle" );
auto up = cat.create( "Circle" );       // std::unique_ptr<Shape>, or nullptr

insert / erase are public but are the registration macros' job — calling them by hand is for tests or a host that builds a plugin in-process without a DSO.