16 #ifndef ROOT7_RDirectory
17 #define ROOT7_RDirectory
24 #include <type_traits>
25 #include <unordered_map>
30 namespace Experimental {
35 class RDirectoryUnknownKey:
public std::exception {
39 RDirectoryUnknownKey(std::string_view keyName): fKeyName(keyName) {}
40 const char *what() const noexcept final {
return fKeyName.c_str(); }
47 class RDirectoryTypeMismatch:
public std::exception {
51 RDirectoryTypeMismatch(std::string_view keyName): fKeyName(keyName) {}
52 const char *what() const noexcept final {
return fKeyName.c_str(); }
75 using ContentMap_t = std::unordered_map<std::string, Internal::RDirectoryEntry>;
78 ContentMap_t fContent;
81 struct ToContentType {
82 using decaytype =
typename std::decay<T>::type;
84 typename std::enable_if<!std::is_pointer<decaytype>::value && !std::is_member_pointer<decaytype>::value &&
85 !std::is_void<decaytype>::value,
89 using ToContentType_t =
typename ToContentType<T>::type;
97 template <
class T,
class... ARGS>
98 std::shared_ptr<ToContentType_t<T>> Create(std::string_view name, ARGS &&... args)
100 auto ptr = std::make_shared<ToContentType_t<T>>(std::forward<ARGS>(args)...);
107 Internal::RDirectoryEntry Find(std::string_view name)
const
109 auto idx = fContent.find(std::string(name));
110 if (idx == fContent.end())
118 enum class EFindStatus {
133 std::pair<Internal::RDirectoryEntry, EFindStatus> Find(std::string_view name)
const
135 auto idx = fContent.find(std::string(name));
136 if (idx == fContent.end())
137 return {
nullptr, EFindStatus::kKeyNameNotFound};
138 if (idx->second.GetTypeInfo() ==
typeid(ToContentType_t<T>))
139 return {idx->second, EFindStatus::kValidValue};
140 if (idx->second.CastPointer<ToContentType_t<T>>())
141 return {idx->second, EFindStatus::kValidValueBase};
142 return {
nullptr, EFindStatus::kTypeMismatch};
153 std::shared_ptr<ToContentType_t<T>> Get(std::string_view name)
155 const auto &pair = Find<T>(name);
156 const Internal::RDirectoryEntry &entry = pair.first;
157 EFindStatus status = pair.second;
159 case EFindStatus::kValidValue:
return std::static_pointer_cast<ToContentType_t<T>>(entry.GetPointer());
160 case EFindStatus::kValidValueBase:
return entry.CastPointer<ToContentType_t<T>>();
161 case EFindStatus::kTypeMismatch:
163 throw RDirectoryTypeMismatch(name);
164 case EFindStatus::kKeyNameNotFound:
throw RDirectoryUnknownKey(name);
172 void Add(std::string_view name,
const std::shared_ptr<T> &ptr)
174 Internal::RDirectoryEntry entry(ptr);
176 std::string sName(name);
177 auto idx = fContent.find(sName);
178 if (idx != fContent.end()) {
179 R__LOG_HERE(ELogLevel::kWarning,
"CORE") <<
"Replacing object with name \"" << name <<
"\"" << std::endl;
180 idx->second.swap(entry);
182 fContent[sName].swap(entry);
187 bool Remove(std::string_view name)
189 std::string sName(name);
190 auto idx = fContent.find(sName);
191 if (idx != fContent.end()) {
207 static RDirectory &Heap();