diff options
Diffstat (limited to 'include/mts/MTS_SharedPtr.h')
-rw-r--r-- | include/mts/MTS_SharedPtr.h | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/include/mts/MTS_SharedPtr.h b/include/mts/MTS_SharedPtr.h new file mode 100644 index 0000000..0fd670e --- /dev/null +++ b/include/mts/MTS_SharedPtr.h @@ -0,0 +1,137 @@ +/* + * 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 <http://www.gnu.org/licenses/>. + * + */ + +/*! \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 T> 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<T>& other); //!< Constructs from another shared pointer, increasing reference count + ~SharedPtr(); //!< Destructs the AutoPtr deleting T + + SharedPtr<T>& operator=(const SharedPtr<T>& 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<class T> SharedPtr<T>::SharedPtr(T* ptr, MallocType type) + : m_pObj(ptr), m_pReferences(new int(1)), m_eType(type) { + } + + template<class T> SharedPtr<T>::SharedPtr(const SharedPtr<T>& other) + : m_pObj(other.m_pObj), m_pReferences(other.m_pReferences) { + *(m_pReferences) += 1; + } + + template<class T> SharedPtr<T>::~SharedPtr() { + release(); + } + + template<class T> SharedPtr<T>& SharedPtr<T>::operator=( + const SharedPtr<T>& 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<class T> T& SharedPtr<T>::operator*() const { + return *m_pObj; + } + + template<class T> T* SharedPtr<T>::operator->() const { + return m_pObj; + } + + template<class T> T& SharedPtr<T>::operator[](const uint32_t& index) const { + return m_pObj[index]; + } + + template<class T> T* SharedPtr<T>::get() const { + return m_pObj; + } + + template<class T> bool SharedPtr<T>::isNull() const { + return (m_pObj == 0); + } + + template<class T> bool SharedPtr<T>::isShared() const { + return ((*m_pReferences) > 1); + } + + template<class T> int SharedPtr<T>::count() const { + return (*m_pReferences); + } + + template<class T> void SharedPtr<T>::release() { + (*m_pReferences) -= 1; + if ((*m_pReferences) == 0) { + if (m_eType == SINGLE) { + delete m_pObj; + } else { + delete[] m_pObj; + } + delete m_pReferences; + } + } +} + +#endif |