// Classe lista: listc.h
#ifndef LISTC_H
#define LISTC_H
/* Creo una classe base per le liste, in modo da creare la classe
 * template che contiene solo funzioni inline.
 * Tutti i membri sono protected, perche' verranno usati dalla
 * classe template list
 * Tutti i metodi hanno nomi diversi da quelli del template, per
 * evitare conflitti nella risoluzione del template
 */
class list_base {
protected:
  list_base *next;                        // Link della catena
  list_base *index (int i, int curr = 1); // Elemento num. (da 1)
  void concat (list_base *add);           // Concatena due liste
  void remove_base (list_base **base);    // elimina da lista
};

/* Classe template list
 * Per consentire di gestire elementi di tipi diversi (derivati), con gli
 * opportuni tipi di ritorno e per i parametri, deve essere una classe
 * template.
 * La classe base list_base e' private, perche' i metodi e attributi di
 * list_base devono essere gestiti solo dalle classi template
 */
template <class T> class list : private list_base {
protected :
  // Definisco un tipo puntatore a classe finale, per costruire
  // variabili passate per riferimento (un puntatore non va bene)
  typedef T *TPtr;
public :
  // Costruttore: si aggiunge in testa ad una lista 'base'
  list (TPtr &base) { next = (list *) base; base = (T*) this;};
  // Ritorna il valore del prossimo elemento
  T *Next () { return (T*) next; };
  // Operatore indice: ritorna l'elemento i-esimo (a partire da 1)
  // ATTENZIONE: si applica agli OGGETTI, non ai PUNTATORI!!!
  T *operator [] (int i) { return ((T*)index (i)); };
  // Distruttore virtuale - distrugge tutti gli elementi della lista
  virtual ~list () { if (next) delete next; };
  // Elimina l'elemento corrente dalla lista in cui e' contenuto
  void remove (TPtr &base) { remove_base ((list_base **) &base); };
  // Concatena la seconda lista alla prima
  void operator += (T *add) { concat ((list_base*) add); };
};
#endif