[coco] Default constructible DLinkedList::Node (#926)
author박종현/동작제어Lab(SR)/Staff Engineer/삼성전자 <jh1302.park@samsung.com>
Wed, 8 Aug 2018 04:56:41 +0000 (13:56 +0900)
committerGitHub Enterprise <noreply-CODE@samsung.com>
Wed, 8 Aug 2018 04:56:41 +0000 (13:56 +0900)
The current design of DLinkedList::Node enforces all of its descendent classes to
implement a consturctor that takes PtrLink, and passes it to its parent.

This restriction makes it difficult to introduce some intermediate
traists.

This commit revises DLinkedList::Node to remove this restriction.

The current design enforces only leaf classes to implement 'get' method.

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

index d2af781..71ebf51 100644 (file)
@@ -133,7 +133,7 @@ template<typename Child, typename Parent> struct DLinkedList
   class Node
   {
   public:
-    Node(const PtrLink<Child, Parent> *link) : _link{link}
+    Node()
     {
       static_assert(std::is_base_of<Node, Child>::value, "Type `Child` must be subclass of `Node`.");
 
@@ -144,8 +144,17 @@ template<typename Child, typename Parent> struct DLinkedList
   public:
     virtual ~Node() = default;
 
+  protected:
+    virtual void get(const PtrLink<Child, Parent> **out) const = 0;
+
   public:
-    Parent *parent(void) const { return _link->find(reinterpret_cast<const Child *>(this)); }
+    Parent *parent(void) const
+    {
+      const PtrLink<Child, Parent> *link = nullptr;
+      get(&link);
+      assert(link != nullptr);
+      return link->find(reinterpret_cast<const Child *>(this));
+    }
 
   public:
     Child *prev(void) const { return _prev; }
@@ -237,9 +246,6 @@ template<typename Child, typename Parent> struct DLinkedList
     }
 
   private:
-    const PtrLink<Child, Parent> * const _link;
-
-  private:
     Child *_prev;
     Child *_next;
   };
index 4bce989..2d7d100 100644 (file)
@@ -22,7 +22,7 @@ class Block final : public DLinkedList<Block, Module>::Node
 {
 public:
   Block(const PtrLink<Block, Module> *block_link, PtrLink<Instr, Block> *instr_link)
-    : DLinkedList<Block, Module>::Node{block_link}, _instr{this, instr_link}
+    : _block_link{block_link}, _instr{this, instr_link}
   {
     // DO NOTHING
   }
@@ -31,6 +31,12 @@ public:
   Block(const Block &) = delete;
   Block(Block &&) = delete;
 
+private:
+  const PtrLink<Block, Module> * const _block_link;
+
+private:
+  void get(const PtrLink<Block, Module> **out) const override { *out = _block_link; }
+
 public:
   InstrList *instr(void) { return &_instr; }
   const InstrList *instr(void) const { return &_instr; }
index 67745b5..1756076 100644 (file)
@@ -29,10 +29,7 @@ using InstrList = coco::DLinkedList<Instr, Block>::Head;
 class Instr : public coco::DLinkedList<Instr, Block>::Node
 {
 public:
-  Instr(const PtrLink<Instr, Block> *link) : DLinkedList<Instr, Block>::Node{link}
-  {
-    // DO NOTHING
-  }
+  Instr() = default;
 
 public:
   Instr(const Instr &) = delete;
@@ -137,7 +134,7 @@ namespace coco
 class FeatureInstr : public Instr
 {
 public:
-  FeatureInstr(const PtrLink<Instr, Block> *link) : Instr{link}, _ifm{nullptr}, _ofm{nullptr}
+  FeatureInstr() : _ifm{nullptr}, _ofm{nullptr}
   {
     // DO NOTHING
   }
@@ -178,7 +175,7 @@ namespace coco
 class UnitF final : public FeatureInstr
 {
 public:
-  UnitF(const PtrLink<Instr, Block> *link) : FeatureInstr{link}, _op{nullptr}
+  UnitF(const PtrLink<Instr, Block> *link) : _link{link}, _op{nullptr}
   {
     // DO NOTHING
   }
@@ -192,6 +189,12 @@ public:
   std::set<Bag *> updates(void) const override;
 
 private:
+  const PtrLink<Instr, Block> * const _link;
+
+private:
+  void get(const PtrLink<Instr, Block> **out) const override { *out = _link; }
+
+private:
   Op *_op;
 
 public:
index 42fef2b..d48029b 100644 (file)
@@ -25,16 +25,22 @@ private:
   ChildList _list;
 };
 
-class Child : public coco::DLinkedList<Child, Parent>::Node
+class Child final : public coco::DLinkedList<Child, Parent>::Node
 {
 public:
-  Child(const coco::PtrLink<Child, Parent> *link) : coco::DLinkedList<Child, Parent>::Node{link}
+  Child(const coco::PtrLink<Child, Parent> *link) : _link{link}
   {
     // DO NOTHING
   }
 
+private:
+  void get(const coco::PtrLink<Child, Parent> **out) const override { *out = _link; }
+
 public:
   ChildList *head(void) const override { return parent()->children(); }
+
+private:
+  const coco::PtrLink<Child, Parent> *_link;
 };
 
 } // namespace
index e11db7e..894db1c 100644 (file)
@@ -10,12 +10,14 @@ namespace mock
 struct FeatureInstr : public coco::FeatureInstr
 {
 public:
-  FeatureInstr(const coco::PtrLink<coco::Instr, coco::Block> *ins_link)
-      : coco::FeatureInstr{ins_link}
+  FeatureInstr()
   {
-
+    // DO NOTHING
   }
 
+private:
+  void get(const coco::PtrLink<coco::Instr, coco::Block> **) const override { return; }
+
 public:
   std::set<coco::Bag *> reads(void) const override { return std::set<coco::Bag *>(); }
   std::set<coco::Bag *> updates(void) const override { return std::set<coco::Bag *>(); }
@@ -25,8 +27,7 @@ public:
 
 TEST(IR_FEATURE_INSTR, ctor)
 {
-  coco::PtrLink<coco::Instr, coco::Block> link;
-  ::mock::FeatureInstr ins{&link};
+  ::mock::FeatureInstr ins;
 
   // IFM and OFM should be initialized as nullptr
   ASSERT_EQ(ins.ifm(), nullptr);
@@ -42,8 +43,7 @@ TEST(IR_FEATURE_INSTR, ifm_update)
   auto obj = obj_mgr.create(nncc::core::ADT::feature::Shape{1, 3, 3});
 
   // Test 'FeatureInstr' class
-  coco::PtrLink<coco::Instr, coco::Block> link;
-  ::mock::FeatureInstr ins{&link};
+  ::mock::FeatureInstr ins;
 
   // 'ifm(FeatureObject *)' method should affect 'ifm()' method
   ins.ifm(obj);
@@ -59,8 +59,7 @@ TEST(IR_FEATURE_INSTR, ofm_update)
   auto obj = obj_mgr.create(nncc::core::ADT::feature::Shape{1, 3, 3});
 
   // Test 'FeatureInstr' class
-  coco::PtrLink<coco::Instr, coco::Block> link;
-  ::mock::FeatureInstr ins{&link};
+  ::mock::FeatureInstr ins;
 
   // 'ofm(FeatureObject *)' method should affect 'ofm()' method
   ins.ofm(obj);