/* Copyright 2019 The Mathworks, Inc. */ #pragma once #include #include // Custom shared intrusive pointer. Counts the number of items pointing to an object // without storing a separate reference count. Requires the corresponding object to // store a field called "referenceCount" as well as friend this class. namespace coder { template class shared_ptr { public: explicit shared_ptr(T* p = nullptr); shared_ptr(const shared_ptr& sp); unsigned int use_count(); T* get() const; bool unique() const; ~shared_ptr(); shared_ptr& operator=(shared_ptr rhs); shared_ptr& operator=(T* rhs); T& operator*() const; T* operator->() const; friend void swap(shared_ptr& lhs, shared_ptr& rhs) { using std::swap; swap(lhs.fPtr, rhs.fPtr); } private: T* fPtr; }; template shared_ptr::shared_ptr(T* p) : fPtr(p) { if (fPtr != nullptr) { fPtr->referenceCount++; } } template shared_ptr::shared_ptr(const shared_ptr& sp) : fPtr(sp.fPtr) { if (fPtr) { fPtr->referenceCount++; } } template shared_ptr& shared_ptr::operator=(shared_ptr rhs) { swap(*this, rhs); return *this; } template shared_ptr& shared_ptr::operator=(T* rhs) { shared_ptr temp(rhs); *this = temp; return *this; } template T& shared_ptr::operator*() const { return *fPtr; } template T* shared_ptr::operator->() const { return fPtr; } // returns the number of pointers pointing to this object template unsigned int shared_ptr::use_count() { return fPtr->referenceCount; } // returns the object template T* shared_ptr::get() const { return fPtr; } // checks whether this is the only pointer pointing to this object template bool shared_ptr::unique() const { return fPtr->referenceCount == 1; } // if there are no more pointers pointing to this object, delete the object template shared_ptr::~shared_ptr() { if (fPtr != nullptr) { fPtr->referenceCount--; if (fPtr->referenceCount == 0) { delete fPtr; } } } template shared_ptr make_shared() { return shared_ptr(new T()); } } // namespace coder