⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ienumiterator.hpp

📁 Visual C++下的界面设计
💻 HPP
📖 第 1 页 / 共 2 页
字号:
#ifndef __IENUM_ITERATOR__
#define __IENUM_ITERATOR__
///////////////////////////////////////////////////////////////////////////////
//
// File           : $Workfile:   IEnumIterator.hpp  $
// Version        : $Revision:   1.5  $
// Function       : 
//
// Author         : $Author:   len  $
// Date           : $Date:   Oct 25 1998 20:51:20  $
//
// Notes          : 
//
// Modifications  :
//
// $Log:   G:/Documents/JetByte/Source/JetByteTools/COMTools/PVCS/IEnumIterator.hpv  $
// 
//    Rev 1.5   Oct 25 1998 20:51:20   len
// Bug fixes and Lint changes.
// 
//    Rev 1.4   Sep 16 1998 07:41:54   len
// 
//    Rev 1.3   Aug 30 1998 16:25:34   len
// 
//    Rev 1.2   Aug 28 1998 07:33:04   len
// 
//    Rev 1.1   Jun 06 1998 07:56:20   Len
// 
//    Rev 1.0   May 18 1998 07:34:46   Len
// Initial revision.
// 
///////////////////////////////////////////////////////////////////////////////
//
// Copyright 1998 JetByte Limited.
//
// JetByte Limited grants you ("Licensee") a non-exclusive, royalty free, 
// licence to use, modify and redistribute this software in source and binary 
// code form, provided that i) this copyright notice and licence appear on all 
// copies of the software; and ii) Licensee does not utilize the software in a 
// manner which is disparaging to JetByte Limited.
//
// This software is provided "AS IS," without a warranty of any kind. ALL
// EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING 
// ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE 
// OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBYTE LIMITED AND ITS LICENSORS 
// SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF 
// USING, MODIFYING OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO 
// EVENT WILL JETBYTE LIMITED BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, 
// OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE 
// DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING 
// OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN IF JETBYTE LIMITED 
// HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
//
// This software is not designed or intended for use in on-line control of
// aircraft, air traffic, aircraft navigation or aircraft communications; or in
// the design, construction, operation or maintenance of any nuclear
// facility. Licensee represents and warrants that it will not use or
// redistribute the Software for such purposes.
//
///////////////////////////////////////////////////////////////////////////////

#ifndef __COM_EXCEPTION__
#include "ComException.hpp"
#endif

#ifndef __COM_UTILS__
#include "ComUtils.hpp"
#endif

///////////////////////////////////////////////////////////////////////////////
// Namespace: JetByteTools
///////////////////////////////////////////////////////////////////////////////

namespace JetByteTools {

///////////////////////////////////////////////////////////////////////////////
// Templates defined in this file...
///////////////////////////////////////////////////////////////////////////////

template <class T, class I, class E> class IEnumIterator;

template <class T, class E> class TCache;

///////////////////////////////////////////////////////////////////////////////
// TCache
//
// A template cache to manage the "read ahead" buffer used by IEnumIterator 
// so that we can call the underlying interface pointer's Next() function for
// multiple items...
///////////////////////////////////////////////////////////////////////////////

template <class T, class E>
class TCache
{
	public :

		TCache(unsigned long size = 1);				// Create a cache of a specific  
																// size 
		~TCache();

		void ResizeCache(unsigned long newSize);	// Change size of cache, safe to
																// use even if cache has items
																// in it and you're making it
																// smaller...
		
		void EmptyCache();								// empties the cache and destroys
																// items.
		
		E *GetCache() const;								// Returns pointer to the cache
		
		unsigned long GetSize() const;				// Returns size of cache

		void FillCache(unsigned long numItems);	// Set cache as having x items

		const E &GetCurrent() const;					// Get current item

		bool Next();										// Step to next item, Destroy
																// last item, return true if the
																// cache is not now empty

		unsigned long Skip(unsigned long numToSkip);		// Skip numToSkip items or
																		// to end of cache, return
																		// number actually skipped

		bool IsEmpty() const;							// Does the cache have items?

      TCache(const TCache<T,E> &rhs);					// Copy
      TCache &operator=(const TCache<T,E> &rhs);	// Assign


	private :

		E *CopyCache() const;						

		static E *CopyCache(
			E *pCache, 
			unsigned long current, 
			unsigned long cached, 
			unsigned long newSize);

		void Destroy();

		void DestroyItem(E item);

		mutable E *m_pCache;								// Mutable to allow for lazy
																// creation

		unsigned long m_current;						// current item in cache
		unsigned long m_cached;							// number of items in cache
		unsigned long m_size;							// logical size of cache
		mutable unsigned long m_allocatedSize;		// physical size of cache
};

///////////////////////////////////////////////////////////////////////////////
// IEnumIterator<T,I,E>
///////////////////////////////////////////////////////////////////////////////

template <class T, class I, class E> 
class IEnumIterator
{

	friend class TCache<T,E>;

   public :

      class NullIterator {};				// Exception thrown if you dereference
													// an invalid iterator

      virtual ~IEnumIterator();

      IEnumIterator<T,I,E> &operator++();

#ifdef IENUM_ITERATOR_USE_POST_INC		// Protect from indavertant use of 
													// expensive post inc

      IEnumIterator<T,I,E> operator++(int);

#endif // IENUM_ITERATOR_USE_POST_INC

      bool operator!=(const IEnumIterator<T,I,E> &rhs);
      bool operator==(const IEnumIterator<T,I,E> &rhs);

      operator E() const;					// Access enumerated item

		void SetCacheSize(					// Change read ahead for I->Next()
			unsigned long max);

		void Reset();							// Reset iterator to start of sequence

		unsigned long Skip(					// Skip x items, returns number skipped
			unsigned long numToSkip);

		static const T &End();				// Generic End of sequence iterator

   protected :       
         
      IEnumIterator(I *pIEnum, unsigned long max = 64);

      const E &Enumerated() const;

      IEnumIterator(const IEnumIterator<T,I,E> &rhs);
      IEnumIterator &operator=(const IEnumIterator<T,I,E> &rhs);

   private :

      void Advance();						
      void CheckValid() const;
		void CheckPrimed() const;

		// Function called to destroy each item in the cache
		// Defaults to doing nothing
		virtual void Destroy(E /*item*/) const { }

		// Function called to copy each item in the cache
		// Defaults to returning the item supplied 
		
		virtual E Copy(E item) const { return item; }

      mutable I *m_pIEnum;

		mutable bool m_bAtEnd;
		mutable bool m_bNotPrimed;

		TCache<T,E> m_cache;
		
		// Interface for our friend TCache<E>
		
		static void DestroyItem(E item); 
		static E CopyItem(E item); 
};

///////////////////////////////////////////////////////////////////////////////
// Implement TCache
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
// Construction and destruction
///////////////////////////////////////////////////////////////////////////////

template <class T, class E>
TCache<T,E>::TCache(
	unsigned long size /* = 1 */)
	:	m_pCache(0),
		m_current(0),
		m_cached(0),
		m_size(size),
		m_allocatedSize(0)
{
	// Nothing to do. We dont allocate the cache at this point, the client 
	// is likely to change the size before use, so we will wait until either
	// the size changes or we attempt to use the cache before we allocate.
}

template <class T, class E>
TCache<T,E>::TCache(const TCache<T,E> &rhs)
	:	m_pCache(rhs.CopyCache()),
		m_current(rhs.m_current),
		m_cached(rhs.m_cached),
		m_size(rhs.m_size),
		m_allocatedSize(rhs.m_allocatedSize)
{

}

template <class T, class E>
TCache<T,E>::~TCache()
{
	Destroy();			// Call Destroy to Destroy each item remaining in the 
							// cache and then delete the cache itself...
}

template <class T, class E>
TCache<T,E> &TCache<T,E>::operator=(const TCache<T,E> &rhs)
{
	if (this != &rhs)
	{
		E *pNewCache = rhs.CopyCache();

		Destroy();		// Call Destroy to Destroy each item remaining in the 
							// cache and then delete the cache itself...
		
		m_pCache = pNewCache;		
	
		m_current = rhs.m_current;
		m_cached = rhs.m_cached;
		m_size = rhs.m_size;
		m_allocatedSize = rhs.m_allocatedSize;
	}
}

///////////////////////////////////////////////////////////////////////////////
// Cache management
///////////////////////////////////////////////////////////////////////////////

template <class T, class E>
void TCache<T,E>::ResizeCache(unsigned long newSize)
{
	if (newSize > m_allocatedSize)
	{
		// Making cache physically bigger...

		E *pNewCache = CopyCache(m_pCache, m_current, m_cached, newSize);

		Destroy();		// Call Destroy to Destroy each item remaining in the 
							// cache and then delete the cache itself...

		m_pCache = pNewCache;

		m_allocatedSize = newSize;
		m_size = newSize;
	}
	else 
	{
		// Cache is physically big enough, adjust logical size
		m_size = newSize;
	}
}

template <class T, class E>
void TCache<T,E>::EmptyCache()
{
	while (!IsEmpty())
	{
		Next();
	}

	m_cached = 0;
	m_current = 0;
}

template <class T, class E>
void TCache<T,E>::FillCache(unsigned long numItems)
{
	// Cache items are inserted by calling GetCache and writing to the
	// pointer returned...

	// This just sets the counter...

	m_cached = numItems;
}

template <class T, class E>
E *TCache<T,E>::GetCache() const
{
	if (m_allocatedSize == 0 && m_size != 0)
	{
		// Lazy cache creation, if we still don't have one, create it now, 
		// just before first use...

		m_pCache = new E[m_size];

		m_allocatedSize = m_size;
	}

	// Could throw an exception if the cache is 0 size?
	// We could paramaterise ourself on an exception type to
	// throw in this circumstance...

//	if (IsEmpty())
//	{
//		throw E;
//	}

	return m_pCache;
}

template <class T, class E>
unsigned long TCache<T,E>::GetSize() const
{
	return m_size;
}

template <class T, class E>
const E &TCache<T,E>::GetCurrent() const
{
	// We could paramaterise ourself on an exception type to
	// throw in this circumstance...

//	if (IsEmpty())
//	{
//		throw E;
//	}

	return m_pCache[m_current];
}

template <class T, class E>
bool TCache<T,E>::IsEmpty() const
{
	return (m_cached == 0 || m_current >= m_cached);
}

template <class T, class E>
bool TCache<T,E>::Next()
{
	bool ok = false;

	if (++m_current < m_cached)
	{
		ok = true;
	}

	if (m_current <= m_cached)
	{
		// Destroy the item we just stepped past...
		// Including the last item...

		DestroyItem(m_pCache[m_current -1]);
	}

	return ok;
}

template <class T, class E>
unsigned long TCache<T,E>::Skip(unsigned long numToSkip)
{
	unsigned long numSkipped = 0;

	while(!IsEmpty() && numSkipped < numToSkip)
	{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -