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

📄 list.h

📁 用测试OLE DB提供者的一个程序。能够测试出OEL DB提供者到底实现了哪些接口?很灵的。
💻 H
字号:
//-----------------------------------------------------------------------------
// Microsoft OLE DB RowsetViewer
// Copyright (C) 1994 - 1998 By Microsoft Corporation.
//
// @doc
//
// @module LIST.H
//
//-----------------------------------------------------------------------------------

#ifndef _LIST_H_
#define _LIST_H_
			
/////////////////////////////////////////////////////////////////////////////
// Includes
//
/////////////////////////////////////////////////////////////////////////////


/////////////////////////////////////////////////////////////////////////////
// Defines
//
/////////////////////////////////////////////////////////////////////////////
typedef void* LISTPOS;


/////////////////////////////////////////////////////////////////////////////
// CNode
//
/////////////////////////////////////////////////////////////////////////////
template <class TYPE> class CNode
{
public:
	// constructors
	CNode(TYPE data, CNode* pPrevNode, CNode* pNextNode);
	virtual ~CNode();

	// members
	TYPE     m_data;       // element data
	CNode*   m_pNextNode;  // next CNode
	CNode*   m_pPrevNode;  // prev CNode
};


/////////////////////////////////////////////////////////////////////////////
// CNode::CNode
//
/////////////////////////////////////////////////////////////////////////////
template <class TYPE> CNode<TYPE>::CNode(TYPE data, CNode* pPrevNode, CNode* pNextNode)
{
	//Constructor
	m_data = data;
	m_pPrevNode = pPrevNode;
	m_pNextNode = pNextNode;
}

/////////////////////////////////////////////////////////////////////////////
// CNode::~CNode
//
/////////////////////////////////////////////////////////////////////////////
template <class TYPE> CNode<TYPE>::~CNode()
{
	//Destructor
	m_pPrevNode = NULL;
	m_pNextNode = NULL;
}


/////////////////////////////////////////////////////////////////////////////
// CList
//
/////////////////////////////////////////////////////////////////////////////
template <class TYPE> class CList
{
public:

	//constructors
	CList();
	virtual ~CList();

	//members
	
	//list modifying operations
	virtual LISTPOS		AddHead(TYPE element);		// Add to Head
	virtual LISTPOS		AddTail(TYPE element);		// Add to Tail

	virtual LISTPOS		InsertBefore(LISTPOS position, TYPE element);	// Add before position
	virtual LISTPOS		InsertAfter(LISTPOS position, TYPE element);	// Add after position

	virtual TYPE		RemoveHead();				// Remove from Head
	virtual TYPE		RemoveTail();				// Remove from Tail
	virtual TYPE		RemoveAt(LISTPOS position); // RemoveAt position
	virtual void		RemoveAll();				// Remove all elements

	//Seeking methods
	virtual LISTPOS		Find(TYPE element);	        // Find element

	//Peek methods
	virtual LISTPOS		GetHeadPosition();			// Head Position
	virtual LISTPOS		GetTailPosition();			// Tail Position

	virtual TYPE		GetHead();					// Head element
	virtual TYPE		GetTail();					// Tail element
	virtual TYPE		GetNext(LISTPOS& position); // Next element
	virtual TYPE		GetPrev(LISTPOS& position); // Prev element

	//Data methods
	virtual TYPE		GetAt(LISTPOS position) const;			//Get element value
	virtual TYPE		SetAt(LISTPOS position, TYPE element);	//Set element value

	//Array-like methods
	virtual LISTPOS		FindIndex(ULONG iIndex);	//Index element

	//informational methods
	virtual BOOL		IsEmpty();					// IsEmpty
	virtual ULONG		GetCount();					// Elements in the list

private:
	//data
	CNode<TYPE>*		m_pHeadNode;				// Head of CList
	CNode<TYPE>*		m_pTailNode;				// Tail of CList

	ULONG				m_ulElements;				// Elements in the list
};


/////////////////////////////////////////////////////////////////////////////
// CList::CList
//
/////////////////////////////////////////////////////////////////////////////
template <class TYPE> CList<TYPE>::CList()
{
	//constructor
	m_pHeadNode		= NULL;
	m_pTailNode		= NULL;
	m_ulElements	= 0;
}

/////////////////////////////////////////////////////////////////////////////
// CList::~CList
//
/////////////////////////////////////////////////////////////////////////////
template <class TYPE> CList<TYPE>::~CList() 
{
	//Remove all elements
	RemoveAll();
}


/////////////////////////////////////////////////////////////////////////////
// CList::AddHead
//
/////////////////////////////////////////////////////////////////////////////
template <class TYPE> LISTPOS CList<TYPE>::AddHead(TYPE element) 
{
	//Add to the Head of the CList, (stack)
	CNode<TYPE>* pHeadNode = new CNode<TYPE>(element, NULL, m_pHeadNode);
	ASSERT(pHeadNode);

	//If there was a list hook the head->prev to the new head
	if(m_pHeadNode) 
	  m_pHeadNode->m_pPrevNode = pHeadNode;

	//If there isn't a tail element, hook it to the head
	if(!m_pTailNode)
	  m_pTailNode = pHeadNode;

	m_pHeadNode = pHeadNode;
	m_ulElements++;
	return m_pHeadNode;
}


/////////////////////////////////////////////////////////////////////////////
// CList::AddTail
//
/////////////////////////////////////////////////////////////////////////////
template <class TYPE> LISTPOS CList<TYPE>::AddTail(TYPE element) 
{
	//Add to the m_pTailNode of the CList
	CNode<TYPE>* pTailNode = new CNode<TYPE>(element, m_pTailNode, NULL);
	ASSERT(pTailNode);

	//if previously empty
	if(!m_pHeadNode)
	{
		ASSERT(m_pTailNode == NULL);
		m_pHeadNode = pTailNode;
	}
	else
	{
		ASSERT(m_pTailNode);
		m_pTailNode->m_pNextNode = pTailNode;
	}

	m_pTailNode = pTailNode;
	m_ulElements++;
	return m_pTailNode;
}



/////////////////////////////////////////////////////////////////////////////
// CList::GetHeadPosition
//
/////////////////////////////////////////////////////////////////////////////
template <class TYPE> inline LISTPOS CList<TYPE>::GetHeadPosition() 
{
	//return Head element Position
	return m_pHeadNode;
}

/////////////////////////////////////////////////////////////////////////////
// CList::GetTailPosition
//
/////////////////////////////////////////////////////////////////////////////
template <class TYPE> inline LISTPOS CList<TYPE>::GetTailPosition() 
{
	//return Tail element Position
	return m_pTailNode;
}

/////////////////////////////////////////////////////////////////////////////
// CList::GetHead
//
/////////////////////////////////////////////////////////////////////////////
template <class TYPE> inline TYPE CList<TYPE>::GetHead() 
{
	//return Head element value
	ASSERT(m_pHeadNode);
	return m_pHeadNode->m_data;
}

/////////////////////////////////////////////////////////////////////////////
// CList::AddTail
//
/////////////////////////////////////////////////////////////////////////////
template <class TYPE> inline TYPE CList<TYPE>::GetTail() 
{
	// return Tail element value
	ASSERT(m_pTailNode);
	return m_pTailNode->m_data;
}


/////////////////////////////////////////////////////////////////////////////
// CList::GetNext
//
/////////////////////////////////////////////////////////////////////////////
template <class TYPE> inline TYPE CList<TYPE>::GetNext(LISTPOS& position) 
{
	ASSERT(position);

	//Set position to the next element
	CNode<TYPE>* pNode = (CNode<TYPE>*)position;
	position = pNode->m_pNextNode;

	//return the current element
	return pNode->m_data;
}


/////////////////////////////////////////////////////////////////////////////
// CList::GetPrev
//
/////////////////////////////////////////////////////////////////////////////
template <class TYPE> inline TYPE CList<TYPE>::GetPrev(LISTPOS& position) 
{
	ASSERT(position);
	
	//Set position to the next element
	CNode<TYPE>* pNode = (CNode<TYPE>*)position;
	position = pNode->m_pPrevNode;
	
	//return the current element
	return pNode->m_data;
}


/////////////////////////////////////////////////////////////////////////////
// CList::GetAt
//
/////////////////////////////////////////////////////////////////////////////
template <class TYPE> inline TYPE CList<TYPE>::GetAt(LISTPOS position) const
{
	ASSERT(position);
	return ((CNode<TYPE>*)position)->m_data;
}

/////////////////////////////////////////////////////////////////////////////
// CList::SetAt
//
/////////////////////////////////////////////////////////////////////////////
template <class TYPE> inline TYPE CList<TYPE>::SetAt(LISTPOS position, TYPE element)
{
	ASSERT(position);

	//Save the old data
	CNode<TYPE>* pNode = (CNode<TYPE>*)position;
	TYPE oldData = pNode->m_data;

	//Store new data
	pNode->m_data = element;

	//return olddata
	return oldData;
}


/////////////////////////////////////////////////////////////////////////////
// CList::Find
//
/////////////////////////////////////////////////////////////////////////////
template <class TYPE> LISTPOS CList<TYPE>::Find(TYPE element) 
{
	//return pointer to found element
	for(CNode<TYPE>* p = m_pHeadNode; p != NULL; p = p->m_pNextNode)
	  if(p->m_data == element)
		return p;   // return position to found CNode

	return NULL;  // return NULL if not found
}


/////////////////////////////////////////////////////////////////////////////
// CList::IsEmpty
//
/////////////////////////////////////////////////////////////////////////////
template <class TYPE> inline BOOL CList<TYPE>::IsEmpty() 
{
	// returns TRUE if Empty
	return m_ulElements == 0;
}



/////////////////////////////////////////////////////////////////////////////
// CList::RemoveHead
//
/////////////////////////////////////////////////////////////////////////////
template <class TYPE> TYPE CList<TYPE>::RemoveHead() 
{
	//Remove and return from the Head of the List
	ASSERT(m_pHeadNode);

	CNode<TYPE>* pOldHead = m_pHeadNode;	// pointer to the Removed node
	TYPE element = GetHead();				//make a copy, before deleteing

	m_pHeadNode = pOldHead->m_pNextNode;	// reroute Head to exclude the first element
	if(m_pHeadNode)
	{
		ASSERT(m_pTailNode);
		m_pHeadNode->m_pPrevNode = NULL;
	}
	else
	{
		m_pTailNode = NULL;
	}

	m_ulElements--;
	delete pOldHead;						// delete head
	return element;
}


/////////////////////////////////////////////////////////////////////////////
// CList::RemoveTail
//
/////////////////////////////////////////////////////////////////////////////
template <class TYPE> TYPE CList<TYPE>::RemoveTail() 
{
	//Remove and return from the m_pTailNode of the CList
	ASSERT(m_pTailNode);

	CNode<TYPE>* pOldTail = m_pTailNode;
	TYPE element = GetTail();  //make a copy before deleteing

	m_pTailNode = pOldTail->m_pPrevNode;
	if(m_pTailNode)
	{
		ASSERT(m_pHeadNode);
		m_pTailNode->m_pNextNode = NULL;
	}
	else
	{
		m_pHeadNode = NULL;
	}

	m_ulElements--;
	delete pOldTail;
	return element;
}


/////////////////////////////////////////////////////////////////////////////
// CList::RemoveAt
//
/////////////////////////////////////////////////////////////////////////////
template <class TYPE> TYPE CList<TYPE>::RemoveAt(LISTPOS position)
{
	//Remove CList[position]
	ASSERT(position);

	CNode<TYPE>* pNode = (CNode<TYPE>*)position;
	TYPE oldData = pNode->m_data;

	// If removing the head
	if (pNode == m_pHeadNode)
		m_pHeadNode = pNode->m_pNextNode;
	else
		pNode->m_pPrevNode->m_pNextNode = pNode->m_pNextNode;
	
	//If removing the tail
	if (pNode == m_pTailNode)
		m_pTailNode = pNode->m_pPrevNode;
	else
		pNode->m_pNextNode->m_pPrevNode = pNode->m_pPrevNode;

	m_ulElements--;
	delete pNode;
	return oldData;
}


/////////////////////////////////////////////////////////////////////////////
// CList::RemoveAll
//
/////////////////////////////////////////////////////////////////////////////
template <class TYPE> void CList<TYPE>::RemoveAll() 
{
	// Remove all items from the CList
	CNode<TYPE>* pNode = m_pHeadNode;
	while(pNode)
	{
		CNode<TYPE>* pTemp = pNode;
		pNode = pNode->m_pNextNode;
		delete pTemp;
	}

	m_pHeadNode   = NULL;
	m_pTailNode   = NULL;
	m_ulElements    = 0;
}


/////////////////////////////////////////////////////////////////////////////
// CList::GetCount
//
/////////////////////////////////////////////////////////////////////////////
template <class TYPE> inline ULONG CList<TYPE>::GetCount() 
{
	// return the Length
	return m_ulElements;
}

				   
/////////////////////////////////////////////////////////////////////////////
// CList::InsertBefore
//
/////////////////////////////////////////////////////////////////////////////
template <class TYPE> LISTPOS CList<TYPE>::InsertBefore(LISTPOS position, TYPE element)
{
	//insert before the position
	if(position == m_pHeadNode)    // Add before Head
	  return AddHead(element);

	CNode<TYPE>* pOldNode = (CNode<TYPE>*)position;

	//otherwise a little more difficult
	CNode<TYPE>* pNewNode = new CNode<TYPE>(element, pOldNode->m_pPrevNode, pOldNode);
	
	//Hook up before after nodes to it
	pOldNode->m_pPrevNode->m_pNextNode = pNewNode;
	pOldNode->m_pPrevNode = pNewNode;

	m_ulElements++;
	return pNewNode;
}



/////////////////////////////////////////////////////////////////////////////
// CList::InsertAfter
//
/////////////////////////////////////////////////////////////////////////////
template <class TYPE> LISTPOS CList<TYPE>::InsertAfter(LISTPOS position, TYPE element)
{
	//insert after the position
	if(position == m_pTailNode)     // Add after the m_pTailNode
	  return AddTail(element);
	
	CNode<TYPE>* pOldNode = (CNode<TYPE>*)position;

	//other wise a little more difficult
	CNode<TYPE>* pNewNode = new CNode<TYPE>(element, pOldNode, pOldNode->m_pNextNode);
	
	//Hook up before after nodes to it
	pOldNode->m_pNextNode->m_pPrevNode = pNewNode;
	pOldNode->m_pNextNode = pNewNode;

	m_ulElements++;
	return pNewNode;
}


/////////////////////////////////////////////////////////////////////////////
// CList::FindIndex
//
/////////////////////////////////////////////////////////////////////////////
template <class TYPE> LISTPOS CList<TYPE>::FindIndex(ULONG iIndex)
{
	ASSERT(iIndex>=0 && iIndex<m_ulElements);

	CNode<TYPE>* pNode = m_pHeadNode;

	//Find the specified index
	while(iIndex--)
		pNode = pNode->m_pNextNode;

	return (LISTPOS)pNode;
}

#endif //_LIST_H_

⌨️ 快捷键说明

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