mirror of
https://github.com/scylladb/scylladb.git
synced 2026-04-23 01:50:35 +00:00
class_registrator: ensure the static member initialization order
There was a possibility for initialization disorder of static member _classes and its usage in another static class. Defining the _classes inside the static method that is called when it's accessed ensures the proper initialization (aka "standard trick", quoting Avi ;)). Signed-off-by: Vlad Zolotarov <vladz@cloudius-systems.com>
This commit is contained in:
@@ -14,20 +14,22 @@ public:
|
||||
template<typename BaseType, typename... Args>
|
||||
class class_registry {
|
||||
using creator_type = std::function<std::unique_ptr<BaseType>(Args...)>;
|
||||
static std::unordered_map<sstring, creator_type> _classes;
|
||||
public:
|
||||
static void register_class(sstring name, creator_type creator);
|
||||
template<typename T>
|
||||
static void register_class(sstring name);
|
||||
static std::unique_ptr<BaseType> create(const sstring& name, Args...);
|
||||
|
||||
static std::unordered_map<sstring, creator_type>& classes() {
|
||||
static std::unordered_map<sstring, creator_type> _classes;
|
||||
|
||||
return _classes;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename BaseType, typename... Args>
|
||||
std::unordered_map<sstring, typename class_registry<BaseType, Args...>::creator_type> class_registry<BaseType, Args...>::_classes;
|
||||
|
||||
template<typename BaseType, typename... Args>
|
||||
void class_registry<BaseType, Args...>::register_class(sstring name, class_registry<BaseType, Args...>::creator_type creator) {
|
||||
_classes.emplace(name, std::move(creator));
|
||||
classes().emplace(name, std::move(creator));
|
||||
}
|
||||
|
||||
template<typename BaseType, typename... Args>
|
||||
@@ -50,8 +52,8 @@ struct class_registrator {
|
||||
|
||||
template<typename BaseType, typename... Args>
|
||||
std::unique_ptr<BaseType> class_registry<BaseType, Args...>::create(const sstring& name, Args... args) {
|
||||
auto it = _classes.find(name);
|
||||
if (it == _classes.end()) {
|
||||
auto it = classes().find(name);
|
||||
if (it == classes().end()) {
|
||||
throw no_such_class(sstring("unable to find class '") + name + sstring("'"));
|
||||
}
|
||||
return it->second(args...);
|
||||
|
||||
Reference in New Issue
Block a user