/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights 
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *	  notice, this list of conditions and the following disclaimer. 
 *
 * 2. 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.
 *
 * 3. The end-user documentation included with the redistribution,
 *	  if any, must include the following acknowledgment:  
 *		 "This product includes software developed by the
 *		  Apache Software Foundation (http://www.apache.org/)."
 *	  Alternately, this acknowledgment may appear in the software itself,
 *	  if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *	  not be used to endorse or promote products derived from this
 *	  software without prior written permission. For written 
 *	  permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *	  nor may "Apache" appear in their name, without prior written
 *	  permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
 * ITS 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
#if !defined(XALAN_OBJECTCACHE_HEADER_GUARD)
#define XALAN_OBJECTCACHE_HEADER_GUARD



#include <algorithm>
#include <vector>



#include <Include/STLHelper.hpp>
#include <Include/XalanAutoPtr.hpp>



template<class ObjectType>
class DefaultCacheCreateFunctor
{
public:

	ObjectType*
	operator()() const
	{
		return new ObjectType;
	}
};



template<class ObjectType>
class DefaultCacheResetFunctor
{
public:

	void
	operator()(ObjectType*) const
	{
	}
};



template<class ObjectType>
class ClearCacheResetFunctor
{
public:

	void
	operator()(ObjectType*	theInstance) const
	{
		theInstance->clear();
	}
};



#if defined(XALAN_OBJECT_CACHE_KEEP_BUSY_LIST)

template<
class ObjectType,
#if defined(XALAN_NO_DEFAULT_TEMPLATE_ARGUMENTS)
class CreateFunctorType,
class DeleteFunctorType,
class ResetFunctorType>
#else
class CreateFunctorType = DefaultCacheCreateFunctor<ObjectType>,
class DeleteFunctorType = DeleteFunctor<ObjectType>,
class ResetFunctorType = DefaultCacheResetFunctor<ObjectType> >
#endif
class XalanObjectCache
{
public:

#if defined(XALAN_NO_NAMESPACES)
	typedef vector<ObjectType*>			VectorType;
#else
	typedef std::vector<ObjectType*>	VectorType;
#endif

	typedef ObjectType	CacheObjectType;

	explicit
	XalanObjectCache(unsigned int	initialListSize = 0) :
		m_availableList(),
		m_busyList()
	{
		m_availableList.reserve(initialListSize);

		m_busyList.reserve(initialListSize);
	}

	~XalanObjectCache()
	{
		reset();

#if !defined(XALAN_NO_NAMESPACES)
		using std::for_each;
#endif

		for_each(
				m_availableList.begin(),
				m_availableList.end(),
				m_deleteFunctor);
	}

	ObjectType*
	get()
	{
		// We'll always return the back of the free list, since
		// that's the cheapest thing.
		if (m_availableList.size() == 0)
		{
			ObjectType* const	theNewObject = m_createFunctor();

			m_busyList.push_back(theNewObject);

			return theNewObject;
		}
		else
		{
			ObjectType* const	theObject = m_availableList.back();

			m_busyList.push_back(theObject);

			m_availableList.pop_back();

			return theObject;
		}
	}

	bool
	release(ObjectType*		theInstance)
	{
#if !defined(XALAN_NO_NAMESPACES)
		using std::find;
#endif

		typedef typename VectorType::iterator	IteratorType;

		const IteratorType	i =
			find(
				m_busyList.begin(),
				m_busyList.end(),
				theInstance);

		if (i == m_busyList.end())
		{
			return false;
		}
		else
		{
			m_resetFunctor(theInstance);

			m_availableList.push_back(theInstance);

			m_busyList.erase(i);

			return true;
		}
	}

	void
	reset()
	{
		while (m_busyList.size() != 0)
		{
			ObjectType* const	theInstance = m_busyList.back();

			m_resetFunctor(theInstance);

			m_availableList.push_back(theInstance);

			m_busyList.pop_back();
		}
	}

	// Functors for various operations...
	CreateFunctorType	m_createFunctor;

	DeleteFunctorType	m_deleteFunctor;

	ResetFunctorType	m_resetFunctor;

private:

	// There are not defined...
	XalanObjectCache(const XalanObjectCache<ObjectType, CreateFunctorType, DeleteFunctorType, ResetFunctorType>&	theRHS);

	XalanObjectCache<ObjectType, CreateFunctorType, DeleteFunctorType, ResetFunctorType>&
	operator=(const XalanObjectCache<ObjectType, CreateFunctorType, DeleteFunctorType, ResetFunctorType>&	theRHS);


	// Data members...
	VectorType			m_availableList;

	VectorType			m_busyList;
};



#else



template<
class ObjectType,
#if defined(XALAN_NO_DEFAULT_TEMPLATE_ARGUMENTS)
class CreateFunctorType,
class DeleteFunctorType,
class ResetFunctorType>
#else
class CreateFunctorType = DefaultCacheCreateFunctor<ObjectType>,
class DeleteFunctorType = DeleteFunctor<ObjectType>,
class ResetFunctorType = DefaultCacheResetFunctor<ObjectType> >
#endif
class XalanObjectCache
{
public:

#if defined(XALAN_NO_NAMESPACES)
	typedef vector<ObjectType*>			VectorType;
#else
	typedef std::vector<ObjectType*>	VectorType;
#endif

	typedef ObjectType	CacheObjectType;

	explicit
	XalanObjectCache(unsigned int	initialListSize = 0) :
		m_availableList()
	{
		m_availableList.reserve(initialListSize);
	}

	~XalanObjectCache()
	{
		reset();

#if !defined(XALAN_NO_NAMESPACES)
		using std::for_each;
#endif

		for_each(
				m_availableList.begin(),
				m_availableList.end(),
				m_deleteFunctor);
	}

	ObjectType*
	get()
	{
		// We'll always return the back of the free list, since
		// that's the cheapest thing.
		if (m_availableList.size() == 0)
		{
			return m_createFunctor();
		}
		else
		{
			ObjectType* const	theObject = m_availableList.back();

			m_availableList.pop_back();

			return theObject;
		}
	}

	bool
	release(ObjectType*		theInstance)
	{
		m_resetFunctor(theInstance);

		m_availableList.push_back(theInstance);

		return true;
	}

	void
	reset()
	{
	}

	// Functors for various operations...
	CreateFunctorType	m_createFunctor;

	DeleteFunctorType	m_deleteFunctor;

	ResetFunctorType	m_resetFunctor;

private:

	// These are not defined...
	XalanObjectCache(const XalanObjectCache<ObjectType, CreateFunctorType, DeleteFunctorType, ResetFunctorType>&	theRHS);

	XalanObjectCache<ObjectType, CreateFunctorType, DeleteFunctorType, ResetFunctorType>&
	operator=(const XalanObjectCache<ObjectType, CreateFunctorType, DeleteFunctorType, ResetFunctorType>&	theRHS);


	// Data members...
	VectorType			m_availableList;
};



#endif



template<class XalanObjectCacheType>
class GuardCachedObject
{
public:

	typedef typename XalanObjectCacheType::CacheObjectType	CacheObjectType;

	GuardCachedObject(XalanObjectCacheType&	theCache) :
		m_cache(theCache),
		m_cachedObject(theCache.get())
	{
	}

	~GuardCachedObject()
	{
		if (m_cachedObject != 0)
		{
			m_cache.release(m_cachedObject);
		}
	}

	CacheObjectType*
	get() const
	{
		return m_cachedObject;
	}

	CacheObjectType*
	release()
	{
		CacheObjectType* const	temp = m_cachedObject;

		m_cachedObject = 0;

		return temp;
	}

private:

	// Not implemented...
	GuardCachedObject(const GuardCachedObject<XalanObjectCacheType>&);


	// Data members...
	XalanObjectCacheType&	m_cache;

	CacheObjectType*		m_cachedObject;
};



template<class ObjectType>
class XalanObjectCacheDefault : public XalanObjectCache<ObjectType, DefaultCacheCreateFunctor<ObjectType>, DeleteFunctor<ObjectType>, DefaultCacheResetFunctor<ObjectType> >
{
public:

	typedef XalanObjectCache<ObjectType, DefaultCacheCreateFunctor<ObjectType>, DeleteFunctor<ObjectType>, DefaultCacheResetFunctor<ObjectType> >		BaseClassType;

	explicit
	XalanObjectCacheDefault(unsigned int	initialListSize = 0) :
		BaseClassType(initialListSize)
	{
	}
};



#endif
