encfs/base/Registry.h
Valient Gough a89752dfe7 reformat with clang-format -style=Google
git-svn-id: http://encfs.googlecode.com/svn/trunk@121 db9cf616-1c43-0410-9cb8-a902689de0d6
2013-10-19 22:35:26 +00:00

95 lines
2.2 KiB
C++

#ifndef REGISTRY_H
#define REGISTRY_H
#include <list>
#include <map>
#include <string>
namespace encfs {
template <typename T>
class Registry {
public:
typedef T *(*FactoryFn)();
struct Data {
FactoryFn constructor;
typename T::Properties properties;
};
void Register(const char *name, FactoryFn fn,
typename T::Properties properties) {
Data d;
d.constructor = fn;
d.properties = properties;
data[name] = d;
}
T *Create(const char *name) {
auto it = data.find(name);
if (it == data.end()) return NULL;
return (*it->second.constructor)();
}
T *CreateForMatch(const std::string &description) {
for (auto &it : data) {
auto name = it.second.properties.toString();
if (!name.compare(0, description.size(), description))
return (*it.second.constructor)();
}
return NULL;
}
std::list<std::string> GetAll() const {
std::list<std::string> result;
for (auto &it : data) {
result.push_back(it.first);
}
return result;
}
const typename T::Properties *GetProperties(const char *name) const {
auto it = data.find(name);
if (it == data.end()) return NULL;
return &(it->second.properties);
}
const typename T::Properties *GetPropertiesForMatch(
const std::string &description) const {
for (auto &it : data) {
auto name = it.second.properties.toString();
if (!name.compare(0, description.size(), description))
return &(it.second.properties);
}
return NULL;
}
private:
std::map<std::string, Data> data;
};
template <typename T, typename BASE>
class Registrar {
public:
Registrar(const char *name) {
BASE::GetRegistry().Register(name, Registrar<T, BASE>::Construct,
T::GetProperties());
}
static BASE *Construct() { return new T(); }
};
#define DECLARE_REGISTERABLE_TYPE(TYPE) static Registry<TYPE> &GetRegistry()
#define DEFINE_REGISTERABLE_TYPE(TYPE) \
Registry<TYPE> &TYPE::GetRegistry() { \
static Registry<TYPE> registry; \
return registry; \
}
#define REGISTER_CLASS(DERIVED, BASE) \
static Registrar<DERIVED, BASE> registrar_##DERIVED##_##BASE(#DERIVED)
} // namespace encfs
#endif // REGISTRY_H