#ifndef XMLSTORAGE_H #define XMLSTORAGE_H #include "sourceObject.h" #include "xmlObjectLoader.h" #include "exceptions.h" #include #include #include #include SimpleMessageException(StoreFailed); #define SINGLE(X) \ boost::intrusive_ptr #define STORAGEOF(X) \ std::map > #define ANONORDEREDSTORAGEOF(X) \ std::list > #define ANONSTORAGEOF(X) \ std::set > class Storer; typedef boost::intrusive_ptr StorerPtr; class Storer : public virtual IntrusivePtrBase { public: template static StorerPtr into(SINGLE(X) * obj); template static StorerPtr into(STORAGEOF(X) * map); template static StorerPtr into(ANONSTORAGEOF(X) * set); template static StorerPtr into(ANONORDEREDSTORAGEOF(X) * list); virtual boost::intrusive_ptr save(const xmlpp::Element *) = 0; }; template class StorerBase : public Storer { public: typedef M * Map; boost::intrusive_ptr save(const xmlpp::Element * p) { try { boost::intrusive_ptr O = boost::dynamic_pointer_cast( LoaderBase::getLoader(p->get_name())->createFrom(p)); if (O) { if (!insert(p, O)) { throw StoreFailed(p->get_attribute_value("name")); } } return O; } catch (NotSupported) { return NULL; } } virtual bool insert(const xmlpp::Element *, boost::intrusive_ptr) = 0; }; template class StorerImpl : public StorerBase { public: StorerImpl(M * m); bool insert(const xmlpp::Element *, boost::intrusive_ptr O); }; template class StorerImpl : public StorerBase { public: typedef SINGLE(X) Obj; StorerImpl(SINGLE(X) * o) : obj(o) { } bool insert(const xmlpp::Element *, boost::intrusive_ptr O) { *obj = O; return true; } Obj * obj; }; template class StorerImpl : public StorerBase { public: typedef STORAGEOF(X) Map; StorerImpl(STORAGEOF(X) * m) : map(m) { } bool insert(const xmlpp::Element *, boost::intrusive_ptr O) { return map->insert(typename Map::value_type(O->name, O)).second; } Map * map; }; template class StorerImpl : public StorerBase { public: typedef ANONSTORAGEOF(X) Map; StorerImpl(ANONSTORAGEOF(X) * m) : map(m) { } bool insert(const xmlpp::Element *, boost::intrusive_ptr O) { map->insert(O); return true; } Map * map; }; template class StorerImpl : public StorerBase { public: typedef ANONORDEREDSTORAGEOF(X) Map; StorerImpl(ANONORDEREDSTORAGEOF(X) * m) : map(m) { } bool insert(const xmlpp::Element *, boost::intrusive_ptr O) { map->push_back(O); return true; } Map * map; }; template StorerPtr Storer::into(SINGLE(X) * obj) { return new StorerImpl(obj); } template StorerPtr Storer::into(STORAGEOF(X) * map) { return new StorerImpl(map); } template StorerPtr Storer::into(ANONSTORAGEOF(X) * set) { return new StorerImpl(set); } template StorerPtr Storer::into(ANONORDEREDSTORAGEOF(X) * list) { return new StorerImpl(list); } #endif