vector: added support rc_ptr and arc_ptr to vector
authorsub.mohanty@samsung.com <smohantty@gmail.com>
Sun, 25 Aug 2019 06:49:31 +0000 (15:49 +0900)
committerHermet Park <hermetpark@gmail.com>
Wed, 4 Sep 2019 08:28:44 +0000 (17:28 +0900)
why?
std::shared_ptr uses 2 pointer instead of 1.
we don't always need atomic ref count thats why rc_ptr
in situation where atomic ref cound needed use arc_ptr

src/vector/vsharedptr.h [new file with mode: 0644]

diff --git a/src/vector/vsharedptr.h b/src/vector/vsharedptr.h
new file mode 100644 (file)
index 0000000..ff746f2
--- /dev/null
@@ -0,0 +1,122 @@
+#ifndef VSHAREDPTR_H
+#define VSHAREDPTR_H
+
+#include <cassert>
+#include <memory>
+
+template <typename T, typename Rc>
+class vshared_ptr {
+    struct model {
+        Rc mRef{1};
+
+        model() = default;
+
+        template <class... Args>
+        explicit model(Args&&... args) : mValue(std::forward<Args>(args)...){}
+        explicit model(const T& other) : mValue(other){}
+
+        T mValue;
+    };
+    model* mModel{nullptr};
+
+public:
+    using element_type = T;
+
+    vshared_ptr() = default;
+
+    ~vshared_ptr()
+    {
+        unref();
+    }
+
+    template <class... Args>
+    explicit vshared_ptr(Args&&... args) : mModel(new model(std::forward<Args>(args)...))
+    {
+    }
+
+    vshared_ptr(const vshared_ptr& x) noexcept : vshared_ptr()
+    {
+        if (x.mModel)  {
+            mModel = x.mModel;
+            ++mModel->mRef;
+        }
+    }
+
+    vshared_ptr(vshared_ptr&& x) noexcept : vshared_ptr()
+    {
+        if (x.mModel)  {
+            mModel = x.mModel;
+            x.mModel = nullptr;
+        }
+    }
+
+    auto operator=(const vshared_ptr& x) noexcept -> vshared_ptr&
+    {
+        unref();
+        mModel = x.mModel;
+        ref();
+        return *this;
+    }
+
+    auto operator=(vshared_ptr&& x) noexcept -> vshared_ptr&
+    {
+        unref();
+        mModel = x.mModel;
+        x.mModel = nullptr;
+        return *this;
+    }
+
+    operator bool() const noexcept {
+      return mModel != nullptr;
+    }
+
+    auto operator*() const noexcept -> element_type& { return read(); }
+
+    auto operator-> () const noexcept -> element_type* { return &read(); }
+
+    std::size_t refCount() const noexcept
+    {
+        assert(mModel);
+
+        return mModel->mRef;
+    }
+
+    bool unique() const noexcept
+    {
+        assert(mModel);
+
+        return mModel->mRef == 1;
+    }
+
+private:
+
+    auto read() const noexcept -> element_type&
+    {
+        assert(mModel);
+
+        return mModel->mValue;
+    }
+
+    void ref()
+    {
+        if (mModel) ++mModel->mRef;
+    }
+
+    void unref()
+    {
+        if (mModel && (--mModel->mRef == 0)) {
+            delete mModel;
+            mModel = nullptr;
+        }
+    }
+};
+
+// atomic ref counted pointer implementation.
+template < typename T>
+using arc_ptr = vshared_ptr<T, std::atomic<std::size_t>>;
+
+// ref counter pointer implementation.
+template < typename T>
+using rc_ptr = vshared_ptr<T, std::size_t>;
+
+#endif // VSHAREDPTR_H