/**
 * Multi-thread safe reference counting for OpenClass
 *
 * @author Laura Werner
 *
 * @package Utilities
 *
 * @copyright
 *      IBM Open Class Library
 *      (C) Copyright International Business Machines Corporation 1992-1997
 *      Licensed Material - Program-Property of IBM - All Rights Reserved.
 *
 * Revision:   53   1.17.1.4   source/core/utils/imrefcnt.hpp, utilities, ioc.v400, 980918   
 */
#ifndef _IMREFCNT_
#define _IMREFCNT_

#if __IBMCPP__ >= 400
#pragma namemangling(compat)
#endif

#pragma pack(push,4)
#pragma enum(4)

/** ---------------------------------------------------------------------------------
 * Abstract base class implementing thread-safe reference counting behavior.
 *
 * To make one of your classes reference counted, have it inherit from this class
 * When adding and removing references, call addRef and removeRef functions.
 * When the object's reference count reaches zero, it will be deleted.
 * <p>
 * When an IMReferenceCounted object is constructed, its initial reference
 * count is zero.  This is <em>not</em> the same behavior as the older,
 * deprecated IRefCounted class, so be careful when converting your code.
 *              @see IRefCounted.
 * <p>
 * If you want to have addRef and removeRef called for you,     consider using
 * ICountedPointerTo, a "smart pointer" that handles reference counting
 * automatically.
 *              @see ICountedPointerTo
 *
 * @threads All IMRefCounted methods are, of course, thread safe.
 */
class IMRefCounted {
public:
        /** Increment the reference count.
         *
         * Call this function when you create a new pointer that refers
         * to this object.
         */
        void                    addRef();

        /** Decrement the reference count.
         *
         * Call this function when you are finished using a pointer that refers
         * to this object.  If the reference count reaches zero, the object will
         * be deleted.
         */
        void                    removeRef();

        /** Return the current reference count */
        unsigned long   count() const;

protected:
        /** Construct a new object with an initial reference count of zero. */
                                        IMRefCounted();

        /** Copy-construct a reference-counted object.
         *
         * This function is only provided for completeness, so that subclass
         * copy constructors will have an inherited method to call.
         * It does <em>not</em> copy the reference count; the reference count
         * of the new object is initialized to zero.
         */
                                        IMRefCounted(const IMRefCounted&);

        /** Assign a reference-counted object.
         *
         * This function is only provided for completeness, so that subclass
         * copy constructors will have an inherited method to call.
         * It does <em>not</em> copy the reference count; the reference count
         * of the new object is initialized to zero.
         */
        IMRefCounted&   operator=(const IMRefCounted&);

        /** Destroy the object.
         *
         * Subclasses needing to do cleanup should override the destructor.
         * The destructor will be called (and the object will be deleted
         * from the heap) when the reference count reaches zero.
         */
        virtual                 ~IMRefCounted();

private:
        unsigned long   fCount;
};

#pragma enum(pop)
#pragma pack(pop)

#if __IBMCPP__ >= 400
#pragma namemangling()
#endif

#endif // _IMREFCNT_
