mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-03 13:13:55 +00:00
lottie/vector: added cow_ptr class to support copy_on_write class in vector.
Change-Id: I485637da44d44ce473dc760aaf484b0377bdcda1
This commit is contained in:
parent
547434e2a6
commit
8c20000b08
82
src/vector/vcowptr.h
Normal file
82
src/vector/vcowptr.h
Normal file
@ -0,0 +1,82 @@
|
||||
#ifndef VCOWPTR_H
|
||||
#define VCOWPTR_H
|
||||
|
||||
#include<assert.h>
|
||||
|
||||
template <typename T>
|
||||
class vcow_ptr {
|
||||
struct model {
|
||||
std::atomic<std::size_t> mRef{1};
|
||||
|
||||
model() = default;
|
||||
|
||||
template <class... Args>
|
||||
explicit model(Args&&... args) : mValue(std::forward<Args>(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 <class... Args>
|
||||
vcow_ptr(Args&&... args)
|
||||
: mModel(new model(std::forward<Args>(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
|
||||
Loading…
x
Reference in New Issue
Block a user