]> git.tdb.fi Git - libs/datafile.git/blob - source/loadabletyperegistry.h
Cosmetic changes
[libs/datafile.git] / source / loadabletyperegistry.h
1 #ifndef MSP_DATAFILE_LOADABLETYPEREGISTRY_H_
2 #define MSP_DATAFILE_LOADABLETYPEREGISTRY_H_
3
4 #include <map>
5 #include <string>
6 #include <vector>
7 #include <msp/core/maputils.h>
8 #include <msp/core/noncopyable.h>
9
10 namespace Msp {
11 namespace DataFile {
12
13 /**
14 Associates types with keywords for adding to a Loader.  The target Loader class
15 must be given as a template parameter, as well as a helper template struct to
16 handle the actual adding of keywords.
17 */
18 template<typename L, template<typename> class A>
19 class LoadableTypeRegistry: public NonCopyable
20 {
21 private:
22         class TypeBase
23         {
24         protected:
25                 std::string keyword;
26
27                 TypeBase(const std::string &kw): keyword(kw) { }
28         public:
29                 virtual ~TypeBase() { }
30
31                 virtual void add(L &) const = 0;
32         };
33
34         template<typename T>
35         class RegisteredType: public TypeBase
36         {
37         public:
38                 RegisteredType(const std::string &kw): TypeBase(kw) { }
39
40                 virtual void add(L &ldr) const { A<T>::add(ldr, this->keyword); }
41         };
42
43         typedef std::map<std::string, TypeBase *> TypeMap;
44
45         TypeMap types;
46
47 public:
48         ~LoadableTypeRegistry();
49
50         template<typename T>
51         void register_type(const std::string &);
52
53         void add_all(L &) const;
54 };
55
56 template<typename L, template<typename> class A>
57 LoadableTypeRegistry<L, A>::~LoadableTypeRegistry()
58 {
59         for(typename TypeMap::iterator i=types.begin(); i!=types.end(); ++i)
60                 delete i->second;
61 }
62
63 template<typename L, template<typename> class A>
64 template<typename T>
65 void LoadableTypeRegistry<L, A>::register_type(const std::string &kw)
66 {
67         if(types.count(kw))
68                 throw key_error(kw);
69
70         types[kw] = new RegisteredType<T>(kw);
71 }
72
73 template<typename L, template<typename> class A>
74 void LoadableTypeRegistry<L, A>::add_all(L &ldr) const
75 {
76         for(typename TypeMap::const_iterator i=types.begin(); i!=types.end(); ++i)
77                 i->second->add(ldr);
78 }
79
80 } // namespace DataFile
81 } // namespace Msp
82
83 #endif