summaryrefslogtreecommitdiff
path: root/project2/xmlStorage.h
diff options
context:
space:
mode:
Diffstat (limited to 'project2/xmlStorage.h')
-rw-r--r--project2/xmlStorage.h66
1 files changed, 66 insertions, 0 deletions
diff --git a/project2/xmlStorage.h b/project2/xmlStorage.h
new file mode 100644
index 0000000..d35a182
--- /dev/null
+++ b/project2/xmlStorage.h
@@ -0,0 +1,66 @@
+#ifndef XMLSTORAGE_H
+#define XMLSTORAGE_H
+
+#include "sourceObject.h"
+#include "exceptions.h"
+#include <boost/intrusive_ptr.hpp>
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/member.hpp>
+#include <boost/multi_index/ordered_index.hpp>
+
+SimpleMessageException(StoreFailed);
+
+struct bySOName { };
+struct bySOOrder { };
+
+template <class X>
+class Storage {
+ public:
+ typedef boost::multi_index::multi_index_container<
+ boost::intrusive_ptr<X>,
+ boost::multi_index::indexed_by<
+ boost::multi_index::ordered_unique<
+ boost::multi_index::tag<bySOOrder>, BOOST_MULTI_INDEX_MEMBER(SourceObject, const unsigned int, order)>,
+ boost::multi_index::ordered_unique<
+ boost::multi_index::tag<bySOName>, BOOST_MULTI_INDEX_MEMBER(SourceObject, const std::string, name)>
+ > > Objects;
+ typedef Objects * ObjectsPtr;
+};
+class Storer;
+typedef boost::intrusive_ptr<Storer> StorerPtr;
+class Storer : public virtual IntrusivePtrBase {
+ public:
+ template <class X>
+ static StorerPtr into(X * map);
+
+ virtual bool save(SourceObjectPtr o) const = 0;
+};
+
+template <class X>
+class StorerImpl : public Storer {
+ public:
+ StorerImpl(typename Storage<X>::ObjectsPtr m) : map(m)
+ {
+ }
+
+ bool save(SourceObjectPtr obj) const {
+ boost::intrusive_ptr<X> O = boost::dynamic_pointer_cast<X>(obj);
+ if (O) {
+ if (map->insert(O).second) {
+ return true;
+ }
+ throw StoreFailed(obj->name);
+ }
+ return false;
+ }
+ typename Storage<X>::ObjectsPtr map;
+};
+
+template <class X>
+StorerPtr
+Storer::into(X * map) {
+ return new StorerImpl<typename X::value_type::element_type>(map);
+}
+
+#endif
+