/*
* This class implements a stack by directly using a linked list.
* This version adds a destructor to clean up when the object is destroyed.
*/
#ifndef _lnkstack2_h_
#define _lnkstack2_h_
template <typename T>
class Stack {
public:
// Initialize the stack empty.
Stack() {
m_head = nullptr;
m_size = 0;
}
// Clean up any remaining nodes.
~Stack() {
auto scan = m_head;
while(scan != nullptr) {
auto zombie = scan;
scan = scan->next();
delete zombie;
}
m_size = 0; // Unnecessary, since object won't exist any more.
}
// Push the argument item.
void push(const T &itm) {
m_head = new node(itm, m_head);
++m_size;
}
// Pop the argument item, and return true, or return false if the
// the stack is empty.
bool pop(T &itm) {
if(m_head == nullptr) return false;
itm = m_head->data();
node *zombie = m_head;
m_head = m_head->next();
delete zombie;
--m_size;
return true;
}
// Convenience to pop and return the top object. Only works
// for types where T() is a valid expression.
T pop() {
T ret;
if(pop(ret)) return ret;
return T();
}
// Tell if empty.
bool empty() {
return m_head == nullptr;
}
// Report the size
int size() {
return m_size;
}
private:
// Nodes for the linked list.
class node {
public:
node(const T &d, node *n = nullptr) {
m_data = d;
m_next = n;
}
const T& data() { return m_data; }
node *next() { return m_next; }
private:
T m_data;
node *m_next;
};
node * m_head; // Head of the linked list.
int m_size; // Size of the stack.
};
#endif