registries: make registration dynamic

Rather than having to manually hook code for registries, add a small
registration function to the registry header and use this registration
results throughout the registry interactions.

Tested:

Confirmed registries have same behavior.

```
$ curl -s -k https://localhost:18080/redfish/v1/Registries/ | jq '.Members | map(."@odata.id")'
[
  "/redfish/v1/Registries/Base",
  "/redfish/v1/Registries/HeartbeatEvent",
  "/redfish/v1/Registries/OpenBMC",
  "/redfish/v1/Registries/ResourceEvent",
  "/redfish/v1/Registries/TaskEvent",
  "/redfish/v1/Registries/Telemetry"
]
```

```
$ curl -s -k https://localhost:18080/redfish/v1/Registries/TaskEvent/TaskEvent | jq ".Messages | keys"
[
  "TaskAborted",
  "TaskCancelled",
  "TaskCompletedOK",
  "TaskCompletedWarning",
  "TaskPaused",
  "TaskProgressChanged",
  "TaskRemoved",
  "TaskResumed",
  "TaskStarted"
]
```

Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
Change-Id: Iaa355420736a2587d9da4e995208d579443ca9b8
diff --git a/redfish-core/include/registries.hpp b/redfish-core/include/registries.hpp
index d379147..f7a8df3 100644
--- a/redfish-core/include/registries.hpp
+++ b/redfish-core/include/registries.hpp
@@ -11,6 +11,9 @@
 #include <charconv>
 #include <cstddef>
 #include <format>
+#include <functional>
+#include <map>
+#include <optional>
 #include <span>
 #include <string>
 #include <string_view>
@@ -43,6 +46,30 @@
     const char* resolution;
 };
 using MessageEntry = std::pair<const char*, const Message>;
+using MessageEntries = std::span<const MessageEntry>;
+
+struct RegistryEntry
+{
+    const Header& header;
+    const char* url;
+    MessageEntries entries;
+};
+using RegistryEntryRef = std::reference_wrapper<RegistryEntry>;
+
+auto allRegistries() -> std::map<std::string, RegistryEntry>&;
+
+auto getRegistryFromPrefix(const std::string& registryName)
+    -> std::optional<RegistryEntryRef>;
+
+auto getRegistryMessagesFromPrefix(const std::string& registryName)
+    -> MessageEntries;
+
+template <typename T>
+void registerRegistry()
+{
+    allRegistries().emplace(T::header.registryPrefix,
+                            RegistryEntry{T::header, T::url, T::registry});
+}
 
 inline std::string fillMessageArgs(
     const std::span<const std::string_view> messageArgs, std::string_view msg)