/* * Copyright (C) 2015 by Multi-Tech Systems * * This file is part of libmts. * * libmts is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * libmts is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libmts. If not, see . * */ /*! \file MTS_SharedPtr.h \brief A shared pointer template \date 15JUN11 \author Sean Godinez A shared pointer template */ #ifndef _MTS_SHAREDPTR_H #define _MTS_SHAREDPTR_H namespace MTS { //! A shared pointer /*! A shared pointer keeps track of references and cleans up when the reference count reaches zero */ template class SharedPtr { public: enum MallocType { SINGLE, ARRAY }; explicit SharedPtr(T* ptr = 0, MallocType type = SINGLE); //!< Explicitly Constructs the SharedPtr to reference ptr SharedPtr(const SharedPtr& other); //!< Constructs from another shared pointer, increasing reference count ~SharedPtr(); //!< Destructs the AutoPtr deleting T SharedPtr& operator=(const SharedPtr& other); //!< Releases *this and shares other's T T& operator*() const; //!< Returns T T* operator->() const; //!< Returns address of T T& operator[](const uint32_t& index) const; //!< Returns T at index T* get() const; //!< Returns address of T bool isNull() const; //!< Returns true if pointer is NULL bool isShared() const; //!< Returns true if reference count is greater than 1 int count() const; //!< Returns number of references private: T* m_pObj; //!< Reference to class T int* m_pReferences; //!< Reference to reference count MallocType m_eType; //!< Describes memory allocated as a single T or block of Ts void release(); }; template SharedPtr::SharedPtr(T* ptr, MallocType type) : m_pObj(ptr), m_pReferences(new int(1)), m_eType(type) { } template SharedPtr::SharedPtr(const SharedPtr& other) : m_pObj(other.m_pObj), m_pReferences(other.m_pReferences) { *(m_pReferences) += 1; } template SharedPtr::~SharedPtr() { release(); } template SharedPtr& SharedPtr::operator=( const SharedPtr& other) { if (&other != this) { release(); this->m_pObj = other.m_pObj; this->m_pReferences = other.m_pReferences; this->m_eType = other.m_eType; (*m_pReferences) += 1; } return *this; } template T& SharedPtr::operator*() const { return *m_pObj; } template T* SharedPtr::operator->() const { return m_pObj; } template T& SharedPtr::operator[](const uint32_t& index) const { return m_pObj[index]; } template T* SharedPtr::get() const { return m_pObj; } template bool SharedPtr::isNull() const { return (m_pObj == 0); } template bool SharedPtr::isShared() const { return ((*m_pReferences) > 1); } template int SharedPtr::count() const { return (*m_pReferences); } template void SharedPtr::release() { (*m_pReferences) -= 1; if ((*m_pReferences) == 0) { if (m_eType == SINGLE) { delete m_pObj; } else { delete[] m_pObj; } delete m_pReferences; } } } #endif