+template<typename T, typename S>
+struct Collection::Loader::Add<T, S, false>
+{
+ static void add(Loader &loader, const std::string &kwd)
+ { loader.add(kwd, &Loader::item<T, S>); }
+};
+
+template<typename T, typename S>
+struct Collection::Loader::Add<T, S, true>
+{
+ static void add(Loader &loader, const std::string &kwd)
+ { loader.add(kwd, &Loader::coll_item<T, S, typename T::Loader::Collection>); }
+};
+
+
+class CollectionItemTypeBase
+{
+protected:
+ class TagBase
+ {
+ protected:
+ TagBase() { }
+ public:
+ virtual ~TagBase() { }
+ };
+
+ template<typename T>
+ class Tag: public TagBase
+ {
+ public:
+ virtual ~Tag() { }
+ };
+
+ std::string kwd;
+ TagBase *tag;
+
+ CollectionItemTypeBase(): tag(0) { }
+public:
+ virtual ~CollectionItemTypeBase()
+ { delete tag; }
+
+ virtual void add_to_loader(Collection::Loader &) const = 0;
+ virtual bool can_create() const = 0;
+ virtual void create_item(Collection &, const std::string &) const = 0;
+
+ template<typename T>
+ bool check_type() const
+ { return dynamic_cast<Tag<T> *>(tag); }
+};
+
+
+template<typename T>
+class CollectionItemType: public CollectionItemTypeBase
+{
+private:
+ class CreatorBase
+ {
+ protected:
+ CreatorBase() { }
+ public:
+ virtual ~CreatorBase() { }
+
+ virtual T *create(Collection &, const std::string &) const = 0;
+ };
+
+ template<typename C>
+ class Creator: public CreatorBase
+ {
+ public:
+ typedef T *(C::*FuncPtr)(const std::string &);
+
+ private:
+ FuncPtr func;
+
+ public:
+ Creator(FuncPtr f): func(f) { }
+
+ virtual T *create(Collection &coll, const std::string &name) const
+ { return (static_cast<C &>(coll).*func)(name); }
+ };
+
+ class StoreBase
+ {
+ protected:
+ StoreBase() { }
+ public:
+ virtual ~StoreBase() { }
+
+ virtual void store(Collection &, const std::string &, T *) = 0;
+
+ virtual void add_to_loader(Collection::Loader &, const std::string &) = 0;
+ };
+
+ template<typename S>
+ class Store: public StoreBase
+ {
+ public:
+ virtual void store(Collection &coll, const std::string &name, T *obj)
+ { coll.add(name, static_cast<S *>(obj)); }
+
+ virtual void add_to_loader(Collection::Loader &loader, const std::string &kwd)
+ { Collection::Loader::Add<T, S>::add(loader, kwd); }
+ };
+
+ CreatorBase *creat;
+ StoreBase *store;