ECSTASY
All in the name
Loading...
Searching...
No Matches
TypeRegistry.hpp
Go to the documentation of this file.
1
11
12#ifndef ECSTASY_RTTI_TYPEREGISTRY_HPP_
13#define ECSTASY_RTTI_TYPEREGISTRY_HPP_
14
15#include <algorithm>
16#include <functional>
17#include <optional>
18
19#include "Type.hpp"
21
22#define CONCAT_IMPL(x, y) x##y
23#define CONCAT(x, y) CONCAT_IMPL(x, y)
24
31#define REGISTER_TYPE(TYPE) \
32 static bool CONCAT(registered_, __COUNTER__) = \
33 reinterpret_cast<bool &>(ecstasy::rtti::TypeRegistry::getInstance().registerType<TYPE>(#TYPE));
34
41#define REGISTER_TYPES(TYPE, ...) FOR_EACH(REGISTER_TYPE, TYPE, __VA_ARGS__)
42
43namespace ecstasy::rtti
44{
45
55 public:
60
69 [[nodiscard]] static TypeRegistry &getInstance() noexcept;
70
83 template <typename T>
84 AType &registerType(std::string_view name)
85 {
86 size_t hash = std::hash<std::string_view>{}(name);
87 OptionalATypeReference type = find(hash);
88
89 if (type.has_value())
90 return type.value();
91 else
92 return *_types.emplace(hash, std::make_unique<Type<T>>(name)).first->second;
93 }
94
107 template <is_comparable_with_atype T>
108 [[nodiscard]] bool has(const T &target) const noexcept
109 {
110 return find(target).has_value();
111 }
112
123 [[nodiscard]] bool has(size_t name_hash) const noexcept;
124
135 template <typename T>
136 [[nodiscard]] bool has() const noexcept
137 {
138 return has<std::type_info>(typeid(T));
139 }
140
151 [[nodiscard]] OptionalATypeReference findIf(const Predicate &p) const noexcept;
152
165 [[nodiscard]] AType &getIf(const Predicate &p) const;
166
181 template <is_comparable_with_atype T>
182 [[nodiscard]] OptionalATypeReference find(const T &target) const noexcept
183 {
184 auto result = std::find_if(_types.begin(), _types.end(), [&target](const auto &pair) {
185 return *pair.second == target;
186 });
187
188 if (result == _types.end())
189 return std::nullopt;
190 return std::ref(*result->second);
191 }
192
203 [[nodiscard]] OptionalATypeReference find(std::size_t name_hash) const noexcept;
204
215 template <typename T>
216 [[nodiscard]] OptionalATypeReference find() const noexcept
217 {
218 return find<std::type_info>(typeid(T));
219 }
220
235 template <is_comparable_with_atype T>
236 [[nodiscard]] AType &get(const T &target) const
237 {
238 auto result = find(target);
239
240 if (result.has_value())
241 return result.value();
242 throw std::out_of_range("Type not found.");
243 }
244
257 [[nodiscard]] AType &get(std::size_t name_hash) const;
258
271 template <typename T>
272 [[nodiscard]] AType &get() const
273 {
274 return get<std::type_info>(typeid(T));
275 }
276
277 private:
280
286 TypeRegistry() noexcept = default;
287
293 ~TypeRegistry() noexcept = default;
294 };
295
296} // namespace ecstasy::rtti
297
298#endif /* !ECSTASY_RTTI_TYPEREGISTRY_HPP_ */
File containing the Type class (AType implementation) for cross-platform type information.
Type erased interface for cross-platform type information.
Definition AType.hpp:46
Type erased interface for cross-platform type information.
Definition Type.hpp:35
Type registry class to store types in cross-platform way.
static TypeRegistry & getInstance() noexcept
Get the Instance object.
OptionalATypeReference find(const T &target) const noexcept
Search for a registered type.
AType & get(const T &target) const
Get a reference to the AType instance matching the target.
bool has(size_t name_hash) const noexcept
Check if a type is registered from its hash.
std::unordered_map< std::size_t, std::unique_ptr< AType > > _types
Map of types indexed by their (cross-platform) hash code.
OptionalATypeReference find() const noexcept
Search for a registered type.
std::optional< std::reference_wrapper< AType > > OptionalATypeReference
Alias to an optional reference to a type (to be less verbose).
std::function< bool(const std::pair< const std::size_t, std::unique_ptr< AType > > &)> Predicate
Predicate type for custom type search.
bool has() const noexcept
Check if a type is registered.
TypeRegistry() noexcept=default
Construct a new Type Registry instance.
AType & getIf(const Predicate &p) const
Get a reference to the AType instance matching the predicate.
OptionalATypeReference findIf(const Predicate &p) const noexcept
Calls std::find_if on the types map using the given predicate.
AType & get() const
Get a reference to the AType instance matching the target.
AType & registerType(std::string_view name)
Register a type in the registry.
bool has(const T &target) const noexcept
Check if a type is registered.
T find_if(T... args)
T make_unique(T... args)
Namespace regrouping the cross platform rtti symbols.
Definition AType.cpp:15
T has_value(T... args)
T ref(T... args)
T value(T... args)