#include <iostream.h>
#include <iomanip.h>
#include <list>

class team;

class driver {
private:
  char name[20];
  int points;
  team* driverFor;  

public:
  driver(team* T){driverFor=T;};  // drivers are created only with a team

  friend ostream& operator<<(ostream&, driver*);
  friend istream& operator>>(istream&, driver*);
};

// the g++ compiler needs iterators to be defined as types
typedef list<driver*>::const_iterator driverItor;

class team {
private:
  list<driver*> hasDrivers;
  char name[20];

public:

  friend ostream& operator<<(ostream&, team*);
  friend istream& operator>>(istream&, team*);
};

// the g++ compiler needs iterators to be defined as types
// const iterators are used when the access will not change
// the object in the container. 
typedef list<team*>::const_iterator teamItorConst;
// 
// non-const iterators are used when the element will be changed
typedef list<team*>::iterator teamItor;

ostream& operator<<(ostream& out,  team *t)
{
  driverItor curDriver;

  out << "Team: " << t->name << endl;
  out << "Driver                Points" << endl;
  
  // output each driver in the list
  for (curDriver = t->hasDrivers.begin(); //first element
       curDriver != t->hasDrivers.end();  //one past the last
       curDriver++)
    out << *curDriver; // *curDriver is a pointer to a driver

  out << endl;
}

istream& operator>>(istream& in, team* t)
{
  driver* d;
  int numDrivers;

  cout << "Team Name: ";
  in >> t->name;
  cout << "How many drivers: ";
  in >> numDrivers;

  for (; numDrivers; numDrivers--) {
    d = new driver(t); // create a new driver instance 
    if (d) { // successfull alloc
      in >> d; // input the data for the new driver
      t->hasDrivers.push_front(d); // put it at the front of the list
    }
  }
}

ostream& operator<<(ostream& out, driver *d)
{
  out << setw(20) << d->name <<  "    " << d->points << endl;
}

istream& operator>>(istream& in, driver* d)
{
  cout << "Driver name: ";
  in >> d->name;
  cout << "Points: ";
  in >> d->points;
}

void main()
{
  list<team*> F1;
  int numTeams;
  teamItorConst tc;
  teamItor ti;

  cout << "How many teams: ";
  cin >> numTeams;

  for(; numTeams; numTeams--)
    F1.push_back(new team); // make a new team and put it on the list

  // use the non const iterator here, because the 
  // list elements will change
  for(ti=F1.begin(); ti!=F1.end(); ti++)
    cin >> *ti; // input the data for the team, *ti is a ptr

  // use the const iterator here, since printing
  // does not change the elements
  for(tc=F1.begin(); tc!=F1.end(); tc++) 
    cout << *tc << endl; // *tc is a pointer to a team

}


  

