cpp2html 0.1-alpha © 2002 Andrea Leofreddi. To get the source click here

// 1.2: funzioni template
#include <iostream>
#include <cstring>
#include <cstdlib>

using namespace std;

template<class T> T *arraycopy(unsigned int dsize, T *src, unsigned int ssize) {
	unsigned int largest = dsize > ssize ? ssize : dsize;
	T *p;

	if(!dsize)
		return NULL;

	//cout << "size " << dsize << ", source " << ssize << ", largest " << largest << endl;
	p = new T[dsize + 1];

	for(int i = 0; i < largest; ++i) {
	//	cout << "p[" << i << "] = src[" << i << "]\n";
		p[i] = src[i];
	}

	return p;
}

class StackException {
	private:
		const char *err;
	public:
		// Metodi pubblici
		const char *get_err() { return err; };

		// Costruttori e distruttore
		StackException(const char *p)
		: err(p) { }
};

template<class T>class Stack {
	private:
		// Membri privati
		T *v;
		unsigned int vsize;

		// Metodi privati
		void deallocate() {
			if(v) {
				cout << "v era " << v << endl;
				delete v;
				v = NULL;
			}
		}

	public:
		// Metodi pubblici

		// Push
		void push(const T &n) {
			v = arraycopy(vsize + 1, v, vsize);

			v[vsize] = n;

			vsize++;
		}

		// Pop
		T pop() {
			if(!vsize)
				throw StackException("stack underflow");

			T r(v[vsize - 1]); // copia l'oggetto prima della distruzione
			
			v = arraycopy(vsize - 1, v, vsize);
			vsize--;
			
			return r;
		}

		// Size
		unsigned int size() {
			return vsize;
		}

		// Operatori
		const Stack &operator=(const Stack &copy) {
			if(&copy == this)
				return *this;

			deallocate();

			vsize = copy.vsize;
			v = arraycopy(copy.vsize, copy.v, copy.vsize);
		}

		T &operator[](unsigned int i) {
			if(i >= vsize)
				throw StackException("index out of range");

			return v[i];
		}

		// Costruttori e distruttore
		Stack() 
		: v(NULL), vsize(0) { }

		Stack(const Stack<T> &copy) 
		: vsize(copy.vsize) {
			v = arraycopy(copy.vsize, copy.v, copy.vsize);
		}

		~Stack() {
			deallocate();
		}
};

void showcmd() { }

int main() {
	Stack< Stack<int> > stackarray; // Stack di stack di interi
	bool done(false); // booleano per uscire dal while principale
	char line[256]; // buffer per contenere l'input
	char *cmd, *arg; // puntatori per memorizzare il comando e l'argomento
	unsigned int s(0); // intero che selezione lo stack che stiamo usando in stackarray

	cout << "Welcome to Stack example\nType help to get some help, quit to quit\n\n";

	while(!done) {		  
		try {
			cout << "Stack: > ";
			cin.getline(line, 256);
			
			cmd = line;

			if(arg = strchr(line, ' ')) {
				*arg = '\0';
				++arg;
			}
			
	//		cout << "Command: *" << cmd << "*, arg *" << arg << "*\n";

			if(!strcmp(cmd, "quit")) { // quit!
				done = true;
			} else if (!strcmp(cmd, "help")) {
				showcmd();
			} else if (!strcmp(cmd, "create")) {
				stackarray.push(Stack<int>());
			} else if (!strcmp(cmd, "destroy")) {
				stackarray.pop();
			} else if (!strcmp(cmd, "show")) {
				for(int i = 0; i < stackarray.size(); ++i) {
					cout << "> Stack " << (s == i ? "<*>" : "") << i << " (" << stackarray[i].size() << " elements) { ";
					for(int j = 0; j < stackarray[i].size(); ++j) 
						cout << stackarray[i][j] << (j != stackarray[i].size() - 1 ? ", " : " ");
					cout << "}" << endl;
				}
			} else if (!strcmp(cmd, "push")) {
				if(!arg)
					cerr << "Error: push command requires an argument" << endl;
				else {
					cout << "> Invoking PUSH on current stack " << s << " with argument " << atoi(arg) << endl;
					stackarray[s].push(atoi(arg));
				}
			} else if (!strcmp(cmd, "pop")) {
				cout << "> Invoking POP on current stack " << s << endl;
				stackarray[s].pop();
			} else if (!strcmp(cmd, "select")) {
				if(!arg)
					cerr << "Error: select command requires an argument" << endl;
				else {
					cout << "> Selecting " << atoi(arg) << " stack\n";
					s = atoi(arg);
					stackarray[s].size(); // Prova l'accesso al metodo size per vedere se abbiamo un indice corretto
				}
			} else if (!*cmd) 
				continue;
			else {
				cerr << "Error: unknown command " << cmd << endl;
			}
		} catch(StackException e) {
			cerr << "Error: Exception catch'd: " << e.get_err() << endl;
			cerr << "Error: recovery from error, selecting stack 0" << endl;

			s = 0;
		}
	}
}