diff --git a/TinySTL/COWPtr.h b/TinySTL/COWPtr.h index fd23cfc..9b22626 100644 --- a/TinySTL/COWPtr.h +++ b/TinySTL/COWPtr.h @@ -4,10 +4,33 @@ #include "Memory.h" namespace TinySTL{ + template + class cow_ptr; + namespace Detail{ + template + class proxy{ + public: + explicit proxy(cow_ptr *const cp) :cp_(cp){} + proxy(const proxy&) = default; + proxy& operator = (const proxy&) = default; + + const T& operator *()const; + T& operator *(); + const T *operator ->()const; + T *operator ->(); + cow_ptr& operator = (const T& val); + operator T()const; + private: + cow_ptr *cp_; + }; + } template class cow_ptr{ public: typedef T element_type; + private: + template + using proxy = Detail::proxy < _T > ; public: explicit cow_ptr(T *p = nullptr); template @@ -15,13 +38,12 @@ namespace TinySTL{ cow_ptr(const cow_ptr& cp); cow_ptr& operator = (const cow_ptr& cp); - - const element_type& operator *()const; - const element_type *operator ->()const; - //注意 这两个函数可能会改变指针指向的对象的内容,需要cow机制 - //element_type& operator *(); - //element_type *operator ->(); - + + const proxy operator *()const; + proxy operator *(); + const proxy operator ->()const; + proxy operator ->(); + element_type *get(); const element_type *get()const; @@ -41,6 +63,9 @@ namespace TinySTL{ friend bool operator != (const cow_ptr& cp, nullptr_t p); template friend bool operator != (nullptr_t p, const cow_ptr& cp); + + template + friend class Detail::proxy; }; } diff --git a/TinySTL/Detail/COWPtr.impl.h b/TinySTL/Detail/COWPtr.impl.h index 0010a1a..fad4eb1 100644 --- a/TinySTL/Detail/COWPtr.impl.h +++ b/TinySTL/Detail/COWPtr.impl.h @@ -2,6 +2,35 @@ #define _COWPTR_IMPL_H_ namespace TinySTL{ + namespace Detail{ + template + const T& proxy::operator *()const{ + return *(cp_->ptr_); + } + template + T& proxy::operator *(){ + auto t = *(cp_->ptr_); + cp_->ptr_ = make_shared(t); + return *(cp_->ptr_); + } + template + const T *proxy::operator ->()const{ + return cp_->ptr_.operator->(); + } + template + T *proxy::operator ->(){ + auto t = *(cp_->ptr_); + cp_->ptr_ = make_shared(t); + return cp_->ptr_.operator->(); + } + template + cow_ptr& proxy::operator = (const T& val){ + cp_->ptr_ = make_shared(val); + return *cp_; + } + template + proxy::operator T()const{ return *(cp_->ptr_); } + } template cow_ptr::cow_ptr(T *p = nullptr) :ptr_(p){} template @@ -20,19 +49,6 @@ namespace TinySTL{ return *this; } template - const typename cow_ptr::element_type& cow_ptr::operator *()const{ - return *ptr_; - } - template - const typename cow_ptr::element_type *cow_ptr::operator ->()const{ - return ptr_.operator->(); - } - //注意 这两个函数可能会改变指针指向的对象的内容,需要cow机制 - //template - //typename cow_ptr::element_type& cow_ptr::operator *(); - //template - //typename cow_ptr::element_type *cow_ptr::operator ->(); - template typename cow_ptr::element_type *cow_ptr::get(){ return ptr_.get(); } @@ -44,6 +60,22 @@ namespace TinySTL{ cow_ptr::operator bool()const{ return ptr_ != nullptr; } + template + const typename cow_ptr::proxy cow_ptr::operator *()const{ + return proxy(const_cast(this)); + } + template + typename cow_ptr::proxy cow_ptr::operator *(){ + return proxy(this); + } + template + const typename cow_ptr::proxy cow_ptr::operator ->()const{ + return proxy(const_cast(this)); + } + template + typename cow_ptr::proxy cow_ptr::operator ->(){ + return proxy(this); + } template bool operator == (const cow_ptr& cp1, const cow_ptr& cp2){