[ create a new paste ] login | about

Link: http://codepad.org/A8uhjc75    [ raw code | fork ]

C++, pasted on Oct 14:
#ifndef __STACK_H_INCLUDED__
#define __STACK_H_INCLUDED__

#include <iostream>

template <typename TYPE> class StackNode;  // スタック要素
template <typename TYPE> class Stack;      // スタック

/*===========================================================================*/
/*  StackNode:                                                               */
/*===========================================================================*/
template <typename TYPE>
class StackNode
{
public:// メンバ
	StackNode*	m_prevnode; // 前の要素へのポインタ
	StackNode*	m_nextnode; // 次の要素へのポインタ
	TYPE		m_data;     // この要素が持つデータ
	
public:// コンストラクタ
	StackNode(TYPE data);

};

template <typename TYPE>
StackNode<TYPE>::StackNode(TYPE data)
	: m_prevnode(0), m_nextnode(0), m_data(data)// 初期化子によるゼロクリア
{
}

/*===========================================================================*/
/*  Stack:                                                                   */
/*===========================================================================*/ 
template <typename TYPE>
class Stack
{
private:// メンバ
	StackNode<TYPE>* m_lownode;                   // スタック最下段要素へのポインタ
	StackNode<TYPE>* m_topnode;                   // スタック最上段要素へのポインタ
	int              m_elems;                     // スタックの要素数
	
public:// コンストラクタ&デストラクタ
	Stack();                                      // コンストラクタ
	Stack(const Stack<TYPE>& rother);             // コピーコンストラクタ
	~Stack();                                     // デストラクタ

public:// インライン関数
	inline int  size() const;                     // スタックの要素数
	inline bool empty() const;                    // スタックが空なら true
	inline int  bytes() const;                    // スタック全要素のデータのバイト数

public:// メソッド
	void		push(const TYPE& data);           // スタックへ要素をプッシュ
	void		pop();                            // スタックから要素をポップ
	TYPE&		top();                            // スタック最上段要素のデータへの参照を返す
	const TYPE&	top() const;                      //  "
	void		swap(Stack<TYPE>& rother) throw();// スタックをスワップ
	void		clear();                          // スタックのクリア

public:// オペレータのオーバロード
	Stack<TYPE>& operator =(const Stack<TYPE>& rother);// スタックのコピー

};

/*---------------------------------------------------------------------------*/
/*  Stack: Inline Functions                                                  */
/*---------------------------------------------------------------------------*/
template <typename TYPE>
inline int Stack<TYPE> ::size() const
{
	return m_elems;
}

template <typename TYPE>
inline int Stack<TYPE> ::bytes() const
{
	return m_elems * sizeof(TYPE);
}

template <typename TYPE>
inline bool Stack<TYPE> ::empty() const
{
	return (m_topnode == 0);
}

/*---------------------------------------------------------------------------*/
/*  Stack: Constructers                                                      */
/*---------------------------------------------------------------------------*/
template <typename TYPE>
Stack<TYPE> ::Stack()
	: m_lownode(0), m_topnode(0), m_elems(0)// 初期化子によるゼロクリア
{
}

template <typename TYPE>
Stack<TYPE> ::Stack(const Stack<TYPE>& rother)
	: m_lownode(0), m_topnode(0), m_elems(0)// 初期化子によるゼロクリア
{
	if (this == &rother) {
		return;
	}
	clear();
	
	StackNode<TYPE> *thisnode, *newnode;
	
	for (thisnode = rother.m_lownode; thisnode != NULL; thisnode = thisnode->m_nextnode)
	{
		newnode = new StackNode<TYPE>( thisnode->m_data );
		if (m_topnode == NULL) {
			m_lownode = m_topnode = newnode;
		} else {
			m_topnode->m_nextnode = newnode;
			newnode->m_prevnode   = m_topnode;
			m_topnode             = newnode;
		}
	}
	m_elems = rother.m_elems;
}

/*---------------------------------------------------------------------------*/
/*  Stack: Destructer                                                        */
/*---------------------------------------------------------------------------*/
template <typename TYPE>
Stack<TYPE> ::~Stack()
{
	clear();
}

/*---------------------------------------------------------------------------*/
/*  Stack: Methods                                                           */
/*---------------------------------------------------------------------------*/
template <typename TYPE>
void Stack<TYPE> ::push(const TYPE& data)
{
	StackNode<TYPE>* newnode;
	
	newnode = new StackNode<TYPE>( data );	// 新規要素を確保
	if (m_topnode == 0) {	                //  スタックが空なら
		m_lownode = m_topnode = newnode;    // 新規要素を最下段と最上段へ
	} else {                                //  スタックが空でなければ
		m_topnode->m_nextnode = newnode;	// 最上段要素の次に新規要素を繋げ
		newnode->m_prevnode   = m_topnode;	// 新規要素の前に最上段要素を繋げ
		m_topnode             = newnode;	// 最上段要素を更新
	}
	m_elems++;                              // 要素数をインクリメント
}

template <typename TYPE>
void Stack<TYPE>::pop()
{
	if (m_topnode == 0) {
		std::cout << "error: Pop: stack underflow." << std::endl;
		return;
	}
	StackNode<TYPE>	*prevnode;
	
	prevnode = m_topnode->m_prevnode;// 要素の削除準備
	delete m_topnode;                // 要素の削除
                                     // 以下、リンク
	if ( prevnode ) {                //  削除要素の前が空でなければ
		prevnode->m_nextnode = 0;    // 次の要素へのポインタをクリアして
		m_topnode = prevnode;        // 最上段要素のポインタを更新
	} else {                         //  削除要素がスタック最下段要素なら
		m_lownode = m_topnode = 0;   // ポインタをクリア
	}                                // 以上、リンク
	m_elems--;                       // 要素数をデクリメント
}

template <typename TYPE>
TYPE& Stack<TYPE>::top()
{
	static TYPE dummy;
	
	if ( m_topnode )
		return m_topnode->m_data;
	else {
		std::cout << "error: Stack: TYPE& Top(): stack underflow." << std::endl;
		return dummy;
	}
}

template <typename TYPE>
const TYPE& Stack<TYPE>::top() const
{
	static TYPE dummy;
	
	if ( m_topnode )
		return m_topnode->m_data;
	else {
		std::cout << "error: Stack: const TYPE& Top() const: stack underflow." << std::endl;
		return dummy;
	}
}

template <typename TYPE>
void Stack<TYPE>::swap(Stack<TYPE>& rother) throw()
{
	std::swap(m_lownode, rother.m_lownode);// 最下段要素へのポインタをスワップ
	std::swap(m_topnode, rother.m_topnode);// 最上段要素へのポインタをスワップ
	std::swap(m_elems, rother.m_elems);    // 要素数をスワップ
}

template<typename TYPE>
void Stack<TYPE> ::clear()
{
	StackNode<TYPE> *curstack, *delstack;
	
	for (curstack = m_topnode; curstack != 0; )// 要素を最上段から辿りすべて削除
	{
		delstack = curstack;
		curstack = curstack->m_prevnode;
		delete delstack;
	}
	// メンバのクリア
	m_lownode = m_topnode = 0;
	m_elems = 0;
}

/*---------------------------------------------------------------------------*/
/*  Stack: Operator Overload                                                 */
/*---------------------------------------------------------------------------*/
template <typename TYPE>
Stack<TYPE>& Stack<TYPE> ::operator =(const Stack<TYPE>& rother)
{
	Stack<TYPE>(rother).swap(*this);
	return *this;
}

#endif//__STACK_H_INCLUDED__


Create a new paste based on this one


Comments: