// This file may be redistributed and modified only under the terms of
// the GNU Lesser General Public License (See COPYING for details).
// Copyright (C) 2000 Aloril
// Copyright (C) 2000-2005 Al Riddoch
#ifndef ATLAS_OBJECTS_SMARTPTR_H
#define ATLAS_OBJECTS_SMARTPTR_H
#include <Atlas/Exception.h>
namespace Atlas { namespace Objects {
class NullSmartPtrDereference : public Atlas::Exception
{
public:
NullSmartPtrDereference() : Atlas::Exception("Null SmartPtr dereferenced") {}
virtual ~NullSmartPtrDereference() throw ();
};
template <class T>
class SmartPtr
{
public:
typedef T DataT;
typedef typename T::iterator iterator;
typedef typename T::const_iterator const_iterator;
SmartPtr() : ptr(T::alloc()) {
}
SmartPtr(const SmartPtr<T>& a) : ptr(a.get()) {
incRef();
}
SmartPtr(T *a_ptr) : ptr(a_ptr)
{
incRef();
}
template<class oldType>
explicit SmartPtr(const SmartPtr<oldType>& a) : ptr(a.get()) {
}
~SmartPtr() {
decRef();
}
SmartPtr& operator=(const SmartPtr<T>& a) {
if (a.get() != this->get()) {
decRef();
ptr = a.get();
incRef();
}
return *this;
}
template<class newType>
operator SmartPtr<newType>() const {
return SmartPtr<newType>(ptr);
}
template<class newType>
operator SmartPtr<const newType>() const {
return SmartPtr<const newType>(ptr);
}
bool isValid() const {
return ptr != 0;
}
T& operator*() const {
if (ptr == 0) {
throw NullSmartPtrDereference();
}
return *ptr;
}
T* operator->() const {
if (ptr == 0) {
throw NullSmartPtrDereference();
}
return ptr;
}
T* get() const {
return ptr;
}
SmartPtr<T> copy() const
{
SmartPtr<T> ret = SmartPtr(ptr->copy());
ret.decRef();
return ret;
}
SmartPtr<T> getDefaultObject() const
{
return SmartPtr(ptr->getDefaultObject());
}
// If you want to make these protected, please ensure that the
// detructor is made virtual to ensure your new class bahaves
// correctly.
private:
void decRef() const {
if (ptr != 0) {
ptr->decRef();
}
}
void incRef() const {
if (ptr != 0) {
ptr->incRef();
}
}
T * ptr;
};
template<typename returnPtrType, class fromType>
returnPtrType smart_dynamic_cast(const SmartPtr<fromType> & o)
{
return returnPtrType(dynamic_cast<typename returnPtrType::DataT*>(o.get()));
}
template<typename returnPtrType, class fromType>
returnPtrType smart_static_cast(const SmartPtr<fromType> & o)
{
return returnPtrType((typename returnPtrType::DataT *)o.get());
}
} } // namespace Atlas::Objects
#endif // ATLAS_OBJECTS_SMARTPTR_H
syntax highlighted by Code2HTML, v. 0.9.1