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:
Vlad Zolotarov
2015-06-01 11:31:49 +03:00
parent 73278798a9
commit f1aa0df4c3

View File

@@ -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...);