From: Mikko Rasa Date: Wed, 12 Jun 2019 10:13:22 +0000 (+0300) Subject: Add a utility for registering types for loading X-Git-Url: http://git.tdb.fi/?a=commitdiff_plain;h=676ba621244ea35b69903a7e8aa45637b4bf8648;p=libs%2Fdatafile.git Add a utility for registering types for loading Somewhat ironically Collection can't use this because it has much more complex requirements. --- diff --git a/source/loadabletyperegistry.h b/source/loadabletyperegistry.h new file mode 100644 index 0000000..ace98cb --- /dev/null +++ b/source/loadabletyperegistry.h @@ -0,0 +1,83 @@ +#ifndef MSP_DATAFILE_LOADABLETYPEREGISTRY_H_ +#define MSP_DATAFILE_LOADABLETYPEREGISTRY_H_ + +#include +#include +#include +#include +#include + +namespace Msp { +namespace DataFile { + +/** +Associates types with keywords for adding to a Loader. The target Loader class +must be given as a template parameter, as well as a helper template struct to +handle the actual adding of keywords. +*/ +template class A> +class LoadableTypeRegistry: public NonCopyable +{ +private: + class TypeBase + { + protected: + std::string keyword; + + TypeBase(const std::string &kw): keyword(kw) { } + public: + virtual ~TypeBase() { } + + virtual void add(L &) const = 0; + }; + + template + class RegisteredType: public TypeBase + { + public: + RegisteredType(const std::string &kw): TypeBase(kw) { } + + virtual void add(L &ldr) const { A::add(ldr, this->keyword); } + }; + + typedef std::map TypeMap; + + TypeMap types; + +public: + ~LoadableTypeRegistry(); + + template + void register_type(const std::string &); + + void add_all(L &) const; +}; + +template class A> +LoadableTypeRegistry::~LoadableTypeRegistry() +{ + for(typename TypeMap::iterator i=types.begin(); i!=types.end(); ++i) + delete i->second; +} + +template class A> +template +void LoadableTypeRegistry::register_type(const std::string &kw) +{ + if(types.count(kw)) + throw key_error(kw); + + types[kw] = new RegisteredType(kw); +} + +template class A> +void LoadableTypeRegistry::add_all(L &ldr) const +{ + for(typename TypeMap::const_iterator i=types.begin(); i!=types.end(); ++i) + i->second->add(ldr); +} + +} // namespace DataFile +} // namespace Msp + +#endif