/* * Copyright (c) 2004, Nate Nielsen * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the * above copyright notice, this list of conditions and * the following disclaimer in the documentation and/or * other materials provided with the distribution. * * The names of contributors to this software may not be * used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. * * * CONTRIBUTORS * Nate Nielsen * */ #ifndef __REFERENCE_H__ #define __REFERENCE_H__ /* * Reference * * A basic reference counting pointer */ template class Reference { public: Reference() { m_ptr = NULL; } Reference(C* ptr) { m_ptr = ptr; addref(); } Reference(C* ptr, bool addr) { m_ptr = ptr; if(addr) addref(); } ~Reference() { release(); } Reference(const Reference& orig) { m_ptr = orig.m_ptr; addref(); } Reference& operator=(const C* ptr) { C* old = m_ptr; m_ptr = (C*)ptr; addref(); if(old) old->release(); return *this; } Reference& operator=(const Reference& orig) { return operator=(orig.m_ptr); } void attach(C* ptr) { release(); m_ptr = ptr; } C* detach() { C* ptr = m_ptr; m_ptr = NULL; return ptr; } operator C*() const { return m_ptr; } C* operator->() const { return m_ptr; } #if 0 operator bool() const { return m_ptr != NULL; } #endif void release() { if(m_ptr) m_ptr->release(); m_ptr = NULL; } void addref() { if(m_ptr) m_ptr->addRef(); } private: C* m_ptr; }; /* * Instance * * A basic reference counted object. */ class Instance { public: Instance() { m_x = 0; } virtual ~Instance() { } void addRef() { m_x++; } void release() { if((--m_x) <= 0) delete this; } private: // The reference count int m_x; }; #endif //__REFERENCE_H__