From: Mikko Rasa Date: Wed, 5 Dec 2012 19:16:00 +0000 (+0200) Subject: Rework the list and containment queries X-Git-Url: http://git.tdb.fi/?a=commitdiff_plain;h=bcbe8b90de68e18260313b8f0e8a8dd9c7661903;p=libs%2Fdatafile.git Rework the list and containment queries Most of the implementations are now in .cpp, and they should deal better with base classes. --- diff --git a/source/collection.cpp b/source/collection.cpp index 2333aaf..fbe894a 100644 --- a/source/collection.cpp +++ b/source/collection.cpp @@ -35,6 +35,35 @@ const Variant &Collection::get_var(const string &name, const CollectionItemTypeB return get_item(items, name); } +void Collection::gather_items(list *vars, list *names, const CollectionItemTypeBase &type, bool include_sources) const +{ + for(ItemMap::const_iterator i=items.begin(); i!=items.end(); ++i) + if(type.check_item_type(i->second)) + { + if(vars) + vars->push_back(&i->second); + if(names) + names->push_back(i->first); + } + + if(include_sources && names) + gather_names_from_sources(*names, type); +} + +unsigned Collection::get_status(const string &name, const CollectionItemTypeBase &type) const +{ + ItemMap::const_iterator i = items.find(name); + if(i==items.end()) + { + for(SourceList::const_iterator j=sources.begin(); j!=sources.end(); ++j) + if((*j)->is_loadable(type, name)) + return 2; + return 0; + } + + return type.check_item_type(i->second); +} + CollectionItemTypeBase *Collection::get_type_for_item(const Variant &var) const { for(TypeList::const_iterator i=types.begin(); i!=types.end(); ++i) @@ -48,6 +77,28 @@ void Collection::add_source(CollectionSource &s) sources.push_back(&s); } +void Collection::gather_names_from_sources(list &names, const CollectionItemTypeBase &type) const +{ + for(SourceList::const_iterator i=sources.begin(); i!=sources.end(); ++i) + { + std::list available_names = (*i)->get_names(type); + for(std::list::iterator j=available_names.begin(); j!=available_names.end(); ++j) + if(!items.count(*j)) + names.push_back(*j); + } +} + +void Collection::load_items_from_sources(const CollectionItemTypeBase &type) +{ + for(SourceList::const_iterator i=sources.begin(); i!=sources.end(); ++i) + { + std::list available_names = (*i)->get_names(type); + for(std::list::iterator j=available_names.begin(); j!=available_names.end(); ++j) + if(!items.count(*j)) + (*i)->load(*this, type, *j); + } +} + Collection::Loader::Loader(Collection &c): coll(c) diff --git a/source/collection.h b/source/collection.h index 6e6900c..d5853f2 100644 --- a/source/collection.h +++ b/source/collection.h @@ -138,30 +138,23 @@ private: T &extract(const Variant &var) const; template - void collect_items(std::list *objects, std::list *names, std::list *future_names) const + std::list extract_list(const std::list &vars) const { - typedef RefPtr::Type> RPNCT; + std::list result; + for(std::list::const_iterator i=vars.begin(); i!=vars.end(); ++i) + result.push_back(&extract(**i)); + return result; + } - for(ItemMap::const_iterator i=items.begin(); i!=items.end(); ++i) - if(i->second.check_type()) - { - if(objects) - objects->push_back(i->second.value().get()); - if(names) - names->push_back(i->first); - } - - if(future_names) - if(CollectionItemTypeBase *type = get_type()) - { - for(SourceList::const_iterator i=sources.begin(); i!=sources.end(); ++i) - { - std::list available_names = (*i)->get_names(*type); - for(std::list::iterator j=available_names.begin(); j!=available_names.end(); ++j) - if(!items.count(*j)) - future_names->push_back(*j); - } - } + void gather_items(std::list *, std::list *, const CollectionItemTypeBase &, bool) const; + + template + void gather_items(std::list *vars, std::list *names, const CollectionItemTypeBase *type, bool include_sources) const + { + if(type || (type = get_type())) + gather_items(vars, names, *type, include_sources); + else + gather_items(vars, names, CollectionItemType(), false); } public: @@ -169,9 +162,9 @@ public: template std::list get_names() const { - std::list result; - collect_items(0, &result, 0); - return result; + std::list names; + gather_items::Type>(0, &names, 0, false); + return names; } /** Returns a list of the names of objects of one type in the collection or @@ -179,18 +172,18 @@ public: template std::list get_names() { - std::list result; - collect_items(0, &result, &result); - return result; + std::list names; + gather_items::Type>(0, &names, 0, true); + return names; } /// Returns a list of objects of one type in the collection. template std::list get_list() const { - std::list result; - collect_items(&result, 0, 0); - return result; + std::list vars; + gather_items::Type>(&vars, 0, 0, false); + return extract_list(vars); } /** Returns a list of objects of one type, loading them from sources if @@ -198,48 +191,40 @@ public: template std::list get_list() { - std::list result; - std::list future; - collect_items(&result, 0, &future); - for(std::list::iterator i=future.begin(); i!=future.end(); ++i) - result.push_back(&get(*i)); - return result; + CollectionItemTypeBase *type = get_type::Type>(); + if(type) + load_items_from_sources(*type); + + std::list vars; + gather_items::Type>(&vars, 0, type, true); + return extract_list(vars); } private: + unsigned get_status(const std::string &, const CollectionItemTypeBase &) const; + template unsigned get_status(const std::string &name) const { - ItemMap::const_iterator i = items.find(name); - if(i==items.end()) - { - if(CollectionItemTypeBase *type = get_type()) - { - for(SourceList::const_iterator j=sources.begin(); j!=sources.end(); ++j) - if((*j)->is_loadable(*type, name)) - return 2; - } - return 0; - } - - typedef RefPtr::Type> RPNCT; - if(!i->second.check_type()) - return 0; + // XXX Should go through all applicable types + if(CollectionItemTypeBase *type = get_type()) + return get_status(name, *type); - return 1; + ItemMap::const_iterator i = items.find(name); + return (i!=items.end() && i->second.check_type >()); } public: /// Checks whether a typed object exists in the collection. template bool contains(const std::string &name) const - { return get_status(name)==1; } + { return get_status::Type>(name)==1; } /** Checks whether a typed object exists in the collection or is loadable from a source. */ template bool contains(const std::string &name) - { return get_status(name)>0; } + { return get_status::Type>(name)>0; } /// Returns the name of an item in the collection. template @@ -270,6 +255,10 @@ protected: CollectionItemTypeBase *get_type_for_item(const Variant &) const; void add_source(CollectionSource &); + + void gather_names_from_sources(std::list &, const CollectionItemTypeBase &) const; + + void load_items_from_sources(const CollectionItemTypeBase &); }; template