From bbaaaeb30d74e1ef339784f7f7d2eba8d3d9a8b1 Mon Sep 17 00:00:00 2001
From: torin <torin@git.sch.bme.hu>
Date: Mon, 25 May 2015 23:59:22 +0200
Subject: [PATCH] =?UTF-8?q?=C3=B6sszerakva=20a=202?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 main.cpp | 194 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 188 insertions(+), 6 deletions(-)

diff --git a/main.cpp b/main.cpp
index e3d1e4b..91f74f7 100644
--- a/main.cpp
+++ b/main.cpp
@@ -3,6 +3,146 @@
 #include <memory>
 #include <vector>
 
+namespace recursive_storage{
+template<class T>
+class node
+{
+private:
+
+  T t;
+  const int ID;
+  static int _id;
+  std::vector<std::shared_ptr<node<T>>> _childs{};
+  std::vector<std::weak_ptr<node<T>>> _bad_childs{};
+
+public:
+
+  node()=delete;
+
+  node(T&& t):t(std::move(t)),ID(_id++){}
+
+  node( const T& t):t(t),ID(_id++){}
+
+  T& data() { return t; }
+
+  int id() { return ID; }
+
+  std::shared_ptr<node<T>>* get_original(node<T>& t)
+  {
+    for(auto& i: _childs)
+      if(i->id() == t.id())
+	return &i;
+    return nullptr;
+  }
+
+  std::vector<node<T>*> childs()
+  {
+    std::vector<node<T>*> ret{};
+    for(auto& it : _childs)
+      ret.push_back(&(*it));
+    for(auto& it : _bad_childs)
+      ret.push_back(&(*(it.lock())));
+    return ret;
+  }
+
+  std::vector<node<T>*> inf_round_childs()
+  {
+    std::vector<node<T>*> ret{};
+    for(auto& it : _bad_childs)
+      ret.push_back(&(*(it.lock())));
+    return ret;
+  }
+
+  std::vector<node<T>*> safe_childs()
+  {
+    std::vector<node<T>*> ret{};
+    for(auto& it : _childs)
+      ret.push_back(&(*it));
+    return ret;
+  }
+
+  void erase_child(node<T>& t)
+  {
+    for(auto it= std::begin(_childs);it!=std::end(_childs);it++)
+      if((*it)->id() == t.id())
+	_childs.erase(it);
+
+    for(auto it= std::begin(_bad_childs);it!=std::end(_bad_childs);it++)
+      if((*it).lock()->id() == t.id())
+	_bad_childs.erase(it);
+  }
+
+  void flow_after(std::function<bool(node<T>&)> funct)
+  {
+    if (funct(*this))
+      return;
+    for(auto& child : _childs)
+      child->flow_after(funct);
+  }
+
+  void flow_before(std::function<bool(node<T>&)> funct)
+  {
+    for(auto& child : _childs)
+      child->flow_before(funct);
+    if (funct(*this))
+      return;
+  }
+
+  node<T>& add_child(node<T>* w)
+  {
+    if(w==this)
+      return *this;
+
+    bool found=false;
+    auto& me=*this;
+    w->flow_after([&found,&me](node<T>& t){if(&t==&me) found=true; return found;});
+    if (!found)
+    {
+      _childs.push_back(std::make_shared<node<T>>(*w));
+    }
+    else
+    {
+      std::shared_ptr<node<T>>* fo=nullptr;
+      w->flow_after([&me,&fo](node<T>& t){ fo=t.get_original(me); if(fo!=nullptr) return true; });
+      _bad_childs.push_back(std::weak_ptr<node<T>>{*fo});
+    }
+    return *this;
+  }
+
+  node<T>& add_child(node<T>& w)
+  {
+    return add_child(&w);
+  }
+
+  node<T>& add_child(const T& t)
+  {
+    _childs.push_back(std::make_shared<node<T>>(node<T>{t}));
+    return *this;
+  }
+
+};
+
+template<class T>
+int node<T>::_id=0;
+
+template<class T>
+class graph
+{
+private:
+  static void erase(node<T>& root , node<T>& to_del)
+  {
+    root.flow_after([&to_del](node<T>& t){ int i= t.childs().size(); t.erase_child(to_del); if(i>t.childs().size()) return true; return false; });
+  }
+
+public:
+  static void erase(node<T>& root , node<T>* t)
+  {
+    erase(root,*t);
+  }
+};
+}
+
+namespace local_storage{
 template<class T>
 class graph
 {
@@ -77,7 +217,13 @@ public:
     if(!foundn || !foundo)
       return;
 
-    connections.push_back(connection{n.id(),o.id()});
+    bool foundround=false;
+    int id=n.id();
+    flow_after(o,[&id,&foundround](node& n){if(n.id()==id) foundround=true;});
+    if(!foundround)
+      connections.push_back(connection{n.id(),o.id()});
+    else
+      weak_connections.push_back(connection{n.id(),o.id()});
   }
 
   void erase(node& n)
@@ -122,6 +268,26 @@ public:
           if(re.id()==i.A)
             ret.push_back(&re);
     }
+    for(auto& i : weak_connections)
+    {
+      if(n.id()==i.A)
+        for(auto& re:nodes)
+          if(re.id()==i.A)
+            ret.push_back(&re);
+    }
+    return ret;
+  }
+
+  std::vector<node*> get_inf_round_childs(node& n)
+  {
+    std::vector<node*> ret{};
+    for(auto& i : weak_connections)
+    {
+      if(n.id()==i.A)
+        for(auto& re:nodes)
+          if(re.id()==i.A)
+            ret.push_back(&re);
+    }
     return ret;
   }
 
@@ -160,20 +326,36 @@ public:
   }
 
 };
-
 template<class T>
 int graph<T>::node::_id=0;
+}
+
+void test()
+{
+  std::vector<recursive_storage::node<int>> a;
+  for(int i=0;i<1000000;i++)
+    a.push_back(recursive_storage::node<int>{5});
+  a[0].add_child(int{6});
+  a[0].childs()[0]->add_child(int{7});
+  a[0].childs()[0]->add_child(int{8});
+  auto to_del = a[0].childs()[0]->childs()[0];
+  a[0].childs()[0]->add_child(a[0]);
+  a[0].flow_after([]( recursive_storage::node<int>& elem ){ std::cout<<"inf rounds from here:"<<elem.inf_round_childs().size()<<" .id:"; std::cout<< elem.id() << ":" << elem.data() <<std::endl; return false; });
+  recursive_storage::graph<int>::erase(a[0],to_del);
+  a[0].flow_after([]( recursive_storage::node<int>& elem ){ std::cout<<"inf rounds from here:"<<elem.inf_round_childs().size()<<" .id:"; std::cout<< elem.id() << ":" << elem.data() <<std::endl; return false; });
+}
 
 int main()
 {
-  graph<int> g{};
+  local_storage::graph<int> g{};
   g.add_node(6);
   auto& t2=g.add_node(6);
-  std::cout<<"ha"<<std::endl;
   auto& t = g.add_node(52);
   g.connect(g[0],t);
   g.connect(g[0],t2);
-  std::cout<<std::endl<<g.get_childs(t).size()<<std::endl;
-  g.flow_before(g[0],[](graph<int>::node& a){std::cout<<a.data()<<":"<<a.id()<<std::endl;});
+  g.connect(t2,g[0]);
+  std::cout<<std::endl<<g.get_childs(t2).size()<<std::endl;
+  g.flow_before(g[0],[](local_storage::graph<int>::node& a){std::cout<<a.data()<<":"<<a.id()<<std::endl;});
+  test();
   return 0;
 }
-- 
GitLab