[coco] Notify Child Join/Leave from DLinkedList (#1653)
author박종현/동작제어Lab(SR)/Staff Engineer/삼성전자 <jh1302.park@samsung.com>
Thu, 27 Sep 2018 09:54:58 +0000 (18:54 +0900)
committerGitHub Enterprise <noreply-CODE@samsung.com>
Thu, 27 Sep 2018 09:54:58 +0000 (18:54 +0900)
With this commit, users may implement a hook on child join/leave event
for classes that inherit DLinkedList traits.

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
contrib/coco/core/src/IR/Block.cpp
contrib/coco/core/src/IR/Instr.cpp

index 6890ab0..229c885 100644 (file)
@@ -12,6 +12,11 @@ namespace coco
 // **CAUTION** Child SHOULD inherit DLinkedList<Child, Parent>::Node
 template <typename Child, typename Parent> struct DLinkedList
 {
+  // @brief A hook for Child-Join event
+  static void joined(Parent *, Child *);
+  // @brief A hook for Child-Leave event
+  static void leaving(Parent *, Child *);
+
   class Head
   {
   public:
@@ -73,6 +78,9 @@ template <typename Child, typename Parent> struct DLinkedList
 
       // Update parent-child relation
       child->parent(_parent);
+
+      // Notify Child-Joining event
+      joined(_parent, child);
     }
 
   public:
@@ -81,6 +89,9 @@ template <typename Child, typename Parent> struct DLinkedList
       assert(child->parent() == _parent);
       assert(!empty());
 
+      // Notify Child-Leaving event
+      leaving(_parent, child);
+
       if (child == _head)
       {
         _head = child->next();
index 7ff35c1..c4dd13e 100644 (file)
@@ -15,16 +15,22 @@ using ChildList = coco::DLinkedList<Child, Parent>::Head;
 class Parent
 {
 public:
-  Parent() : _list{this}
+  friend void coco::DLinkedList<Child, Parent>::joined(Parent *, Child *);
+  friend void coco::DLinkedList<Child, Parent>::leaving(Parent *, Child *);
+
+public:
+  Parent() : _list{this}, _count{0}
   {
     // DO NOTHING
   }
 
 public:
   ChildList *children(void) { return &_list; }
+  uint32_t count(void) const { return _count; }
 
 private:
   ChildList _list;
+  uint32_t _count;
 };
 
 class Child final : public coco::DLinkedList<Child, Parent>::Node
@@ -37,6 +43,9 @@ class Child final : public coco::DLinkedList<Child, Parent>::Node
 namespace coco
 {
 
+template <> void DLinkedList<Child, Parent>::joined(Parent *p, Child *) { p->_count += 1; }
+template <> void DLinkedList<Child, Parent>::leaving(Parent *p, Child *) { p->_count -= 1; }
+
 template <> ChildList *DLinkedList<Child, Parent>::head(Parent *p) { return p->children(); }
 
 } // namespace coco
@@ -92,6 +101,22 @@ void DLinkedListTest::destroy(Child *child)
 
 } // namespace
 
+TEST_F(DLinkedListTest, append)
+{
+  auto parent = create<::Parent>();
+  auto child = create<::Child>();
+
+  parent->children()->append(child);
+
+  ASSERT_EQ(child->parent(), parent);
+  ASSERT_EQ(child->prev(), nullptr);
+  ASSERT_EQ(child->next(), nullptr);
+
+  ASSERT_EQ(parent->children()->head(), child);
+  ASSERT_EQ(parent->children()->tail(), child);
+  ASSERT_EQ(parent->count(), 1);
+}
+
 TEST_F(DLinkedListTest, insert_two_elements)
 {
   auto parent = create<::Parent>();
index f52facf..8b0dc32 100644 (file)
@@ -4,6 +4,16 @@
 namespace coco
 {
 
+template <> void DLinkedList<Block, Module>::joined(Module *, Block *)
+{
+  // TODO Implement this
+}
+
+template <> void DLinkedList<Block, Module>::leaving(Module *, Block *)
+{
+  // TODO Implement this
+}
+
 template <> BlockList *DLinkedList<Block, Module>::head(Module *m) { return m->block(); }
 
 } // namespace coco
index fedcc3a..910e32f 100644 (file)
@@ -6,6 +6,16 @@
 namespace coco
 {
 
+template <> void DLinkedList<Instr, Block>::joined(Block *, Instr *)
+{
+  // TODO Implement this
+}
+
+template <> void DLinkedList<Instr, Block>::leaving(Block *, Instr *)
+{
+  // TODO Implement this
+}
+
 template <> InstrList *DLinkedList<Instr, Block>::head(Block *b) { return b->instr(); }
 
 } // namespace coco