提交 3b0afae3 编写于 作者: Y Yang Yu

Add more comments

上级 bdc82956
...@@ -25,13 +25,14 @@ class ThreadUnsafeOwnershipFlags { ...@@ -25,13 +25,14 @@ class ThreadUnsafeOwnershipFlags {
public: public:
ThreadUnsafeOwnershipFlags(bool flag) : flag_(flag) {} ThreadUnsafeOwnershipFlags(bool flag) : flag_(flag) {}
ThreadUnsafeOwnershipFlags(const ThreadUnsafeOwnershipFlags& o) = delete; ThreadUnsafeOwnershipFlags(const ThreadUnsafeOwnershipFlags& other) = delete;
ThreadUnsafeOwnershipFlags& operator=(const ThreadUnsafeOwnershipFlags& o) = ThreadUnsafeOwnershipFlags& operator=(
delete; const ThreadUnsafeOwnershipFlags& other) = delete;
ThreadUnsafeOwnershipFlags(ThreadUnsafeOwnershipFlags&& o) = default; ThreadUnsafeOwnershipFlags(ThreadUnsafeOwnershipFlags&& other) = default;
void SetOwnership(bool flag) { flag_ = flag; } void SetOwnership(bool flag) { flag_ = flag; }
// Invoke the callback if it is not owned.
template <typename Callback> template <typename Callback>
void AcquireOwnershipOnce(Callback acquire) { void AcquireOwnershipOnce(Callback acquire) {
if (!flag_) { if (!flag_) {
...@@ -44,7 +45,7 @@ class ThreadUnsafeOwnershipFlags { ...@@ -44,7 +45,7 @@ class ThreadUnsafeOwnershipFlags {
bool flag_; bool flag_;
}; };
// Copy On Write pointer. // Copy-On-Write pointer.
// It will hold a T* pointer, and only copy once when `MutableData` is invoked. // It will hold a T* pointer, and only copy once when `MutableData` is invoked.
// //
// The template parameter OwnershipFlags should have: // The template parameter OwnershipFlags should have:
...@@ -52,6 +53,8 @@ class ThreadUnsafeOwnershipFlags { ...@@ -52,6 +53,8 @@ class ThreadUnsafeOwnershipFlags {
// * SetOwnership(bool flag). // * SetOwnership(bool flag).
// * AcquireOwnershipOnce(Callback). It will invoke the callback if it is not // * AcquireOwnershipOnce(Callback). It will invoke the callback if it is not
// owned. // owned.
//
// https://en.wikipedia.org/wiki/Copy-on-write
template <typename T, typename OwnershipFlags = ThreadUnsafeOwnershipFlags> template <typename T, typename OwnershipFlags = ThreadUnsafeOwnershipFlags>
class COWPtr { class COWPtr {
public: public:
...@@ -59,33 +62,34 @@ class COWPtr { ...@@ -59,33 +62,34 @@ class COWPtr {
explicit COWPtr(T* ptr) : payload_(ptr), ownership_{true} {} explicit COWPtr(T* ptr) : payload_(ptr), ownership_{true} {}
// Move methods. Steal ownership from origin // Move methods. Steal ownership from origin
COWPtr(COWPtr&& o) COWPtr(COWPtr&& other)
: payload_(o.payload_), ownership_{std::move(o.ownership_)} {} : payload_(other.payload_), ownership_{std::move(other.ownership_)} {}
COWPtr& operator=(COWPtr&& origin) = default; COWPtr& operator=(COWPtr&& origin) = default;
// Copy methods. Not own payload // Copy methods. Not own payload
COWPtr(const COWPtr& o) : payload_(o.payload_), ownership_{false} {} COWPtr(const COWPtr& other) : payload_(other.payload_), ownership_{false} {}
COWPtr& operator=(const COWPtr& o) { COWPtr& operator=(const COWPtr& other) {
payload_ = o.payload_; payload_ = other.payload_;
ownership_.SetOwnership(false); ownership_.SetOwnership(false);
return *this; return *this;
} }
// Access read only data.
const T& Data() const { return *payload_; } const T& Data() const { return *payload_; }
// Access mutable data. If the data is not owned, the data will be copied
// before.
T* MutableData() { T* MutableData() {
ownership_.AcquireOwnershipOnce( ownership_.AcquireOwnershipOnce(
[this] { payload_.reset(new T(*payload_)); }); [this] { payload_.reset(new T(*payload_)); });
return payload_.get(); return payload_.get();
} }
void Reset() {
ownership_.AcquireOwnershipOnce([this] { payload_.reset(); });
payload_.reset(new T());
}
private: private:
// Actual data pointer.
std::shared_ptr<T> payload_; std::shared_ptr<T> payload_;
// Ownership flag.
OwnershipFlags ownership_; OwnershipFlags ownership_;
}; };
......
...@@ -28,10 +28,6 @@ TEST(COWPtr, all) { ...@@ -28,10 +28,6 @@ TEST(COWPtr, all) {
*ptr2.MutableData() = 10; *ptr2.MutableData() = 10;
ASSERT_EQ(ptr.Data(), 0); ASSERT_EQ(ptr.Data(), 0);
ASSERT_EQ(ptr2.Data(), 10); ASSERT_EQ(ptr2.Data(), 10);
auto ptr_before = ptr2.MutableData();
ptr2.Reset();
ASSERT_NE(ptr2.MutableData(), ptr_before);
} }
} // namespace details } // namespace details
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册