/*****************************************************************************
 * $LastChangedDate: 2011-04-09 21:58:06 -0400 (Sat, 09 Apr 2011) $
 * @file
 * @author  Jim E. Brooks  http://www.palomino3d.org
 * @brief   Shared is a base class with an intrusive reference-count updated by shptr (implementation).
 * @remarks Documented at shptr_doc.hh.
 *//*
 * LEGAL:   COPYRIGHT (C) 2007 JIM E. BROOKS
 *          THIS SOURCE CODE IS RELEASED UNDER THE TERMS
 *          OF THE GNU GENERAL PUBLIC LICENSE VERSION 2 (GPL 2).
 *****************************************************************************/

// -- (common include file) --

#if ! DOXYGEN

////////////////////////////////////////////////////////////////////////////////
// Shared or ThreadableShared class.
//
// Documented at shptr_doc.hh.
//
class SHARED : public SHARED_THREADABLE_OR_NON
{
public:
    // LIMITED USE.
    uint GetRefCount( void ) const
    {
    SHARED_AUTO_LOCK;  // same as SHPTR_AUTO_LOCK
    CHECK_TYPESIG(this,TYPESIG_SHARED);
        return mRefCount;
    }

    // LIMITED USE (see doc).
    void IncRefCount( void )
    {
    SHARED_AUTO_LOCK;
    CHECK_TYPESIG(this,TYPESIG_SHARED);
        ++mRefCount;
    }

protected:
    // SHARED initially has zero references.
    // Copy ctor makes a copy also with zero references.
    SHARED( void )
    :   mRefCount(0)
    {
    SHARED_AUTO_LOCK;
        SET_TYPESIG(this,TYPESIG_SHARED);
    }

    SHARED( const SHARED& src )
    :   mRefCount(0)
    {
    SHARED_AUTO_LOCK;
        SET_TYPESIG(this,TYPESIG_SHARED);
    }

    ~SHARED()
    {
    SHARED_AUTO_LOCK;
        INVALIDATE_TYPESIG(this,TYPESIG_SHARED);
    }

    // operator=() is explicitly defined as NOP (compiler would copy refCounts).
    // Reassigning the value of a SHARED should not affect refCounts.
    SHARED& operator=( const SHARED& src )
    {
    SHARED_AUTO_LOCK;
    CHECK_TYPESIG(this,TYPESIG_SHARED);
        return *this;
    }

private:
    mutable int mRefCount;

public:
    // Confusing Shared/ThreadableShared will cause a type-error at compile-time,
    // so don't need specific typesigs (preprocessor won't parse a typesig define).
    DECLARE_TYPESIG(TYPESIG_SHARED)

template<typename SHARED> friend class SHPTR;
template<typename SHARED> friend class SHPTR0;
};

#endif // ! DOXYGEN
