X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fcollection.h;h=c83b4376d20b2b6d4854b29dfc0fbda9c0c286b5;hb=348a6d9ca1a9b3838ff8c6da5050f61b2c74d010;hp=0595aaca7caddb801d094d9ed847362c669c8be7;hpb=4f036ceabe12869c86cb6821f698fbb65cd47ea6;p=libs%2Fdatafile.git diff --git a/source/collection.h b/source/collection.h index 0595aac..c83b437 100644 --- a/source/collection.h +++ b/source/collection.h @@ -55,34 +55,27 @@ public: template friend class CollectionItemType; private: - template::value> - struct Add; - Collection &coll; public: Loader(Collection &); Collection &get_object() const { return coll; } private: - template - void coll_item(const std::string &n) - { - RefPtr it = new T; - load_sub(*it, dynamic_cast(coll)); - coll.add(n, it.get()); - it.release(); - } - template void item(const std::string &n) { RefPtr it = new T; - load_sub(*it); + ItemLoader ldr(*it, coll); + load_sub_with(ldr); coll.add(n, it.get()); it.release(); } }; +protected: + template::value> + class ItemLoader; + private: typedef std::map ItemMap; typedef std::list TypeList; @@ -137,6 +130,14 @@ protected: insert_unique(items, name, ptr); } + /** Adds the name of a future object, guessing its type. If a type matching + the name can't be found, nothing is done. */ + void add_future(const std::string &name); + + /** Adds the name of a future object, using a keyword to determine its type. + The keyword must be known to the collection. */ + void add_future_with_keyword(const std::string &name, const std::string &); + public: /// Gets a typed object from the collection. template @@ -144,7 +145,7 @@ public: { typedef typename RemoveConst::Type NCT; - T *ptr = get_item(items, name).value >(); + T *ptr = get_item(items, name).value >().get(); if(!ptr) throw key_error(typeid(ItemMap)); return *ptr; @@ -157,7 +158,7 @@ public: private: template - void collect_items(std::list *objects, std::list *names, std::list *future_names) + void collect_items(std::list *objects, std::list *names, std::list *future_names) const { typedef RefPtr::Type> RPNCT; @@ -270,19 +271,22 @@ protected: CollectionItemType &add_type(); }; - -template -struct Collection::Loader::Add +template +class Collection::ItemLoader: public T::Loader { - static void add(Loader &loader, const std::string &kwd) - { loader.add(kwd, &Loader::item); } +public: + ItemLoader(T &o, Collection &): + T::Loader(o) + { } }; -template -struct Collection::Loader::Add +template +class Collection::ItemLoader: public T::Loader { - static void add(Loader &loader, const std::string &kwd) - { loader.add(kwd, &Loader::coll_item); } +public: + ItemLoader(T &o, Collection &c): + T::Loader(o, dynamic_cast(c)) + { } }; @@ -302,15 +306,21 @@ protected: { }; std::string kwd; + std::vector suffixes; TagBase *tag; CollectionItemTypeBase(); public: virtual ~CollectionItemTypeBase(); + void set_keyword(const std::string &); + const std::string &get_keyword() const { return kwd; } + void add_suffix(const std::string &); + bool match_name(const std::string &) const; 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; + virtual Variant create_future() const = 0; template bool check_type() const @@ -360,6 +370,7 @@ private: virtual ~StoreBase() { } virtual void store(Collection &, const std::string &, T *) = 0; + virtual Variant create_future() const = 0; virtual void add_to_loader(Collection::Loader &, const std::string &) = 0; }; @@ -371,8 +382,11 @@ private: virtual void store(Collection &coll, const std::string &name, T *obj) { coll.add(name, static_cast(obj)); } + virtual Variant create_future() const + { return RefPtr(0); } + virtual void add_to_loader(Collection::Loader &loader, const std::string &kwd) - { Collection::Loader::Add::add(loader, kwd); } + { loader.add(kwd, &Collection::Loader::item); } }; CreatorBase *creat; @@ -394,7 +408,17 @@ public: item's name. */ CollectionItemType &keyword(const std::string &k) { - kwd = k; + set_keyword(k); + return *this; + } + + /** Adds a suffix that is used to match names when looking for future + objects. There is no implied separator; a name matches if it ends with the + suffix. If a keyword is defined before any suffixes, then "."+keyword is + added as a suffix. */ + CollectionItemType &suffix(const std::string &s) + { + add_suffix(s); return *this; } @@ -438,6 +462,9 @@ public: if(obj) store->store(coll, name, obj); } + + virtual Variant create_future() const + { return store->create_future(); } }; @@ -458,7 +485,10 @@ T &Collection::get(const std::string &name) if((*j)->can_create() && (*j)->check_type()) (*j)->create_item(*this, name); - return *get_item(items, name).value >(); + NCT *ptr = get_item(items, name).value >().get(); + if(!ptr) + throw key_error(typeid(ItemMap)); + return *ptr; } template