private:
typedef std::map<std::string, Variant> ItemMap;
- typedef std::vector<CollectionItemTypeBase *> TypeList;
- typedef std::vector<const CollectionSource *> SourceList;
- TypeList types;
+ std::vector<CollectionItemTypeBase *> types;
ItemMap items;
- SourceList sources;
+ std::vector<const CollectionSource *> sources;
Collection *fallback;
public:
std::list<T *> extract_list(const std::vector<const Variant *> &vars) const
{
std::list<T *> result;
- for(std::vector<const Variant *>::const_iterator i=vars.begin(); i!=vars.end(); ++i)
- result.push_back(&extract<T>(**i));
+ for(const Variant *v: vars)
+ result.push_back(&extract<T>(*v));
return result;
}
{
typedef RefPtr<typename std::remove_cv<T>::type> RPNCT;
- for(ItemMap::const_iterator i=items.begin(); i!=items.end(); ++i)
- if(i->second.check_type<RPNCT>())
- if(i->second.value<RPNCT>().get()==d)
- return i->first;
+ for(const auto &kvp: items)
+ if(kvp.second.check_type<RPNCT>())
+ if(kvp.second.value<RPNCT>().get()==d)
+ return kvp.first;
// XXX Need better exception class
throw std::runtime_error("Item not found in collection");
virtual bool can_create() const = 0;
virtual void create_item(Collection &, const std::string &) const = 0;
virtual void load_item(Collection &, Parser &, const std::string &) const = 0;
- virtual void notify_item(Collection &, const std::string &, const Variant &) const = 0;
+ virtual void notify_item(const std::string &, const Variant &) const = 0;
template<typename T>
bool can_extract() const
{
- for(std::vector<ExtractorBase *>::const_iterator i=extractors.begin(); i!=extractors.end(); ++i)
- if(dynamic_cast<Extractor<T> *>(*i))
+ for(ExtractorBase *e: extractors)
+ if(dynamic_cast<Extractor<T> *>(e))
return true;
return false;
}
template<typename T>
T *extract(const Variant &var) const
{
- for(std::vector<ExtractorBase *>::const_iterator i=extractors.begin(); i!=extractors.end(); ++i)
- if(Extractor<T> *ex = dynamic_cast<Extractor<T> *>(*i))
+ for(ExtractorBase *e: extractors)
+ if(Extractor<T> *ex = dynamic_cast<Extractor<T> *>(e))
return &ex->extract(var);
return 0;
}
class CollectionItemType: public CollectionItemTypeBase
{
private:
- struct CreatorBase
- {
- virtual ~CreatorBase() { }
-
- virtual T *create(Collection &, const std::string &) const = 0;
- };
-
- template<typename C>
- struct Creator: CreatorBase
- {
- typedef T *(C::*FuncPtr)(const std::string &);
-
- FuncPtr func;
-
- Creator(FuncPtr f): func(f) { }
-
- virtual T *create(Collection &coll, const std::string &name) const
- { return (dynamic_cast<C &>(coll).*func)(name); }
- };
-
- struct NotifyeeBase
- {
- virtual ~NotifyeeBase() { }
-
- virtual void notify(Collection &, const std::string &, T &) const = 0;
- };
-
- template<typename C>
- struct Notifyee: NotifyeeBase
- {
- typedef void (C::*FuncPtr)(const std::string &, T &);
-
- FuncPtr func;
-
- Notifyee(FuncPtr f): func(f) { }
-
- virtual void notify(Collection &coll, const std::string &name, T &item) const
- { (dynamic_cast<C &>(coll).*func)(name, item); }
- };
-
template<typename B>
struct Extractor: CollectionItemTypeBase::Extractor<B>
{
{ return *var.value<RefPtr<T> >(); }
};
- CreatorBase *creat;
- std::vector<NotifyeeBase *> notif;
+ std::function<T *(const std::string &)> create_func;
+ std::vector<std::function<void(const std::string &, T &)>> notify_funcs;
public:
- CollectionItemType():
- creat(0)
- { }
-
- ~CollectionItemType()
- {
- delete creat;
- for(typename std::vector<NotifyeeBase *>::const_iterator i=notif.begin(); i!=notif.end(); ++i)
- delete *i;
- }
-
/** Sets a datafile keyword for this item type. The Collection's loader
will accept a statement with this keyword and a single string argument - the
item's name. */
type. It must return the created object, or null if it could not be
created. It's also permissible to load the item via other means and then
return null. */
- template<typename C>
- CollectionItemType &creator(T *(C::*func)(const std::string &))
+ template<typename F>
+ CollectionItemType &creator(F func)
{
- delete creat;
- creat = new Creator<C>(func);
+ create_func = func;
return *this;
}
return *this;
}
- template<typename C>
- CollectionItemType ¬ify(void (C::*func)(const std::string &, T &))
+ template<typename F>
+ CollectionItemType ¬ify(F func)
{
- notif.push_back(new Notifyee<C>(func));
+ notify_funcs.emplace_back(func);
return *this;
}
{ }
virtual bool can_create() const
- { return creat!=0; }
+ { return static_cast<bool>(create_func); }
virtual void create_item(Collection &coll, const std::string &name) const
{
- if(!creat)
+ if(!create_func)
throw std::runtime_error("no creator");
- T *obj = creat->create(coll, name);
+ T *obj = create_func(name);
if(obj)
coll.add(name, obj);
}
throw std::runtime_error("this type cannot be loaded");
}
- virtual void notify_item(Collection &coll, const std::string &name, const Variant &var) const
+ virtual void notify_item(const std::string &name, const Variant &var) const
{
RefPtr<T> obj = var.value<RefPtr<T> >();
- for(typename std::vector<NotifyeeBase *>::const_iterator i=notif.begin(); i!=notif.end(); ++i)
- (*i)->notify(coll, name, *obj);
+ for(const auto &n: notify_funcs)
+ n(name, *obj);
}
};
template<typename T>
typename CollectionItemTypeChooser<T>::Type &Collection::modify_type()
{
- for(TypeList::const_iterator j=types.begin(); j!=types.end(); ++j)
- if(CollectionItemType<T> *t = dynamic_cast<CollectionItemType<T> *>(*j))
- return *t;
+ for(CollectionItemTypeBase *t: types)
+ if(CollectionItemType<T> *tt = dynamic_cast<CollectionItemType<T> *>(t))
+ return *tt;
throw std::logic_error("type not found in collection");
}
template<typename T>
CollectionItemTypeBase *Collection::get_type(const std::string &name) const
{
- for(TypeList::const_iterator j=types.begin(); j!=types.end(); ++j)
- if(dynamic_cast<CollectionItemType<T> *>(*j))
- return *j;
+ for(CollectionItemTypeBase *t: types)
+ if(dynamic_cast<CollectionItemType<T> *>(t))
+ return t;
CollectionItemTypeBase *type = 0;
- for(TypeList::const_iterator j=types.begin(); j!=types.end(); ++j)
- if((*j)->can_extract<T>())
+ for(CollectionItemTypeBase *t: types)
+ if(t->can_extract<T>())
{
- if(!name.empty() && (*j)->match_name(name))
- return *j;
- type = *j;
+ if(!name.empty() && t->match_name(name))
+ return t;
+ type = t;
}
return type;
}