24#include <unordered_map>
44 using runtime_error::runtime_error;
61 explicit IdMapping(std::shared_ptr<json> documentRoot,
const std::optional<ErrorHandler>& errorHandler = std::nullopt)
62 : m_root(documentRoot), m_errorHandler(errorHandler) {}
73 template <
typename T,
typename IdType>
74 T
get(
const IdType&
id,
const std::optional<Base>& errorLocation = std::nullopt)
const
76 const auto& map = getMap<T>();
77 auto it = map.find(
id);
78 if (it == map.end()) {
79 mapping_error err(
"ID " + formatKeyString(
id) +
" not found in ID mapping");
81 m_errorHandler.value()(err.what(), errorLocation.value_or(
Document(m_root)));
85 if (it->second.typeName != T::JsonSchemaTypeName) {
86 mapping_error err(
"ID " + formatKeyString(
id) +
" has type \"" + std::string(it->second.typeName)
87 +
"\", but the requested type is \"" + std::string(T::JsonSchemaTypeName) +
"\".");
89 m_errorHandler.value()(err.what(), errorLocation.value_or(
Document(m_root)));
93 return T(m_root, it->second.location);
97 template <
typename T,
typename IdType>
100 const auto& map = getMap<T>();
101 return map.find(
id) != map.end();
110 template <
typename T,
typename IdType>
111 void add(
const IdType&
id,
const T& value)
113 auto result = getMap<T>().emplace(
id, MappedLocation{ value.pointer(), T::JsonSchemaTypeName });
114 if (!result.second) {
115 mapping_error err(
"ID " + formatKeyString(
id) +
" already exists for type \"" + std::string(result.first->second.typeName)
116 +
"\" at " + result.first->second.location.to_string());
117 if (m_errorHandler) {
118 m_errorHandler.value()(err.what(), value);
126 std::shared_ptr<json> m_root;
127 std::optional<ErrorHandler> m_errorHandler;
129 using MappedLocation =
struct
132 std::string_view typeName;
134 std::unordered_map<std::string, MappedLocation> m_objectMap;
135 std::unordered_map<int, MappedLocation> m_globalMeasures;
137 template <
typename T,
typename Self>
138 static auto& getMapImpl(Self& self) {
139 if constexpr (std::is_same_v<T, mnx::global::Measure>) {
140 return self.m_globalMeasures;
142 return self.m_objectMap;
146 template <
typename T>
147 const auto& getMap()
const
148 {
return getMapImpl<T>(*
this); }
150 template <
typename T>
152 {
return getMapImpl<T>(*
this); }
154 template <
typename KeyType>
155 static std::string formatKeyString(
const KeyType& key) {
156 if constexpr (std::is_same_v<KeyType, std::string>) {
157 return "\"" + key +
"\"";
159 std::ostringstream oss;
Represents an MNX document and provides methods for loading and saving.
Definition Document.h:87
Provides type-safe ID-based lookup for elements in an MNX document.
Definition IdMapping.h:54
void add(const IdType &id, const T &value)
Adds a key to the mapping. If there is no error handler, it throws mapping_error if there is a duplic...
Definition IdMapping.h:111
IdMapping(std::shared_ptr< json > documentRoot, const std::optional< ErrorHandler > &errorHandler=std::nullopt)
Constructs the index for a given document.
Definition IdMapping.h:61
T get(const IdType &id, const std::optional< Base > &errorLocation=std::nullopt) const
Looks up an object by string ID.
Definition IdMapping.h:74
bool exists(const IdType &id) const
Returns whether the specified ID exists in the mapping.
Definition IdMapping.h:98
base class for mapping error exceptions
Definition IdMapping.h:43
json::json_pointer json_pointer
JSON pointer class for MNX.
Definition BaseTypes.h:198