From be5ecc883a2ea8bc5ed5a2e7fd02a9bcee6339e3 Mon Sep 17 00:00:00 2001 From: Samer Afach Date: Fri, 31 Mar 2017 14:56:22 +0200 Subject: [PATCH] First commit --- main.cpp | 180 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100644 main.cpp diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..8862c2f --- /dev/null +++ b/main.cpp @@ -0,0 +1,180 @@ +#include +#include +#include + +/** + * Simple shared pointer class with NO thread safety (not even the counter is thread-safe) + */ +template +class SharedPtr +{ + //Rule 1: tracker is always NULL when ptr == NULL + //Rule 2: ID is only assigned in constructors + + typedef std::map*> IDMap; + typedef std::pair*> IDPair; + + T* ptr; + IDMap *tracker; //track pointers to same object + unsigned long ID; + static unsigned long __IDCounter; + +public: + typedef T element_type; + SharedPtr(const SharedPtr& other); + SharedPtr& operator=(const SharedPtr& other); + SharedPtr(T* new_ptr = NULL); + ~SharedPtr(); + unsigned long use_count() const; + operator bool(); + T* const get(); + T* release(); + void reset(T* new_ptr = NULL); + inline bool isNull(); +}; + +template +unsigned long SharedPtr::__IDCounter = 0; + +template +SharedPtr::SharedPtr(const SharedPtr &other) +{ + this->tracker = other.tracker; + this->ptr = other.ptr; + this->ID = __IDCounter++; + if(!isNull()) + tracker->insert(IDPair(ID,this)); +} + +template +SharedPtr &SharedPtr::operator=(const SharedPtr &other) +{ + this->tracker = other.tracker; + this->ptr = other.ptr; + this->ID = __IDCounter++; + if(!isNull()) + tracker->insert(IDPair(ID,this)); + return *this; +} + +template +SharedPtr::SharedPtr(T *new_ptr) +{ + ptr = NULL; + tracker = NULL; + ID = __IDCounter++; + reset(new_ptr); +} + +template +SharedPtr::~SharedPtr() +{ + reset(); +} + +template +unsigned long SharedPtr::use_count() const +{ + if(isNull()) + return 0; + else + return tracker->size(); +} + +template +SharedPtr::operator bool() +{ + return !isNull(); +} + +template +T * const SharedPtr::get() +{ + return ptr; +} + +template +T *SharedPtr::release() +{ + T* ret_ptr = ptr; + if(!isNull()) { + IDMap* trackerHolder = tracker; + for(typename IDMap::iterator it = trackerHolder->begin(); it != trackerHolder->end(); it++) + { + it->second->ptr = NULL; + it->second->tracker = NULL; + } + delete trackerHolder; + } + return ret_ptr; +} + +template +void SharedPtr::reset(T *new_ptr) { + if(!isNull()) + { + //ptr and tracker are not NULL, guaranteed + if(tracker->size() == 1) //this is the last reference + { + delete ptr; + ptr = NULL; + delete tracker; + tracker = NULL; + } + else + { + tracker->erase(ID); + if(new_ptr != NULL) + { + tracker = new IDMap; + tracker->insert(IDPair(ID,this)); + } + else + { + tracker = NULL; + ptr = NULL; + } + } + } + else //if this is NULL + { + if(new_ptr != NULL) + { + if(tracker == NULL) { + tracker = new IDMap; + tracker->insert(IDPair(ID,this)); + ptr = new_ptr; + } + } + } +} + +template +bool SharedPtr::isNull() +{ + return (ptr == NULL); +} + +int main() +{ + SharedPtr s; + SharedPtr x = SharedPtr(new int(5)); + std::vector > myvec; + for(long i = 0; i < 100; i++) + { + myvec.push_back(x); + } + SharedPtr y(x); + s = x; + std::cout<<*x.get()< R = SharedPtr(new int(15)); + std::cout<<*R.get()< T = SharedPtr(new int(25)); + SharedPtr U(T); + std::cout<<*U.get()<