// struct.cpp - Simple uses of structures

#include <iostream>
using namespace std;

struct Student {
  int  mid;
  int final;
  int hmws;
};

// We cannot read or write directly a student. That is, we cannot say, cout << sam; 
// or cin >> tom;  where sam and tom are students. However we can extend the
// definition of << and >> to allow us to write and read student information.

// This definition of the operator << allows us
// to output conveniently student objects.
ostream & operator<<(ostream& out, Student& a)
{
  out << '{' << a.mid <<  ", " << a.final << ", " << a.hmws << "}\n";
}

// This definition of the operator >> allows us
// to input conveniently student objects.
istream & operator>>(istream& in, Student& a)
{
  in >>  a.mid >> a.final >> a.hmws;
}

// We cannot compare directly two students (i.e. we cannot say (sam == tom)],
// but we can extend the definition of == to make it possible.

bool operator==(Student& a, Student& b)
{
  return (a.mid == b.mid && a.final == b.final && a.hmws == b.hmws);
}


void main(void){

   Student sam = {85, 90, 88}; // We initialize a student with an aggreagate value
   cout << sam;

   Student tom;
   cout << "Enter values for tom: ";
   cin >> tom;
   
   if (tom == sam)
     cout << "sam and tom are equal" << endl;
   else
     cout << "sam and tom are different" << endl;
   
   // We can assign a student to another student. For example:
   sam = tom;
   cout << sam;

   // We can access a structure and its fields through a pointer

   Student *he = &tom;
   cout << "*he = {" << he->mid << ", " << he->final << ", " << he->hmws << "}\n"; 
        // Notice the arrow notation for accessing the fields from he. 
        // The output will be *he = {85, 90, 88} 
   // We would get the same output if we access the fields in a different way:
   cout << "*he = {" << (*he).mid << ", " << (*he).final << ", " << (*he).hmws << "}\n";
   // And of course we can use <<
   cout << "*he = " << *he <<endl;
}



