/* Copyright (C) 2001-2006, William Joseph. All Rights Reserved. This file is part of GtkRadiant. GtkRadiant is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. GtkRadiant 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 General Public License for more details. You should have received a copy of the GNU General Public License along with GtkRadiant; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #if !defined( INCLUDED_GENERIC_REFERENCECOUNTED_H ) #define INCLUDED_GENERIC_REFERENCECOUNTED_H /// \file /// \brief 'smart' pointers and references. #include template class IncRefDecRefCounter { public: void increment( Type& value ){ value.IncRef(); } void decrement( Type& value ){ value.DecRef(); } }; /// \brief A smart-pointer that uses a counter stored in the object pointed-to. template > class SmartPointer : public Counter { Type* m_value; public: SmartPointer( const SmartPointer& other ) : m_value( other.m_value ){ Counter::increment( *m_value ); } explicit SmartPointer( Type* value ) : m_value( value ){ Counter::increment( *m_value ); } ~SmartPointer(){ Counter::decrement( *m_value ); } SmartPointer& operator=( const SmartPointer& other ){ SmartPointer temp( other ); temp.swap( *this ); return *this; } SmartPointer& operator=( Type* value ){ SmartPointer temp( value ); temp.swap( *this ); return *this; } void swap( SmartPointer& other ){ std::swap( m_value, other.m_value ); } operator Type*() const { return m_value; } Type& operator*() const { return *m_value; } Type* operator->() const { return m_value; } Type* get() const { return m_value; } }; template inline bool operator<( const SmartPointer& self, const SmartPointer& other ){ return self.get() < other.get(); } template inline bool operator==( const SmartPointer& self, const SmartPointer& other ){ return self.get() == other.get(); } template inline bool operator!=( const SmartPointer& self, const SmartPointer& other ){ return !::operator==( self, other ); } namespace std { /// \brief Swaps the values of \p self and \p other. /// Overloads std::swap(). template inline void swap( SmartPointer& self, SmartPointer& other ){ self.swap( other ); } } /// \brief A smart-reference that uses a counter stored in the object pointed-to. template > class SmartReference : public Counter { Type* m_value; public: SmartReference( const SmartReference& other ) : m_value( other.m_value ){ Counter::increment( *m_value ); } explicit SmartReference( Type& value ) : m_value( &value ){ Counter::increment( *m_value ); } ~SmartReference(){ Counter::decrement( *m_value ); } SmartReference& operator=( const SmartReference& other ){ SmartReference temp( other ); temp.swap( *this ); return *this; } SmartReference& operator=( Type& value ){ SmartReference temp( value ); temp.swap( *this ); return *this; } void swap( SmartReference& other ){ std::swap( m_value, other.m_value ); } operator Type&() const { return *m_value; } Type& get() const { return *m_value; } Type* get_pointer() const { return m_value; } }; template inline bool operator<( const SmartReference& self, const SmartReference& other ){ return self.get() < other.get(); } template inline bool operator==( const SmartReference& self, const SmartReference& other ){ return self.get() == other.get(); } template inline bool operator!=( const SmartReference& self, const SmartReference& other ){ return !::operator==( self, other ); } namespace std { /// \brief Swaps the values of \p self and \p other. /// Overloads std::swap(). template inline void swap( SmartReference& self, SmartReference& other ){ self.swap( other ); } } #endif