This commit is contained in:
deeaitch committed 2026-10-05 18:37:20 -04:00
1 parent 8d82b13dad
commit b91cf4aae5
21 files changed
+1165 -1146

No files matched your search

+33 -33
View File
@@ -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