#ifndef LISTA_H
#define LISTA_H// Um modelo de classe para representar o conceito de lista. O único
// argumento do modelo é o tipo dos itens na lista. O tipo dos itens
// deve possuir construtor por omissão.
template<class I>
class Lista {
public:
// É definido sinónimo do tipos de item (util para o utilizador do
// modelo):
typedef I Item;// Declaração de duas classes embutidas usadas para percorrer as listas:
class Iterador;
class IteradorConstante;// Construtores e destrutor:
Lista(); // construtor por omissão.
Lista(const Lista& lista); // construtor por cópia.
~Lista(); // destrutor.// Atribuição por cópia:
Lista& operator = (const Lista& lista);// Remove todos os itens da lista:
void limpa();// Informação acerca do tamanho do lista:
int comprimento() const; // número de itens.
bool vazia() const; // lista vazia?// Acesso aos itens nos extremos da lista. A acesso permite alterações
// apenas se a lista não for constante:
I frente() const; // como primeiro, mas primeiro() devolve iterador.
I& frente();
I tras() const; // como último, mas ultimo() devolve iterador.
I& tras();// Insere novo item no início e no fim da lista, respectivamente:
void poeInicio(const I& item);
void poeFim(const I& item);// Remove primeiro e último item da lista, respectivamente:
void tiraPrimeiro();
void tiraUltimo();// Insere novo item antes do item referenciado pelo iterador:
void insere(Iterador& i, const I& item);
void insere(const Iterador& i, const I& item);
/**
* A primeira versão de insere() deixa o iterador referenciando o
* elemento original, mas a segunda não faz quaisquer garantias: o
* utilizador deve tomar o iterador como inválido após a inserção.
* A segunda versão serve para se poder inserir usando iteradores
* temporários. Por exemplo:
* Lista<int> l;
* l.poeFim(1);
* l.poeFim(2);
* l.insere(l.procura(1), 3);
*/// Remove item referenciado pelo iterador:
void remove(Iterador& i);
void remove(const Iterador& i);
// Ver comentários acerca das versões de insere.// Concatena a lista passada como argumento com a lista implícita:
Lista& operator += (const Lista& lista);// Transfere todos os itens da lista passada como argumento para o final
// da lista implícita:
void transfere(Lista& lista);// Devolução de iteradores:
Iterador primeiro(); // para o primeiro item.
Iterador ultimo(); // para o último item.
Iterador fim(); // para o item fictício depois do último.
Iterador inicio(); // para o item fictício antes do primeiro.
Iterador procura(const I& item); // para o primeiro item com valor dado.
Iterador procuraUltimo(const I& item); // para o último item com valor dado.// Idem para listas constantes (devolvem iteradores constantes):
IteradorConstante primeiro() const;
IteradorConstante ultimo() const;
IteradorConstante fim() const;
IteradorConstante inicio() const;
IteradorConstante procura(const I& item) const;
IteradorConstante procuraUltimo(const I& item) const;// Excepções:
...private:
...
};
// Excepções de Lista:
...
/**
* Classe Iterador. As instâncias servem para percorrer os itens nas listas,
* permitindo aceder ao seu conteúdo. Não existe construtor por omissão!
* Os itens são alteráveis através do iterador.
*/
template<class I>
class Lista<I>::Iterador {
public:
// Construtor por omissão não existe. Um iterador tem de ser criado
// dizendo qual a lista a que deve ser associado. Fica associado ao
// primeiro item da lista:
explicit Iterador(Lista& lista);// Operações de avanço e recuo:
Iterador& operator ++ ();
Iterador operator ++ (int);
Iterador& operator -- ();
Iterador operator -- (int);// Acesso ao item:
I& item() const;// Comparação de iteradores:
bool operator == (const Iterador& i) const;
bool operator == (const IteradorConstante& i) const;
bool operator != (const Iterador& i) const;
bool operator != (const IteradorConstante& i) const;// Excepções:
...private:
...// Quer a lista quer os iteradores constantes são amigos:
friend class Lista;
friend class IteradorConstante;
};
// Excepções de Lista::Iterador:
...
// Como a classe Iterador, mas não permitindo alterar os itens referenciados.
template<class I>
class Lista<I>::IteradorConstante {
public:
explicit IteradorConstante(const Lista&);
IteradorConstante(const Iterador& i);IteradorConstante& operator ++ ();
IteradorConstante operator ++ (int);
IteradorConstante& operator -- ();
IteradorConstante operator -- (int);I item() const;
bool operator == (const IteradorConstante& i) const;
bool operator == (const Iterador& i) const;
bool operator != (const IteradorConstante& i) const;
bool operator != (const Iterador& i) const;...
private:
...friend class Lista;
friend class Iterador;
};
// Excepções de Lista::IteradorConstante:
...// Implementação:
...#endif