[coco] Implement 'insertBefore' (#805)
author박종현/동작제어Lab(SR)/Staff Engineer/삼성전자 <jh1302.park@samsung.com>
Wed, 25 Jul 2018 23:16:15 +0000 (08:16 +0900)
committerGitHub Enterprise <noreply-CODE@samsung.com>
Wed, 25 Jul 2018 23:16:15 +0000 (08:16 +0900)
This commit implements 'insertBefore' method in DLinkedList::Node trait.

Signed-off-by: Jonghyun Park <jh1302.park@samsung.com>
contrib/coco/core/include/coco/ADT/DLinkedList.h
contrib/coco/core/src/ADT/DLinkedList.test.cpp

index bf19fe9..f29951f 100644 (file)
@@ -119,6 +119,34 @@ template<typename Child, typename Parent> struct DLinkedList
     virtual Head *head(void) const = 0;
 
   public:
+    void insertBefore(Child *next)
+    {
+      assert(next != nullptr);
+      assert(next->head() != nullptr);
+
+      assert(_prev == nullptr);
+      assert(_next == nullptr);
+
+      // REQUIRE Child should inheir Node class
+      auto curr = reinterpret_cast<Child *>(this);
+
+      // Update the link of the current node
+      _prev = next->prev();
+      _next = next;
+
+      if (auto prev = next->prev())
+      {
+        prev->_next = curr;
+      }
+      next->_prev = curr;
+
+      // Update parent-child relation
+      assert(parent() == nullptr);
+      next->head()->enlist(curr);
+      assert(parent() == next->parent());
+    }
+
+  public:
     void insertAfter(Child *prev)
     {
       assert(prev != nullptr);
index 8459df3..8138cce 100644 (file)
@@ -86,3 +86,31 @@ TEST(ADT_DLINKED_LINK, insert_two_elements)
   delete parent;
   delete link;
 }
+
+TEST(ADT_DLINKED_LINK, insertBefore)
+{
+  auto link = new coco::PtrLink<::Child, ::Parent>{};
+  auto parent = new ::Parent{link};
+
+  auto child_1 = new ::Child{link};
+  auto child_2 = new ::Child{link};
+
+  parent->children()->append(child_1);
+  child_2->insertBefore(child_1);
+
+  ASSERT_EQ(child_2->parent(), parent);
+  ASSERT_EQ(child_2->prev(), nullptr);
+  ASSERT_EQ(child_2->next(), child_1);
+
+  ASSERT_EQ(child_1->parent(), parent);
+  ASSERT_EQ(child_1->prev(), child_2);
+  ASSERT_EQ(child_1->next(), nullptr);
+
+  ASSERT_EQ(parent->children()->head(), child_2);
+  ASSERT_EQ(parent->children()->tail(), child_1);
+
+  delete child_2;
+  delete child_1;
+  delete parent;
+  delete link;
+}