+
+ typedef RefPtr<typename RemoveConst<T>::Type> RPNCT;
+ if(!i->second.check_type<RPNCT>())
+ return 0;
+
+ return 1;
+ }
+
+public:
+ /// Checks whether a typed object exists in the collection.
+ template<typename T>
+ bool contains(const std::string &name) const
+ { return get_status<T>(name)==1; }
+
+ /** Checks whether a typed object exists in the collection or is loadable
+ from a source. */
+ template<typename T>
+ bool contains(const std::string &name)
+ { return get_status<T>(name)>0; }
+
+ /// Returns the name of an item in the collection.
+ template<typename T>
+ const std::string &get_name(T *d) const
+ {
+ typedef RefPtr<typename RemoveConst<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;
+
+ // XXX Need better exception class
+ throw std::runtime_error("Item not found in collection");
+ }
+
+protected:
+ /** Adds a type to the collection. The returned descriptor object reference
+ can be used to define how objects of that type can be loaded. */
+ template<typename T>
+ CollectionItemType<T> &add_type();
+
+ /// Returns the descriptor for a type, or null if one isn't defined.
+ template<typename T>
+ CollectionItemTypeBase *get_type() const;
+
+ /// Returns the descriptor for an item, or null if it's of an unknown type.
+ CollectionItemTypeBase *get_type_for_item(const Variant &) const;
+
+ void add_source(CollectionSource &);
+};
+
+template<typename T>
+class Collection::ItemLoader<T, false>: public T::Loader
+{
+public:
+ ItemLoader(T &o, Collection &):
+ T::Loader(o)
+ { }
+};
+
+template<typename T>
+class Collection::ItemLoader<T, true>: public T::Loader
+{
+public:
+ ItemLoader(T &o, Collection &c):
+ T::Loader(o, dynamic_cast<typename T::Loader::Collection &>(c))
+ { }
+};
+
+
+class CollectionItemTypeBase
+{
+protected:
+ struct ExtractorBase
+ {
+ virtual ~ExtractorBase() { }