#include <iostream>
using namespace std;
class DataException
{
public:
virtual void println() const = 0;
};
class EmptyException : public DataException
{
public:
EmptyException() {}
void println() const { cout << "Error: Empty" << endl; }
};
class FullyException : public DataException
{
char ch;
public:
FullyException(const char& c) { ch = c; }
void println() const { cout << "Error: Fully '" << ch << '\'' << endl; }
};
#define QUEUESTACK_SIZE (3)
class BaseClass
{
protected:
char data[QUEUESTACK_SIZE];
int lastindex;
int count;
BaseClass() { lastindex = 0; count = 0; }
inline char addLast(const char& value) throw(DataException) {
if (count == QUEUESTACK_SIZE) { throw FullyException(value); }
int index = lastindex;
lastindex = (lastindex + 1) % QUEUESTACK_SIZE;
count++;
return data[index] = value;
}
};
class Queue : public virtual BaseClass
{
protected:
int firstindex;
public:
Queue() { firstindex = 0; }
char enqueue(const char& value) throw(DataException) {
return addLast(value);
}
char dequeue() throw(DataException) {
if (count == 0) { throw EmptyException(); }
int index = firstindex;
firstindex = (firstindex + 1) % QUEUESTACK_SIZE;
count--;
return data[index];
}
};
class Stack : public virtual BaseClass
{
public:
char pop() throw(DataException) {
if (count == 0) { throw EmptyException(); }
lastindex = (lastindex - 1 + QUEUESTACK_SIZE) % QUEUESTACK_SIZE;
count--;
return data[lastindex];
}
char push(const char& value) throw(DataException) {
return addLast(value);
}
};
class QueueStack : public Queue, public Stack
{
public:
QueueStack() {}
} queue, stack;
int main() {
cout << "Queue Test" << endl;
try {
cout << "enqueue: " << queue.enqueue('a') << endl;
cout << "enqueue: " << queue.enqueue('b') << endl;
cout << "enqueue: " << queue.enqueue('c') << endl;
cout << "enqueue: " << queue.enqueue('d') << endl;
} catch (DataException& ex) {
ex.println();
}
try {
cout << "dequeue: " << queue.dequeue() << endl;
cout << "dequeue: " << queue.dequeue() << endl;
cout << "dequeue: " << queue.dequeue() << endl;
cout << "dequeue: " << queue.dequeue() << endl;
} catch (DataException& ex) {
ex.println();
}
cout << "Stack Test" << endl;
try {
cout << "push: " << stack.push('a') << endl;
cout << "push: " << stack.push('b') << endl;
cout << "push: " << stack.push('c') << endl;
cout << "push: " << stack.push('d') << endl;
} catch (DataException& ex) {
ex.println();
}
try {
cout << "pop: " << stack.pop() << endl;
cout << "pop: " << stack.pop() << endl;
cout << "pop: " << stack.pop() << endl;
cout << "pop: " << stack.pop() << endl;
} catch (DataException& ex) {
ex.println();
}
return 0;
}