]> git.tdb.fi Git - libs/datafile.git/blobdiff - source/collection.h
Allow modifying existing types in a collection
[libs/datafile.git] / source / collection.h
index 89e801ffa87850ebcba5b5452c03a4a15a4dbf0b..005abd0db39e3c54c8b934ea784e5431164d70e4 100644 (file)
@@ -1,11 +1,12 @@
 #ifndef MSP_DATAFILE_COLLECTION_H_
 #define MSP_DATAFILE_COLLECTION_H_
 
+#include <msp/core/attributes.h>
 #include <msp/core/maputils.h>
-#include <msp/core/meta.h>
 #include <msp/core/refptr.h>
 #include "collectionsource.h"
 #include "loader.h"
+#include "meta.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. */
@@ -13,20 +14,6 @@ dependencies between those things make it difficult to split up. */
 namespace Msp {
 namespace DataFile {
 
-/**
-Helper struct to determine whether a Loader has a Collection typedef.
-*/
-template<typename T>
-struct NeedsCollection: public Sfinae
-{
-       template<typename U>
-       static Yes f(typename U::Collection *);
-       template<typename U>
-       static No f(...);
-
-       enum { value = Evaluate<sizeof(f<T>(0))>::value };
-};
-
 class CollectionItemTypeBase;
 
 template<typename T>
@@ -250,6 +237,11 @@ protected:
        template<typename T>
        CollectionItemType<T> &add_type();
 
+       /** Returns a mutable reference to an existing type descriptor.  This can be
+       used to e.g. override the creator function of a type added by a base class. */
+       template<typename T>
+       CollectionItemType<T> &modify_type();
+
 private:
        /** Returns the descriptor for a type, or null if one isn't defined.  An
        optional name can be given to prioritize matching types. */
@@ -274,7 +266,8 @@ public:
        IO::Seekable *open_raw(const std::string &) const;
 
 protected:
-       IO::Seekable *open_from_sources(const std::string &n) { return open_raw(n); }
+       // Deprecated.  Use open_raw instead.
+       DEPRECATED IO::Seekable *open_from_sources(const std::string &n) { return open_raw(n); }
 
 private:
        void gather_names_from_sources(std::list<std::string> &, const CollectionItemTypeBase &) const;
@@ -417,7 +410,7 @@ public:
                return *this;
        }
 
-       /** Adds a suffix that is used to match names when looking for future
+       /** Adds a suffix that is used to match names when looking for loadable
        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. */
@@ -500,6 +493,16 @@ CollectionItemType<T> &Collection::add_type()
        return *type;
 }
 
+template<typename T>
+CollectionItemType<T> &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;
+
+       throw std::logic_error("type not found in collection");
+}
+
 template<typename T>
 CollectionItemTypeBase *Collection::get_type(const std::string &name) const
 {