]> git.tdb.fi Git - libs/datafile.git/blobdiff - source/collection.h
Move the definition of Input's operator bool to the header
[libs/datafile.git] / source / collection.h
index 98b359e5eaedd28604a5d1f0a0085f470a657219..a0717cfd8fc44746f1f59c215c2a14ab2ce1f043 100644 (file)
@@ -9,6 +9,7 @@
 #include "collectionsource.h"
 #include "loader.h"
 #include "meta.h"
+#include "mspdatafile_api.h"
 
 /* XXX This file is a big mess with too many things in it.  However, the
 dependencies between those things make it difficult to split up. */
@@ -51,7 +52,7 @@ that are not present.  Items retrieted from the fallback collection are shared
 between the collections, and are only deleted when all collections in the chain
 have been destroyed.
 */
-class Collection: private NonCopyable
+class MSPDATAFILE_API Collection: private NonCopyable
 {
 public:
        /**
@@ -89,10 +90,9 @@ private:
        std::vector<CollectionItemTypeBase *> types;
        ItemMap items;
        std::vector<const CollectionSource *> sources;
-       Collection *fallback;
+       Collection *fallback = nullptr;
 
 public:
-       Collection();
        virtual ~Collection();
 
        /** Adds an object into the collection.  The name must not pre-exist.  The
@@ -335,7 +335,7 @@ class CollectionItemTypeBase
 protected:
        struct ExtractorBase
        {
-               virtual ~ExtractorBase() { }
+               virtual ~ExtractorBase() = default;
        };
 
        template<typename T>
@@ -348,7 +348,7 @@ protected:
        std::vector<std::string> suffixes;
        std::vector<ExtractorBase *> extractors;
 
-       CollectionItemTypeBase() { }
+       CollectionItemTypeBase() = default;
 public:
        virtual ~CollectionItemTypeBase();
 
@@ -364,7 +364,7 @@ public:
        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
@@ -394,68 +394,17 @@ template<typename T>
 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>
        {
-               virtual B &extract(const Variant &var) const
+               B &extract(const Variant &var) const override
                { 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(NotifyeeBase *n: notif)
-                       delete n;
-       }
-
        /** 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. */
@@ -481,11 +430,10 @@ public:
        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;
        }
 
@@ -497,44 +445,44 @@ public:
                return *this;
        }
 
-       template<typename C>
-       CollectionItemType &notify(void (C::*func)(const std::string &, T &))
+       template<typename F>
+       CollectionItemType &notify(F func)
        {
-               notif.push_back(new Notifyee<C>(func));
+               notify_funcs.emplace_back(func);
                return *this;
        }
 
-       virtual bool is_same_type(const CollectionItemTypeBase &other) const
+       bool is_same_type(const CollectionItemTypeBase &other) const override
        { return dynamic_cast<const CollectionItemType<T> *>(&other); }
 
-       virtual bool check_item_type(const Variant &var) const
+       bool check_item_type(const Variant &var) const override
        { return var.check_type<RefPtr<T> >(); }
 
-       virtual void add_to_loader(Collection::Loader &) const
+       void add_to_loader(Collection::Loader &) const override
        { }
 
-       virtual bool can_create() const
-       { return creat!=0; }
+       bool can_create() const override
+       { return static_cast<bool>(create_func); }
 
-       virtual void create_item(Collection &coll, const std::string &name) const
+       void create_item(Collection &coll, const std::string &name) const override
        {
-               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);
        }
 
-       virtual void load_item(Collection &, Parser &, const std::string &) const
+       void load_item(Collection &, Parser &, const std::string &) const override
        {
                throw std::runtime_error("this type cannot be loaded");
        }
 
-       virtual void notify_item(Collection &coll, const std::string &name, const Variant &var) const
+       void notify_item(const std::string &name, const Variant &var) const override
        {
                RefPtr<T> obj = var.value<RefPtr<T> >();
-               for(NotifyeeBase *n: notif)
-                       n->notify(coll, name, *obj);
+               for(const auto &n: notify_funcs)
+                       n(name, *obj);
        }
 };
 
@@ -543,10 +491,10 @@ template<typename T>
 class LoadableCollectionItemType: public CollectionItemType<T>
 {
 public:
-       virtual void add_to_loader(Collection::Loader &loader) const
+       void add_to_loader(Collection::Loader &loader) const override
        { loader.add(this->kwd, &Collection::Loader::item<T, T>); }
 
-       virtual void load_item(Collection &coll, Parser &parser, const std::string &name) const
+       void load_item(Collection &coll, Parser &parser, const std::string &name) const override
        {
                RefPtr<T> obj = new T;
                Collection::ItemLoader<T> ldr(*obj, coll);
@@ -592,7 +540,7 @@ CollectionItemTypeBase *Collection::get_type(const std::string &name) const
        for(CollectionItemTypeBase *t: types)
                if(dynamic_cast<CollectionItemType<T> *>(t))
                        return t;
-       CollectionItemTypeBase *type = 0;
+       CollectionItemTypeBase *type = nullptr;
        for(CollectionItemTypeBase *t: types)
                if(t->can_extract<T>())
                {