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

Private GIT Repository
Move loading of atomic vs. cstdatomic in atomic_compat.h.
[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 Base* operator()() const = 0;
28     };
29
30     template <typename Derived>
31     struct creator: public creator_base {
32         creator(const std::string& descr): creator_base(descr) { }
33         creator(const char* descr): creator_base(descr) { }
34         Base* operator()() const { return new Derived(); }
35     };
36
37     typedef std::map<std::string, const creator_base*> map_type;
38
39     map_type assoc;
40
41     void insert(const std::string& name, const creator_base* creat)
42     {
43         assoc.insert(std::make_pair(name, creat));
44     }
45
46     void insert(const char* name, const creator_base* creat)
47     {
48         assoc.insert(std::make_pair(std::string(name), creat));
49     }
50
51 public:
52     typedef typename map_type::const_iterator iterator;
53
54     named_object_list() { };
55     ~named_object_list()
56     {
57         for (iterator it = begin(); it != end(); ++it)
58             delete it->second;
59     }
60
61     Base* new_instance(const std::string& name) const
62     {
63         iterator it = assoc.find(name);
64         if (it != assoc.end())
65             return (*it->second)();
66         else
67             return NULL;
68     }
69
70     const std::string& get_name(iterator& it) const { return it->first; }
71     const std::string& get_descr(iterator& it) const
72     { return it->second->description; }
73
74     bool exists(const std::string& name) const
75     { return assoc.find(name) != assoc.end(); }
76     iterator begin() const       { return assoc.begin(); }
77     iterator end() const         { return assoc.end();   }
78
79 };
80
81 //===== arity 2 =====
82
83 template <typename Base, typename Arg1, typename Arg2>
84 class named_object_list2 {
85 protected:
86     struct creator_base {
87         std::string description;
88         creator_base(const std::string& descr): description(descr) { }
89         creator_base(const char* descr): description(descr) { }
90         virtual Base* operator()(Arg1, Arg2) const = 0;
91     };
92
93     template <typename Derived>
94     struct creator: public creator_base {
95         creator(const std::string& descr): creator_base(descr) { }
96         creator(const char* descr): creator_base(descr) { }
97         Base* operator()(Arg1 arg1, Arg2 arg2) const
98         { return new Derived(arg1, arg2); }
99     };
100
101     typedef std::map<std::string, const creator_base*> map_type;
102
103     map_type assoc;
104
105     void insert(const std::string& name, const creator_base* creat)
106     {
107         assoc.insert(std::make_pair(name, creat));
108     }
109
110     void insert(const char* name, const creator_base* creat)
111     {
112         assoc.insert(std::make_pair(std::string(name), creat));
113     }
114
115 public:
116     typedef typename map_type::const_iterator iterator;
117
118     named_object_list2() { };
119     ~named_object_list2()
120     {
121         for (iterator it = begin(); it != end(); ++it)
122             delete it->second;
123     }
124
125     Base* new_instance(const std::string& name, Arg1 arg1, Arg2 arg2) const
126     {
127         iterator it = assoc.find(name);
128         if (it != assoc.end())
129             return (*it->second)(arg1, arg2);
130         else
131             return NULL;
132     }
133
134     const std::string& get_name(iterator& it) const { return it->first; }
135     const std::string& get_descr(iterator& it) const
136     { return it->second->description; }
137
138     bool exists(const std::string& name) const
139     { return assoc.find(name) != assoc.end(); }
140     iterator begin() const       { return assoc.begin(); }
141     iterator end() const         { return assoc.end();   }
142
143 };
144
145 //===================
146
147 // "NOL" like in Named_Object_List....
148 #define NOL_INSERT(name, descr, class) insert(name, new creator<class>(descr))
149
150 #endif // !NAMED_OBJECT_LIST_H
151
152 // Local variables:
153 // mode: c++
154 // End: