Logo Search packages:      
Sourcecode: blender version File versions

MEM_RefCountPtr.h

Go to the documentation of this file.
/**
 * $Id: MEM_RefCountPtr.h,v 1.6 2002/12/30 12:11:02 maarten Exp $
 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
 *
 * This program 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. The Blender
 * Foundation also sells licenses for use in proprietary software under
 * the Blender License.  See http://www.blender.org/BL/ for information
 * about this.
 *
 * This program 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 this program; if not, write to the Free Software Foundation,
 * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
 * All rights reserved.
 *
 * The Original Code is: all of this file.
 *
 * Contributor(s): none yet.
 *
 * ***** END GPL/BL DUAL LICENSE BLOCK *****
 */
/**
 * @file    MEM_RefCountPtr.h
 * Declaration of MEM_RefCounted and MEM_RefCountable classes.
 * @author Laurence
 */

#ifndef NAN_INCLUDED_MEM_RefCountPtr_h
#define NAN_INCLUDED_MEM_RefCountPtr_h

#include <stdlib.h> // for NULL !

/**
 * @section MEM_RefCountable
 * This is a base class for reference countable objects.
 * If you want an object to be shared using a reference 
 * counted system derrivce from this class. All subclasses
 * should insist that they are created on the heap, this
 * can be done by makeing all constructors private and 
 * defining a static New() method that returns a ref counted
 * ptr to a new()ly allocated instance. 
 *
 * @section Example subclass
 *
 *
 * class MySharedObject : public MEM_RefCountable {
 *
 * private :
 *    MySharedObject() : MEM_RefCountable() { //class specific initialization};
 *  MySharedObject(const MySharedObject &other) // not implemented
 * public :
 *          static      
 *                MEM_RefCountPtr<MySharedObject> 
 *          New(
 *          ) {
 *                return MEM_RefCountPtr<MySharedObject>( new MySharedObject());
 *          }
 *          
 *          // other member functions
 * };
 *
 * Alternitively you may first wish to define a fully functional
 * class and then define a reference counting wrapper for this class.
 * This is useful when the base type can be used without reference
 * counting.
 *
 * E.g.
 * class UsefullClass {
 * private :
 *  ...
 * public :
 *
 *      UsefullClass()
 *      UsefullMethod(...)
 *      AnotherUsefullMethod(...)
 * };
 *
 * class RcUsefullClass : public UsefullClass, public MEM_RefCountable
 * {
 * private :
 *      // Override base class public constructor --- forces
 *      // use of New(...)
 *      RcUsefullClass(...)
 * public :
 *
 *  // Override each public constructor of UsefullClass with
 *  // an equivalent static New method returning a MEM_RefCountPtr
 *
 *  static
 *      MEM_RefCountPtr<RcUsefullClass>
 *  New(...){
 *       return MEM_RefCountPtr<RcUsefullClass> output(
 *           new UsefullClass(...)
 *       );
 *   }
 *
 *  // warning never call destructor directly allow ref counting
 *  // mechanism to handle object lifetime.
 *  ~RcUsefullClass();
 * };
 *
 *
 */

00114 class MEM_RefCountable {
private :

      /**
       * The reference count!
       * We use mutable here because we would like to
       * share references of const objects!
       * Maybe should think about having decRef()
       * another value because we should not be deleting
       * non-const objects
       */

00126       mutable int m_count;

protected :

      /**
       * Protected constructors
       * This class is not for direct instanciation. Sub classes
       * should only be allocated on the heap.
       */

00136       MEM_RefCountable (
      ) :
            m_count (0)
      {
      };

      MEM_RefCountable (
            const MEM_RefCountable & other
      ) :
            m_count (0)
      {
      }

public :

            void
      IncRef(
      ) const {
            m_count++;
      }

            int
      DecRef(
      ) {
            return (--m_count);
      }

      ~MEM_RefCountable(
      ) {
            //nothing to do
      }
};

/**
 * @section MEM_RefCountPtr
 */

template
      < class T >
00175 class MEM_RefCountPtr {

public :

      /**
       * Construction from reference - share ownership with
       * the right hand side.
       */

00184       MEM_RefCountPtr(
            const MEM_RefCountPtr &rhs
      ) : m_val (NULL) {
            ShareOwnership(rhs.m_val);
      }

      /**
       * Construction from ptr - this class shares
       * ownership of object val.
       */

00195       MEM_RefCountPtr(
            const T* val
      ) :
            m_val (NULL)
      {
            ShareOwnership(val);
      }

      /**
       * Default constructor
       */

00207       MEM_RefCountPtr(
      ) :
            m_val (NULL)
      {
      }

      /**
       * Type conversion from this class to the type
       * of a pointer to the template parameter.
       * This means you can pass an instance of this class
       * to a function expecting a ptr of type T.
       */

00220       operator T * () const {
            return m_val;
      }


      MEM_RefCountPtr & operator=(
            const MEM_RefCountPtr &rhs
      ) {
            if (this->m_val != rhs.m_val) {
                  ReleaseOwnership();
                  ShareOwnership(rhs.m_val);
            }
            return *this;
      }

      /**
       * Overload the operator -> so that it's possible to access
       * all the normal methods of the internal ptr.
       */

00240       T * operator->() const {
            return m_val;
      }

      /**
       * Returrn a reference to the shared object.
       */

            T&
00249       Ref(
      ) {
            return *m_val;
      }


      /**
       * Destructor - deletes object if it's ref count is zero.
       */

00259       ~MEM_RefCountPtr(
      ) {
            ReleaseOwnership();
      }

private :
      
      /// The ptr owned by this class.
00267       T * m_val;

            void
      ShareOwnership(
            const T * val
      ) {
            if (val != NULL) {
                  val->IncRef();
            }
            m_val = const_cast<T *>(val);
      }
            
            void
      ReleaseOwnership(
      ) {
            if (m_val) {
                  if (m_val->DecRef() == 0) {
                        delete(m_val);
                        m_val = NULL;
                  }
            }
      }

};

#endif


Generated by  Doxygen 1.6.0   Back to index