From 8c20000b08bd86a5b2bf97e7e964b58f30953154 Mon Sep 17 00:00:00 2001 From: subhransu mohanty Date: Mon, 23 Jul 2018 09:24:36 +0900 Subject: [PATCH] lottie/vector: added cow_ptr class to support copy_on_write class in vector. Change-Id: I485637da44d44ce473dc760aaf484b0377bdcda1 --- src/vector/vcowptr.h | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 src/vector/vcowptr.h diff --git a/src/vector/vcowptr.h b/src/vector/vcowptr.h new file mode 100644 index 0000000..8e94703 --- /dev/null +++ b/src/vector/vcowptr.h @@ -0,0 +1,82 @@ +#ifndef VCOWPTR_H +#define VCOWPTR_H + +#include + +template +class vcow_ptr { + struct model { + std::atomic mRef{1}; + + model() = default; + + template + explicit model(Args&&... args) : mValue(std::forward(args)...) {} + + T mValue; + }; + model* mModel; +public: + using element_type = T; + + vcow_ptr() { + static model default_s; + mModel = &default_s; + ++mModel->mRef; + } + + ~vcow_ptr() { + if (mModel && (--mModel->mRef == 0)) delete mModel; + } + + template + vcow_ptr(Args&&... args) + : mModel(new model(std::forward(args)...)) {} + + vcow_ptr(const vcow_ptr& x) noexcept : mModel(x.mModel) { + assert(mModel); + ++mModel->mRef; + } + vcow_ptr(vcow_ptr&& x) noexcept : mModel(x.mModel) { + assert(mModel); + x.mModel = nullptr; + } + + auto operator=(const vcow_ptr& x) noexcept -> vcow_ptr& { + return *this = vcow_ptr(x); + } + + auto operator=(vcow_ptr&& x) noexcept -> vcow_ptr& { + auto tmp = std::move(x); + swap(*this, tmp); + return *this; + } + + auto operator*() const noexcept -> const element_type& { return read(); } + + auto operator-> () const noexcept -> const element_type* { return &read(); } + + bool unique() const noexcept { + assert(mModel); + + return mModel->mRef == 1; + } + + auto write() -> element_type& { + if (!unique()) *this = vcow_ptr(read()); + + return mModel->mValue; + } + + auto read() const noexcept -> const element_type& { + assert(mModel); + + return mModel->mValue; + } + + friend inline void swap(vcow_ptr& x, vcow_ptr& y) noexcept { + std::swap(x.mModel, y.mModel); + } +}; + +#endif // VCOWPTR_H -- 2.7.4