Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<atomic>
- #include<iostream>
- namespace cs540
- {
- static int refcount2;
- void dummy(void * a)
- {
- }
- template <class T> void DefaultDeleter(void* p)
- { delete static_cast<T*>(p);}
- template<typename T>
- class Sptr
- {
- public:
- /*template<typename U, typename V>
- Sptr(Sptr<U>* op, V deleterFunction)
- {
- if(op!=nullptr)
- {
- refcount = op->refcount;
- refcount->fetch_add(1);
- d = deleterFunction;
- if(dynamic_cast<T*>(op))
- obj=dynamic_cast<T*>(op);
- }
- else
- {
- refcount=new std::atomic<int>(1);
- refcount2++;
- d = &dummy;
- obj = nullptr;
- }
- std::cout<<"template<typename U, typename V>Sptr(Sptr<U>* op, V deleterFunction)"<<std::endl;
- }*/
- template<typename U, typename V>
- Sptr(Sptr<U>* op, V deleterFunction)
- {
- if(op!=nullptr || op->obj==nullptr && (obj!=nullptr))
- {
- if(refcount->fetch_sub(1)-1==0)
- {
- d(obj);
- obj = nullptr;
- refcount = nullptr;
- refcount2--;
- }
- refcount2++;
- refcount = op->refcount;
- refcount->fetch_add(1);
- d = deleterFunction;
- //if(dynamic_cast<T*>(op))
- //obj=dynamic_cast<T*>(op);
- obj = op->obj;
- }
- else
- {
- refcount=new std::atomic<int>(1);
- refcount2++;
- d = &dummy;
- obj = nullptr;
- }
- std::cout<<"template<typename T, typename V>Sptr(Sptr<T>* op, V deleterFunction)"<<std::endl;
- }
- public:
- void (*d)(void *);
- T* obj;
- std::atomic<int>* refcount;
- // Sptr(const Sptr&) = delete;
- template<typename U>
- //Sptr(const Sptr<U>&) = delete;
- Sptr() = delete;
- Sptr(const Sptr &o): obj(nullptr), Sptr(const_cast<Sptr*>(&o),o.d)
- {
- std::cout<<"Non-templated"<<std::endl;
- }
- Sptr()
- {
- refcount2++;
- refcount = new std::atomic<int>(1);
- d = &dummy;
- obj = nullptr;
- }
- /*
- template<typename U>
- Sptr(const Sptr<U>& a)
- {
- T* b = reinterpret_cast<T*>(a.obj);
- if(b!=nullptr)
- {
- this->obj = b;
- this->refcount = a.refcount;
- refcount->fetch_add(1);
- this->d = a.d;
- }
- std::cout<<"template<typename U> Sptr(const Sptr<U>& a)"<<std::endl;
- }*/
- Sptr(T* obj)
- {
- refcount2++;
- refcount = new std::atomic<int>(1);
- this->obj = obj;
- d = &DefaultDeleter<T>;
- std::cout<<"Default ctor. this is a test message"<<std::endl;
- }
- template<typename U>
- Sptr(U* obj)
- {
- this->obj = obj;
- refcount2++;
- refcount = new std::atomic<int>(1);
- d = &DefaultDeleter<U>;
- std::cout<<"Sptr<U> ctor"<<std::endl;
- }
- template <typename U> Sptr &operator=(const Sptr<U> & a)
- {
- if((long)this !=(long)&a)
- {
- if(this->obj == nullptr)
- {
- this->obj = a.obj;
- this->refcount = a.refcount;
- refcount->fetch_add(1);
- this->d = a.d;
- }
- else if(refcount->fetch_sub(1)==0)
- {
- a.d(a.obj);
- }
- }
- std::cout<<"template <typename U> Sptr &operator=(const Sptr<U> & a)"<<std::endl;
- return *this;
- }
- Sptr &operator=(const Sptr a)
- {
- if((long)this !=(long)&a)
- {
- if(this->obj == nullptr)
- {
- this->obj = a.obj;
- this->refcount = a.refcount;
- refcount->fetch_add(1);
- this->d = a.d;
- }
- else if(refcount->fetch_sub(1)==0)
- {
- a.d(a.obj);
- }
- }
- std::cout<<"Sptr &operator=(const Sptr & a)"<<std::endl;
- return *this;
- }
- void reset()
- {
- if(refcount->fetch_sub(1)=0)
- {
- //delete obj;
- d(obj);
- //free(obj);
- }
- obj = nullptr;
- }
- T &operator*() const
- {
- return *obj;
- }
- T *operator->() const
- {
- return obj;
- }
- T *get() const
- {
- return obj;
- }
- explicit operator bool() const
- {
- std::cout<<"bool"<<std::endl;
- return obj!=nullptr;
- }
- ~Sptr()
- {
- if(*refcount<1 || refcount2<1)
- std::cout<<"ERROROROROROROR"<<std::endl;
- if(refcount->fetch_sub(1)==0)
- {
- refcount2--;
- d((void*)obj);
- delete refcount;
- refcount = nullptr;
- obj = nullptr;
- std::cout<<refcount2<<std::endl;
- }
- }
- };
- template <typename T1, typename T2>
- bool operator==(const Sptr<T1> &a, const Sptr<T2> &b)
- {
- if(!a&& !b)
- return true;
- else if(a && b)
- {
- return a.get()==b.get();
- }
- else return false;
- }
- template <typename T, typename U>
- Sptr<T> static_pointer_cast(const Sptr<U> &sp)
- {
- return Sptr<T>(sp);
- }
- template <typename T, typename U>
- Sptr<T> dynamic_pointer_cast(const Sptr<U> &sp)
- {
- return Sptr<T>(dynamic_cast<T*>(sp.get()));
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement