#ifndef _IPERTHR_INL_
#define _IPERTHR_INL_

/*----------------------------------------------------------------------------*/
/* FILE NAME: iperthr.inl                                                     */
/*                                                                            */
/* DESCRIPTION:                                                               */
/*  This file contains the inlines for iperthr.hpp                            */
/*                                                                            */
/*                                                                            */
/* COPYRIGHT:                                                                 */
/*   IBM Open Class Library                                                   */
/*   Licensed Materials - Property of IBM                                     */
/*                                                                            */
/*   5645-001                                                                 */









/*   (C) Copyright IBM Corporation 1992, 1997  All Rights Reserved.           */













/*                                                                            */
/*----------------------------------------------------------------------------*/

#ifndef IC_BUILD
#define __IOC_INLINE inline
#else
#define __IOC_INLINE
#endif

template <class AType>
__IOC_INLINE
void IThreadLocalStorage<AType>::freeStorage()
{
    delete (AType*)getSlot(index);
    setSlot(index, 0);
}

template <class AType>
__IOC_INLINE
IThreadLocalStorage<AType>::IThreadLocalStorage() :

    canReset(False),
    index(gInvalidThreadSlotIndex)
{
    index = getNextSlot();
}

template <class AType>
__IOC_INLINE
IThreadLocalStorage<AType>::IThreadLocalStorage(const bool resettable) :

    canReset(resettable),
    index(gInvalidThreadSlotIndex)
{
    index = getNextSlot();
}

template <class AType>
__IOC_INLINE
IThreadLocalStorage<AType>::~IThreadLocalStorage()
{
    // If our slot index never got set, then nothing to do
    if (index == gInvalidThreadSlotIndex)
        return;

    // Delete the data and zero the slot
    freeStorage();
}


template <class AType>
__IOC_INLINE
AType* IThreadLocalStorage<AType>::get() const
{
    return (AType*)getSlot(index);
}

template <class AType>
__IOC_INLINE
AType* IThreadLocalStorage<AType>::storage() const
{
    return (AType*)getSlot(index);
}

template <class AType>
__IOC_INLINE
AType* IThreadLocalStorage<AType>::operator->() const
{
    return (AType*)getSlot(index);
}

template <class AType>
__IOC_INLINE
AType& IThreadLocalStorage<AType>::operator*() const
{
    return *((AType*)getSlot(index));
}


template <class AType>
__IOC_INLINE
void
IThreadLocalStorage<AType>::adoptStorage(AType* toadopt)
{
    //
    //  If there is already a pointer and this one does not allow reset
    //  then we need to throw an exception.
    //
    if (getSlot(index))
    {
        if (!canReset)
        {
            IInvalidRequest exc("ThreadLocalStorage object does not support re-adopt",
                                0, IException::unrecoverable);
            ITHROW(exc);
        }

        // Get rid of the current object and zero out the pointer
        delete (AType*)getSlot(index);
        setSlot(index, 0);
    }

    // Store the new pointer
    setSlot(index, toadopt);
}

#endif // _IPERTHR_INL_
