--- /dev/null
+#ifndef __COCO_ADT_PTR_MANAGER_H__
+#define __COCO_ADT_PTR_MANAGER_H__
+
+#include <vector>
+
+#include <memory>
+
+namespace coco
+{
+
+template<typename T> class PtrManager
+{
+public:
+ /// @breif Return the number of managed objects
+ uint32_t size(void) const { return _ptrs.size(); }
+
+public:
+ T *at(uint32_t n) const { return _ptrs.at(n).get(); }
+
+protected:
+ template<typename U> U *take(std::unique_ptr<U> &&o)
+ {
+ auto res = o.get();
+ _ptrs.emplace_back(std::move(o));
+ return res;
+ }
+
+private:
+ std::vector<std::unique_ptr<T>> _ptrs;
+};
+
+} // namespace coco
+
+#endif // __COCO_ADT_PTR_MANAGER_H__
--- /dev/null
+#include "coco/ADT/PtrManager.h"
+
+#include <memory>
+
+#include <gtest/gtest.h>
+
+namespace
+{
+struct Count
+{
+ uint32_t allocated;
+ uint32_t freed;
+
+ Count() : allocated{0}, freed{0}
+ {
+ // DO NOTHING
+ }
+};
+
+class Object
+{
+public:
+ Object(Count *count, uint32_t value) : _count{count}, _value{value}
+ {
+ _count->allocated += 1;
+ }
+
+public:
+ ~Object()
+ {
+ _count->freed += 1;
+ }
+
+public:
+ uint32_t value(void) const { return _value; }
+
+private:
+ Count * const _count;
+
+private:
+ uint32_t _value;
+};
+
+struct ObjectManager final : public coco::PtrManager<Object>
+{
+ Object *alloc(Count *count, uint32_t value)
+ {
+ std::unique_ptr<Object> o{new Object{count, value}};
+ return take(std::move(o));
+ }
+};
+}
+
+TEST(ADT_PTR_MANAGER, usecase)
+{
+ Count c;
+
+ ASSERT_EQ(c.allocated, 0);
+ ASSERT_EQ(c.freed, 0);
+
+ {
+ ::ObjectManager mgr;
+
+ auto obj_1 = mgr.alloc(&c, 3);
+ auto obj_2 = mgr.alloc(&c, 4);
+
+ EXPECT_EQ(c.allocated, 2);
+ ASSERT_EQ(c.freed, 0);
+
+ EXPECT_EQ(mgr.size(), 2);
+ EXPECT_EQ(mgr.at(0), obj_1);
+ EXPECT_EQ(mgr.at(1), obj_2);
+ }
+
+ // PtrManger SHOULD destruct all of the allocated object when it is destructed.
+ ASSERT_EQ(c.allocated, 2);
+ ASSERT_EQ(c.freed, 2);
+}