From fa450d3f9dc8cea958298023bb7414c3bb484065 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=EB=B0=95=EC=A2=85=ED=98=84/=EB=8F=99=EC=9E=91=EC=A0=9C?= =?utf8?q?=EC=96=B4Lab=28SR=29/Staff=20Engineer/=EC=82=BC=EC=84=B1?= =?utf8?q?=EC=A0=84=EC=9E=90?= Date: Wed, 18 Jul 2018 11:46:29 +0900 Subject: [PATCH] [coco] Add 'PtrLink' class (#698) This commit adds 'PtrLink' class which manages a link relation between two object pointers. This commit also adds a related test, which shows the basic usage of this class. Signed-off-by: Jonghyun Park --- contrib/coco/core/include/coco/ADT/PtrLink.h | 53 +++++++++++++++++++++ contrib/coco/core/src/ADT/PtrLink.test.cpp | 69 ++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+) create mode 100644 contrib/coco/core/include/coco/ADT/PtrLink.h create mode 100644 contrib/coco/core/src/ADT/PtrLink.test.cpp diff --git a/contrib/coco/core/include/coco/ADT/PtrLink.h b/contrib/coco/core/include/coco/ADT/PtrLink.h new file mode 100644 index 0000000..cb5077a --- /dev/null +++ b/contrib/coco/core/include/coco/ADT/PtrLink.h @@ -0,0 +1,53 @@ +#ifndef __COCO_ADT_PTR_LINK_H__ +#define __COCO_ADT_PTR_LINK_H__ + +#include + +#include + +namespace coco +{ + +template class PtrLink +{ +public: + Into *find(const From *from) const + { + assert(from != nullptr); + + auto it = _content.find(from); + if (it == _content.end()) + { + return nullptr; + } + + assert(it->second != nullptr); + return it->second; + } + +public: + void set(const From *from, Into *into) + { + assert(from != nullptr); + assert(into != nullptr); + assert(_content.find(from) == _content.end()); + + _content[from] = into; + } + +public: + void unset(const From *from) + { + assert(from != nullptr); + assert(_content.find(from) != _content.end()); + + _content.erase(from); + } + +private: + std::map _content; +}; + +} // namespace coco + +#endif // __COCO_ADT_PTR_LINK_H__ diff --git a/contrib/coco/core/src/ADT/PtrLink.test.cpp b/contrib/coco/core/src/ADT/PtrLink.test.cpp new file mode 100644 index 0000000..2618d48 --- /dev/null +++ b/contrib/coco/core/src/ADT/PtrLink.test.cpp @@ -0,0 +1,69 @@ +#include "coco/ADT/PtrLink.h" + +#include + +namespace +{ + +class Parent; +class Child; + +class Parent +{ +public: + Parent(coco::PtrLink *link) : _link{link} + { + // DO NOTHING + } + +public: + void link(Child *child) + { + _link->set(child, this); + } + +public: + void unlink(Child *child) + { + assert(_link->find(child) == this); + _link->unset(child); + } + +private: + coco::PtrLink *_link; +}; + +class Child +{ +public: + Child(const coco::PtrLink *link) : _link{link} + { + // DO NOTHING + } + +public: + Parent *parent(void) const { return _link->find(this); } + +private: + const coco::PtrLink *_link; +}; + +} // namespace + +TEST(ADT_PTR_LINK, usecase) +{ + // Note that Child has no setter over parent. To update Child's parent, one shuold use + // Parent's link and unlink method. + // + // This restriction prevents incorrect update of parent-child relation. + coco::PtrLink<::Child, ::Parent> link; + + ::Parent parent{&link}; + ::Child child{&link}; + + ASSERT_EQ(child.parent(), nullptr); + parent.link(&child); + ASSERT_EQ(child.parent(), &parent); + parent.unlink(&child); + ASSERT_EQ(child.parent(), nullptr); +} -- 2.7.4