summaryrefslogtreecommitdiff
path: root/include/mts/MTS_SharedPtr.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/mts/MTS_SharedPtr.h')
-rw-r--r--include/mts/MTS_SharedPtr.h137
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