#include <iostream>
using namespace std;

//==============================================
// 练习代码,一个简单的stack类,不妨修改一下以支持模板
//==============================================
class intStack
{
public:
        intStack();
        intStack(const intStack& other);
        intStack& operator = (const intStack& other);
        ~intStack();

        void pop();             
        void push(int value);   

        int  top()      const;
        bool empty()    const;
        int  size()     const;

        void clear();           //清空
        void reverse();         //将栈中元素反转
      
private:   
        struct stackNode
        {
                stackNode(int val = 0, stackNode* link = NULL) 
                        : value_(val), link_(link)
                {}
                int value_;
                stackNode* link_;
        };

        void copy(const intStack& other);
        stackNode* head;
        int count;
};

//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
void intStack::copy(const intStack& other)
{
        stackNode* pass1 = other.head->link_;
        stackNode* pass2 = head;

        while (pass1 != NULL)
        {
                pass2->link_ = new stackNode(pass1->value_);
                pass1 = pass1->link_;
                pass2 = pass2->link_;
        }
}

intStack::intStack() : head(new stackNode(0, NULL)), count(0)
{}

intStack::intStack(const intStack& other) 
        : head(new stackNode(0, NULL)), count(other.count)
{
        copy(other);
}

intStack& intStack::operator = (const intStack& other)
{
        if (this != &other)
        {
                clear();
                copy(other);
                count = other.count;
        }
        return *this;
}

void intStack::clear()
{
        while (!empty())        
                pop();
        head->link_ = NULL;
}

intStack::~intStack()
{
        clear();
        delete head;
}

int intStack::size() const
{
        return count;
}

void intStack::reverse()
{
        stackNode* pass = head->link_;
        head->link_ = NULL;

        while (pass != NULL)
        {
                stackNode* tmp = pass->link_;
                pass->link_ = head->link_;
                head->link_ = pass;
                pass = tmp;
        }
}
            
void intStack::push(int value)
{
        stackNode* newNode = new stackNode(value, head->link_);
        head->link_ = newNode;
        count++;
}

void intStack::pop() 
{
        if (empty())
                throw underflow_error("This stack is empty!");

        stackNode* tmpNode = head->link_;
        head->link_ = tmpNode->link_;
        delete tmpNode;

        count--;
}

int intStack::top() const
{
        if (empty())
                throw underflow_error("This stack is empty!");

        return head->link_->value_;
}

bool intStack::empty() const
{
        return head->link_ == NULL;
}

//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
int main()
{
        intStack testStack;

        for (int i=0; i<=100; i++)      
                testStack.push(i);

        intStack test;
        test = testStack;
        test.reverse();

        cout<<test.size()<<endl;

        while (!test.empty())
        {
                cout<<test.top()<<'\t';
                cout<<testStack.top()<<'\t';
                testStack.pop();
                test.pop();
        }

        return 0;
}