#include<bits/stdc++.h>
#include <unistd.h>
using namespace std;
namespace smart_pointer
{
template<typename T>
class SharedPtr{
public:
SharedPtr();
SharedPtr(T *ptr);
SharedPtr(const SharedPtr &sp);
SharedPtr(SharedPtr &&sp);
~SharedPtr();
T* operator ->() const {return ptr;};
T& operator *() const {return *ptr;};
SharedPtr & operator =(const SharedPtr &sp);
SharedPtr & operator =(SharedPtr &&sp);
void reset(T *ptr);
void swap(SharedPtr &sp);
int use_count()const {return *cnt;}
private:
atomic<int> *cnt;
T *ptr;
void defaultDelete(){
if(ptr){
delete ptr;
delete cnt;
ptr=nullptr;
cnt=nullptr;
}
};
};
template<typename T>
SharedPtr<T>::SharedPtr():ptr(nullptr),cnt(nullptr){}
template<typename T>
SharedPtr<T>::SharedPtr(T *_ptr):ptr(_ptr),cnt(new atomic<int>(1)){}
template<typename T>
SharedPtr<T>::SharedPtr(const SharedPtr &sp):ptr(sp.ptr),cnt(sp.cnt){
(*cnt)++;
}
template<typename T>
SharedPtr<T>::~SharedPtr(){
if(ptr){
--(*cnt);
if(*cnt<=0){
defaultDelete();
cout<<" delete shared_ptr"<<endl;
}
}
}
template<typename T>
SharedPtr<T> & SharedPtr<T>::operator=(const SharedPtr &sp){
if(sp.ptr==ptr) return *this;
if(ptr!=nullptr){
(*cnt)--;
if(*cnt==0){
this->defaultDelete();
}
}
ptr = sp.ptr;
cnt = sp.cnt;
if(cnt) (*cnt)++;
return *this;
}
template<typename T>
void SharedPtr<T>::swap(SharedPtr &sp){
std::swap(ptr,sp.ptr);
std::swap(cnt,sp.cnt);
}
template<typename T>
SharedPtr<T>::SharedPtr(SharedPtr &&sp){
sp.swap(*this);
}
template<typename T>
SharedPtr<T> & SharedPtr<T>::operator=(SharedPtr &&sp){
sp.swap(*this);
return *this;
}
};
namespace smart_pointer
{
template<typename T>
class SharedPtr{
public:
SharedPtr():ptr(nullptr),cnt(nullptr){}
SharedPtr(T *_ptr):ptr(_ptr),cnt(new atomic<int>(1)){}
SharedPtr(const SharedPtr &sp):ptr(sp.ptr),cnt(sp.cnt){
(*cnt)++;
}
SharedPtr(SharedPtr &&sp){
sp.swap(*this);
}
~SharedPtr(){
if(ptr){
--(*cnt);
if(*cnt<=0){
defaultDelete();
cout<<" delete SharedPtr"<<endl;
}
}
}
T* operator ->() const {return ptr;}
T& operator *() const {return *ptr;}
SharedPtr & operator =(const SharedPtr &sp){
if(sp.ptr==ptr) return *this;
if(ptr!=nullptr){
(*cnt)--;
if(*cnt==0){
this->defaultDelete();
}
}
ptr = sp.ptr;
cnt = sp.cnt;
if(cnt) (*cnt)++;
return *this;
}
SharedPtr & operator =(SharedPtr &&sp){
sp.swap(*this);
return *this;
}
void swap(SharedPtr &sp){
std::swap(ptr,sp.ptr);
std::swap(cnt,sp.cnt);
}
int use_count()const {return *cnt;}
private:
atomic<int> *cnt;
T *ptr;
void defaultDelete(){
if(ptr){
delete ptr;
delete cnt;
ptr=nullptr;
cnt=nullptr;
}
}
};
};