#ifndef _COWPTR_IMPL_H_ #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 template cow_ptr::cow_ptr(T *p, D d) : ptr_(p, d){} template cow_ptr::cow_ptr(const cow_ptr& cp){ ptr_ = cp.ptr_; } template cow_ptr& cow_ptr::operator = (const cow_ptr& cp){ if (this != &cp){ ptr_.decrease_ref(); ptr_ = cp.ptr_; } return *this; } template typename cow_ptr::element_type *cow_ptr::get(){ return ptr_.get(); } template const typename cow_ptr::element_type *cow_ptr::get()const{ return ptr_.get(); } template 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){ return cp1.ptr_ == cp2.ptr_; } template bool operator == (const cow_ptr& cp, nullptr_t p){ return cp.ptr_ == p; } template bool operator == (nullptr_t p, const cow_ptr& cp){ return cp == p; } template bool operator != (const cow_ptr& cp1, const cow_ptr& cp2){ return !(cp1 == cp2); } template bool operator != (const cow_ptr& cp, nullptr_t p){ return !(cp == p); } template bool operator != (nullptr_t p, const cow_ptr& cp){ return !(cp == p); } } #endif