/*
* 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_eType(other.m_eType) {
*(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