Closes #7
This commit is contained in:
1 parent
8d82b13dad
commit
b91cf4aae5
21 files changed
+1165
-1146
No files matched your search
+33
-33
@@ -7,7 +7,7 @@
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
#include <unordered_map>
|
||||
#include <utility> // std::move
|
||||
#include <utility>// std::move
|
||||
|
||||
/**
|
||||
* @brief Registry-based factory for creating objects by runtime identifier.
|
||||
@@ -55,15 +55,15 @@
|
||||
* (void)b->get();
|
||||
* @endcode
|
||||
*/
|
||||
template <class ClassId, class BaseClass, class... Args>
|
||||
template<class ClassId, class BaseClass, class... Args>
|
||||
class TypeFactory {
|
||||
public:
|
||||
using BasePtr = std::shared_ptr<BaseClass>;
|
||||
using CreatorFn = BasePtr (*)(Args...);
|
||||
using BasePtr = std::shared_ptr<BaseClass>;
|
||||
using CreatorFn = BasePtr (*)(Args...);
|
||||
|
||||
TypeFactory() = default;
|
||||
TypeFactory() = default;
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Registers a Derived type under the given id.
|
||||
*
|
||||
* Requirements (checked at compile-time):
|
||||
@@ -72,47 +72,47 @@ public:
|
||||
*
|
||||
* Re-registering the same id overwrites the previous entry ("last wins").
|
||||
*/
|
||||
template <class Derived>
|
||||
void registerType(const ClassId& id) {
|
||||
static_assert(std::is_base_of_v<BaseClass, Derived>,
|
||||
"Derived must inherit from BaseClass");
|
||||
static_assert(std::is_constructible_v<Derived, Args...>,
|
||||
"Derived must be constructible from Args...");
|
||||
template<class Derived>
|
||||
void registerType(const ClassId &id) {
|
||||
static_assert(std::is_base_of_v<BaseClass, Derived>,
|
||||
"Derived must inherit from BaseClass");
|
||||
static_assert(std::is_constructible_v<Derived, Args...>,
|
||||
"Derived must be constructible from Args...");
|
||||
|
||||
classes.insert_or_assign(id, &instantiate<Derived>);
|
||||
}
|
||||
classes.insert_or_assign(id, &instantiate<Derived>);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Returns creator function for the given id.
|
||||
* @throws std::out_of_range when id is not registered.
|
||||
*/
|
||||
[[nodiscard]] CreatorFn creator(const ClassId& id) const {
|
||||
return classes.at(id);
|
||||
}
|
||||
[[nodiscard]] CreatorFn creator(const ClassId &id) const {
|
||||
return classes.at(id);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Creates an instance for the given id using provided arguments.
|
||||
* @throws std::out_of_range when id is not registered.
|
||||
*/
|
||||
[[nodiscard]] BasePtr create(const ClassId& id, Args... args) const {
|
||||
return creator(id)(std::move(args)...);
|
||||
}
|
||||
[[nodiscard]] BasePtr create(const ClassId &id, Args... args) const {
|
||||
return creator(id)(std::move(args)...);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Checks whether an id is registered.
|
||||
*/
|
||||
[[nodiscard]] bool contains(const ClassId& id) const {
|
||||
return classes.find(id) != classes.end();
|
||||
}
|
||||
[[nodiscard]] bool contains(const ClassId &id) const {
|
||||
return classes.find(id) != classes.end();
|
||||
}
|
||||
|
||||
protected:
|
||||
// Protected by design: derived factories may extend/inspect the registry.
|
||||
std::unordered_map<ClassId, CreatorFn> classes;
|
||||
// Protected by design: derived factories may extend/inspect the registry.
|
||||
std::unordered_map<ClassId, CreatorFn> classes;
|
||||
|
||||
private:
|
||||
template <class Derived>
|
||||
static BasePtr instantiate(Args... args) {
|
||||
return std::make_shared<Derived>(std::move(args)...);
|
||||
}
|
||||
template<class Derived>
|
||||
static BasePtr instantiate(Args... args) {
|
||||
return std::make_shared<Derived>(std::move(args)...);
|
||||
}
|
||||
};
|
||||
#endif // TYPEFACTORY_H
|
||||
#endif// TYPEFACTORY_H
|
||||
Reference in new issue
Block a user