Advertisement
Guest User

Untitled

a guest
Dec 18th, 2018
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.35 KB | None | 0 0
  1. #ifndef GRAFCYTOWAN_CITATION_GRAPH_H
  2. #define GRAFCYTOWAN_CITATION_GRAPH_H
  3.  
  4. #include <vector>
  5. #include <memory>
  6. #include <set>
  7. #include <map>
  8.  
  9. class PublicationNotFound : public std::exception {
  10.     const char *what() const noexcept override {
  11.         return "PublicationNotFound";
  12.     }
  13. };
  14.  
  15. class PublicationAlreadyCreated : public std::exception {
  16.     const char *what() const noexcept override {
  17.         return "PublicationAlreadyCreated";
  18.     }
  19. };
  20.  
  21. class TriedToRemoveRoot : public std::exception {
  22.     const char *what() const noexcept override {
  23.         return "TriedToRemoveRoot";
  24.     }
  25. };
  26.  
  27. template <class Publication>
  28. class CitationGraph {
  29. private:
  30.     struct Node {
  31.         std::set<std::shared_ptr<Node>> children;
  32.         std::set<std::weak_ptr<Node>, std::owner_less<Node>> parents;
  33.         Publication publication;
  34.  
  35.         Node(Publication::id_type const &publication)
  36.             : publication(publication) {
  37.  
  38.         }
  39.     }
  40.  
  41.     using std::map<Publication::id_type, std::weak_ptr<Node>> = mapType
  42.     std::shared_ptr<Node> root;
  43.     std::shared_ptr<mapType> publications;
  44.  
  45. public:
  46.     CitationGraph(Publication::id_type const &stem_id) {
  47.         publications = std::make_shared<mapType>();
  48.         root = std::make_shared<Node>(stem_id);
  49.     }
  50.  
  51.     CitationGraph(const CitationGraph<Publication> &other) = delete;
  52.     CitationGraph<Publication>& operator=(const CitationGraph<Publication> &other) = delete;
  53.  
  54.     CitationGraph(CitationGraph<Publication> &&other) noexcept {
  55.         *this = std::move(other);
  56.     }
  57.  
  58.     CitationGraph<Publication>& operator=(CitationGraph<Publication> &&other) {
  59.         swap(root, other.root);
  60.         swap(publications, other.publications);
  61.  
  62.         return *this;
  63.     }
  64.  
  65.     Publication::id_type get_root_id() const noexcept(noexcept(std::declval<Publication>().get_id())) {
  66.         return root->publication.get_id();
  67.     }
  68.  
  69.  
  70.     std::vector<Publication::id_type> get_children(Publication::id_type const &id) const {
  71.         if (!exists(id))
  72.             throw PublicationNotFound();
  73.  
  74.         std::vector<Publication::id_type> ret;
  75.         std::shared_ptr<Node> foundNode = publications->at(id).lock();
  76.  
  77.         for (std::shared_ptr<Node> child: children)
  78.             ret.emplace_back(child->publication.get_id());
  79.  
  80.         return ret;
  81.     }
  82.  
  83.     std::vector<Publication::id_type> get_parents(Publication::id_type const &id) const {
  84.         if (!exists(id))
  85.             throw PublicationNotFound();
  86.  
  87.         std::vector<Publication::id_type> ret;
  88.         std::shared_ptr<Node> foundNode = publications->at(id).lock();
  89.  
  90.         for (std::shared_ptr<Node> parent: parents)
  91.             if (!parent.expired())
  92.                 ret.emplace_back(parent.lock()->publication.get_id());
  93.  
  94.         return ret;
  95.     }
  96.  
  97.     bool exists(Publication::id_type const &id) const {
  98.         auto foundNode = publications->find(id);
  99.  
  100.         return foundNode != publications.end() && !(foundNode->second.expired());
  101.     }
  102.  
  103.     Publication& operator[](Publication::id_type const &id) const {
  104.         if (!exists(id))
  105.             throw PublicationNotFound();
  106.  
  107.         return publications->find(id).second.lock()->publication;
  108.     }
  109.     // TODO
  110.     // void create(Publication::id_type const &id, Publication::id_type const &parent_id);
  111.     // void create(Publication::id_type const &id, std::vector<Publication::id_type> const &parent_ids);
  112.     // TODO
  113.  
  114.     void add_citation(Publication::id_type const &child_id, Publication::id_type const &parent_id) {
  115.         if (!exists(child_id) || !exists(parent_id))
  116.             throw PublicationNotFound();
  117.  
  118.         shared_ptr<Node> childNode = publications.find(child_id)->second.lock();
  119.         shared_ptr<Node> parentNode = publications.find(parent_id)->second.lock();
  120.         auto insertParent = childNode->parents.insert(parentNode);
  121.  
  122.         try {
  123.             parentNode->children.insert(childNode);
  124.         } catch (...) {
  125.             if (insertParent.second)
  126.                 childNode->publications.erase(insertParent.first);
  127.         }
  128.     }
  129.  
  130.     void remove(Publication::id_type const &id) {
  131.         if (!exists(id))
  132.             throw PublicationNotFound();
  133.         if (root->publication.get_id())
  134.             throw TriedToRemoveRoot();
  135.  
  136.         std::weak_ptr<Node> nodeToRemove = publications.find(id)->second;
  137.         std::shared_ptr<Node> nodeToRemoveShared = nodeToRemove.lock();
  138.  
  139.         for (const std::weak_ptr<Node> &parent : nodeToRemoveShared->parents) {
  140.             if (!parent.expired())
  141.                 parent.lock()->parentShared->children.erase(nodeToRemoveShared);
  142.         }
  143.     }
  144. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement