// This source code is released into the public domain. export module nihil.cli:registry; import nihil.std; namespace nihil { export struct command; /////////////////////////////////////////////////////////////////////// // Command registry storage. This is where command::command() registers // itself when the global command objects are constructed at startup. // // Because we sometimes create stub commands dynamically, the registry // storage is a list of shared_ptr. The "real" commands (which // refer to global objects) will be created with a null deleter so they // are never deleted. This allows real and stub commands to mix in the // same command_tree. // Get the current registry. auto get_registry() -> std::vector> & { static auto commands = std::vector>(); return commands; } // Register a new command. auto register_command(command *cmd) noexcept -> void { auto constexpr null_deleter = [] (command const *) -> void {}; get_registry().emplace_back(cmd, null_deleter); } // Unregister a command. This is not very efficient, but it shouldn't usually be called // except during testing. auto unregister_command(command *cmd) noexcept -> void { auto ®istry = get_registry(); auto it = std::ranges::find_if(registry, [=] (auto c) -> bool { return c.get() == cmd; }); if (it != std::ranges::end(registry)) registry.erase(it); } } // namespace nihil