]> AND Private Git Repository - loba.git/blob - named_object_list.h
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
Replace NULL with nullptr.
[loba.git] / named_object_list.h
1 #ifndef NAMED_OBJECT_LIST_H
2 #define NAMED_OBJECT_LIST_H
3
4 #include <map>
5 #include <string>
6
7 // Define an associative container that maps a name with a class and a
8 // description.  All classes must be derived from a same base class.
9 //
10 // We can then use the name to create an object of the associated
11 // class, and to retrieve a pointer to this object.
12 //
13 // Furthermore, it is possible to iterate over the elements to get
14 // their name and their description.
15
16 // I am too lazy to comment the code, which should be obvious...
17
18 //===== arity 0 =====
19
20 template <typename Base>
21 class named_object_list {
22 protected:
23     struct creator_base {
24         std::string description;
25         creator_base(const std::string& descr): description(descr) { }
26         creator_base(const char* descr): description(descr) { }
27         virtual ~creator_base() { }
28         virtual Base* operator()() const = 0;
29     };
30
31     template <typename Derived>
32     struct creator: public creator_base {
33         creator(const std::string& descr): creator_base(descr) { }
34         creator(const char* descr): creator_base(descr) { }
35         Base* operator()() const { return new Derived(); }
36     };
37
38     typedef std::map<std::string, const creator_base*> map_type;
39
40     map_type assoc;
41
42     void insert(const std::string& name, const creator_base* creat)
43     {
44         assoc.insert(std::make_pair(name, creat));
45     }
46
47     void insert(const char* name, const creator_base* creat)
48     {
49         assoc.insert(std::make_pair(std::string(name), creat));
50     }
51
52 public:
53     typedef typename map_type::const_iterator iterator;
54
55     named_object_list() { };
56     ~named_object_list()
57     {
58         for (iterator it = begin(); it != end(); ++it)
59             delete it->second;
60     }
61
62     Base* new_instance(const std::string& name) const
63     {
64         iterator it = assoc.find(name);
65         if (it != assoc.end())
66             return (*it->second)();
67         else
68             return nullptr;
69     }
70
71     const std::string& get_name(iterator& it) const { return it->first; }
72     const std::string& get_descr(iterator& it) const
73     { return it->second->description; }
74
75     bool exists(const std::string& name) const
76     { return assoc.find(name) != assoc.end(); }
77     iterator begin() const       { return assoc.begin(); }
78     iterator end() const         { return assoc.end();   }
79
80 };
81
82 //===== arity 2 =====
83
84 template <typename Base, typename Arg1, typename Arg2>
85 class named_object_list2 {
86 protected:
87     struct creator_base {
88         std::string description;
89         creator_base(const std::string& descr): description(descr) { }
90         creator_base(const char* descr): description(descr) { }
91         virtual ~creator_base() { }
92         virtual Base* operator()(Arg1, Arg2) const = 0;
93     };
94
95     template <typename Derived>
96     struct creator: public creator_base {
97         creator(const std::string& descr): creator_base(descr) { }
98         creator(const char* descr): creator_base(descr) { }
99         Base* operator()(Arg1 arg1, Arg2 arg2) const
100         { return new Derived(arg1, arg2); }
101     };
102
103     typedef std::map<std::string, const creator_base*> map_type;
104
105     map_type assoc;
106
107     void insert(const std::string& name, const creator_base* creat)
108     {
109         assoc.insert(std::make_pair(name, creat));
110     }
111
112     void insert(const char* name, const creator_base* creat)
113     {
114         assoc.insert(std::make_pair(std::string(name), creat));
115     }
116
117 public:
118     typedef typename map_type::const_iterator iterator;
119
120     named_object_list2() { };
121     ~named_object_list2()
122     {
123         for (iterator it = begin(); it != end(); ++it)
124             delete it->second;
125     }
126
127     Base* new_instance(const std::string& name, Arg1 arg1, Arg2 arg2) const
128     {
129         iterator it = assoc.find(name);
130         if (it != assoc.end())
131             return (*it->second)(arg1, arg2);
132         else
133             return nullptr;
134     }
135
136     const std::string& get_name(iterator& it) const { return it->first; }
137     const std::string& get_descr(iterator& it) const
138     { return it->second->description; }
139
140     bool exists(const std::string& name) const
141     { return assoc.find(name) != assoc.end(); }
142     iterator begin() const       { return assoc.begin(); }
143     iterator end() const         { return assoc.end();   }
144
145 };
146
147 //===================
148
149 // "NOL" like in Named_Object_List....
150 #define NOL_INSERT(name, descr, class) insert(name, new creator<class>(descr))
151
152 #endif // !NAMED_OBJECT_LIST_H
153
154 // Local variables:
155 // mode: c++
156 // End: