+#ifndef NAMED_OBJECT_LIST_H
+#define NAMED_OBJECT_LIST_H
+
+#include <map>
+#include <string>
+
+//===== arity 0 =====
+
+template <typename Base>
+class named_object_list {
+protected:
+ struct creator_base {
+ std::string description;
+ creator_base(const std::string& descr): description(descr) { }
+ creator_base(const char* descr): description(descr) { }
+ virtual Base* operator()() const = 0;
+ };
+
+ template <typename Derived>
+ struct creator: public creator_base {
+ creator(const std::string& descr): creator_base(descr) { }
+ creator(const char* descr): creator_base(descr) { }
+ Base* operator()() const { return new Derived(); }
+ };
+
+ typedef std::map<std::string, const creator_base*> map_type;
+
+ map_type assoc;
+
+ void insert(const std::string& name, const creator_base* creat)
+ {
+ assoc.insert(std::make_pair(name, creat));
+ }
+
+ void insert(const char* name, const creator_base* creat)
+ {
+ assoc.insert(std::make_pair(std::string(name), creat));
+ }
+
+public:
+ typedef typename map_type::const_iterator iterator;
+
+ named_object_list() { };
+ ~named_object_list()
+ {
+ for (iterator it = begin(); it != end(); ++it)
+ delete it->second;
+ }
+
+ Base* new_instance(const std::string& name) const
+ {
+ iterator it = assoc.find(name);
+ if (it != assoc.end())
+ return (*it->second)();
+ else
+ return NULL;
+ }
+
+ Base* new_instance(const char* name) const
+ {
+ return new_instance(std::string(name));
+ }
+
+ const std::string& get_name(iterator& it) const { return it->first; }
+ const std::string& get_descr(iterator& it) const
+ { return it->second->description; }
+
+ size_t size() const { return assoc.size(); }
+ iterator begin() const { return assoc.begin(); }
+ iterator end() const { return assoc.end(); }
+
+};
+
+//===== arity 2 =====
+
+#include <map>
+#include <string>
+
+template <typename Base, typename Arg1, typename Arg2>
+class named_object_list2 {
+protected:
+ struct creator_base {
+ std::string description;
+ creator_base(const std::string& descr): description(descr) { }
+ creator_base(const char* descr): description(descr) { }
+ virtual Base* operator()(Arg1, Arg2) const = 0;
+ };
+
+ template <typename Derived>
+ struct creator: public creator_base {
+ creator(const std::string& descr): creator_base(descr) { }
+ creator(const char* descr): creator_base(descr) { }
+ Base* operator()(Arg1 arg1, Arg2 arg2) const
+ { return new Derived(arg1, arg2); }
+ };
+
+ typedef std::map<std::string, const creator_base*> map_type;
+
+ map_type assoc;
+
+ void insert(const std::string& name, const creator_base* creat)
+ {
+ assoc.insert(std::make_pair(name, creat));
+ }
+
+ void insert(const char* name, const creator_base* creat)
+ {
+ assoc.insert(std::make_pair(std::string(name), creat));
+ }
+
+public:
+ typedef typename map_type::const_iterator iterator;
+
+ named_object_list2() { };
+ ~named_object_list2()
+ {
+ for (iterator it = begin(); it != end(); ++it)
+ delete it->second;
+ }
+
+ Base* new_instance(const std::string& name, Arg1 arg1, Arg2 arg2) const
+ {
+ iterator it = assoc.find(name);
+ if (it != assoc.end())
+ return (*it->second)(arg1, arg2);
+ else
+ return NULL;
+ }
+
+ Base* new_instance(const char* name, Arg1 arg1, Arg2 arg2) const
+ {
+ return new_instance(std::string(name), arg1, arg2);
+ }
+
+ const std::string& get_name(iterator& it) const { return it->first; }
+ const std::string& get_descr(iterator& it) const
+ { return it->second->description; }
+
+ bool exists(const std::string& name) const
+ { return assoc.find(name) != assoc.end(); }
+ iterator begin() const { return assoc.begin(); }
+ iterator end() const { return assoc.end(); }
+
+};
+
+//===================
+
+#define THIS_INSERT(name, descr, class) insert(name, new creator<class>(descr))
+
+#endif // !NAMED_OBJECT_LIST_H
+
+// Local variables:
+// mode: c++
+// End: