[coco] Introduce Dep class (#1401)
author박종현/동작제어Lab(SR)/Staff Engineer/삼성전자 <jh1302.park@samsung.com>
Fri, 7 Sep 2018 02:12:43 +0000 (11:12 +0900)
committerGitHub Enterprise <noreply-CODE@samsung.com>
Fri, 7 Sep 2018 02:12:43 +0000 (11:12 +0900)
This commit introduces Dep class which represents the edge between Bag
and its dependent Object; the code itself is derived from Object::bag.

Signed-off-by: Jonghyun Park <jh1302.park@samsung.com>
contrib/coco/core/include/coco/IR/Dep.h [new file with mode: 0644]
contrib/coco/core/src/IR/Dep.cpp [new file with mode: 0644]
contrib/coco/core/src/IR/Dep.test.cpp [new file with mode: 0644]

diff --git a/contrib/coco/core/include/coco/IR/Dep.h b/contrib/coco/core/include/coco/IR/Dep.h
new file mode 100644 (file)
index 0000000..ea8c493
--- /dev/null
@@ -0,0 +1,52 @@
+#ifndef __COCO_IR_DEP_H__
+#define __COCO_IR_DEP_H__
+
+#include "coco/IR/Bag.h"
+#include "coco/IR/BagInfo.forward.h"
+#include "coco/IR/Object.forward.h"
+
+#include "coco/ADT/PtrLink.h"
+
+namespace coco
+{
+
+/**
+ * @brief A Dep represents the edge between a Bag and its dependent Object
+ *
+ * WARNING A Dep will update dependent Object set (stored BagInfo) only when
+ * users properly initialize object and link values.
+ */
+class Dep final
+{
+public:
+  Dep() = default;
+
+public:
+  Dep(const Dep &) = delete;
+  Dep(Dep &&) = delete;
+
+public:
+  ~Dep();
+
+public:
+  Bag *bag(void) const { return _bag; }
+  void bag(Bag *);
+
+public:
+  Object *object(void) const { return _object; }
+  void object(Object *object) { _object = object; }
+
+public:
+  void link(const PtrLink<Bag, BagInfo> *link) { _link = link; }
+
+private:
+  Bag *_bag = nullptr;
+  Object *_object = nullptr;
+
+private:
+  const PtrLink<Bag, BagInfo> *_link = nullptr;
+};
+
+} // namespace coco
+
+#endif // __COCO_IR_DEP_H__
diff --git a/contrib/coco/core/src/IR/Dep.cpp b/contrib/coco/core/src/IR/Dep.cpp
new file mode 100644 (file)
index 0000000..cf3569e
--- /dev/null
@@ -0,0 +1,49 @@
+#include "coco/IR/Dep.h"
+#include "coco/IR/BagInfo.h"
+#include "coco/IR/Object.h"
+
+#include <cassert>
+
+namespace coco
+{
+
+Dep::~Dep() { bag(nullptr); }
+
+void Dep::bag(Bag *bag)
+{
+  if (_bag != nullptr)
+  {
+    // Remove bag <-> object link (if possible)
+    if (_link && _object)
+    {
+      auto info = _link->find(_bag);
+      assert(info != nullptr);
+      assert(info->object()->find(_object) != info->object()->end());
+
+      info->object()->erase(_object);
+    }
+
+    // Reset _bag
+    _bag = nullptr;
+  }
+
+  assert(_bag == nullptr);
+
+  if (bag != nullptr)
+  {
+    // Set _bag
+    _bag = bag;
+
+    // Create bag <-> object link (if possible)
+    if (_link && _object)
+    {
+      auto info = _link->find(bag);
+      assert(info != nullptr);
+      info->object()->insert(_object);
+    }
+  }
+
+  assert(_bag == bag);
+}
+
+} // namespace coco
diff --git a/contrib/coco/core/src/IR/Dep.test.cpp b/contrib/coco/core/src/IR/Dep.test.cpp
new file mode 100644 (file)
index 0000000..2f892be
--- /dev/null
@@ -0,0 +1,63 @@
+#include "coco/IR/Dep.h"
+
+#include "coco/IR/BagInfo.h"
+#include "coco/IR/BagManager.h"
+
+#include "coco/IR/ObjectInfo.h"
+#include "coco/IR/ObjectManager.h"
+#include "coco/IR/FeatureObject.h"
+
+#include <gtest/gtest.h>
+
+using namespace nncc::core::ADT;
+
+namespace
+{
+class DepTest : public ::testing::Test
+{
+protected:
+  coco::PtrLink<coco::Bag, coco::BagInfo> bag_link;
+  coco::PtrLink<coco::Object, coco::ObjectInfo> obj_link;
+
+  coco::BagManager bag_mgr{&bag_link};
+  coco::ObjectManager obj_mgr{&obj_link, &bag_link};
+};
+} // namespace
+
+TEST_F(DepTest, default_constructor)
+{
+  coco::Dep dep;
+
+  ASSERT_EQ(dep.bag(), nullptr);
+  ASSERT_EQ(dep.object(), nullptr);
+}
+
+TEST_F(DepTest, bag_update)
+{
+  auto bag = bag_mgr.create(3);
+
+  coco::Dep dep;
+
+  // NOTE b->object() is not updated here
+  dep.bag(bag);
+
+  ASSERT_EQ(dep.bag(), bag);
+}
+
+TEST_F(DepTest, bag_update_with_link_and_object)
+{
+  auto bag = bag_mgr.create(3);
+  auto obj = obj_mgr.create(feature::Shape{1, 1, 3});
+
+  coco::Dep dep;
+
+  dep.link(&bag_link);
+  dep.object(obj);
+
+  dep.bag(bag);
+
+  auto deps = *(bag->object());
+
+  ASSERT_EQ(deps.size(), 1);
+  ASSERT_NE(deps.count(obj), 0);
+}