#include <iostream>

int main()
{

  /* 
  Illustration of what the text means on p. 5 by "yields std::cout as 
  its value."  It actually returns not std::cout but a reference to 
  std::cout.  That is the explanation for the & after std::ostream.
  */

  std::ostream& alt_out = (std::cout << "Hello, world #1 \n");

  alt_out <<  "Hello, world #2" << '\n';

  /*
  Illustration of scope: What's outside curly braces can be seen 
  within curly braces.  What's inside curly braces cannot be seen
  outside.
  */

  int a = 1;
  int b = 2;
  int c = 3;
  int d = 4;
  int e = 5;

  {
    int b = 6;            // Note that redefinition is permitted
    int c = 7;            // within curly braces;

    std::cout << a << ' ' << b << ' ' << c << ' ' << d << ' ' << e << '\n';
  }

  std::cout << a << ' ' << b << ' ' << c << ' ' << d << ' ' << e << '\n';

  /* 
  Below is equivalent to what the compiler does when you discard a 
  return value by coding: "std::cout << "Hello, world # 3 \n";"
  */

  { 
     std::ostream& tmp = std::cout << "Hello, world #3 \n";
  }

  /*
  This is an example of left associative:
  */

  std::cout<<"Goodbye cruel world. "<<"I'm off to join the circus"<<'\n';

  (((std::cout<<"Goodbye cruel world. ")<<"I'm off to join the circus")<<'\n');

  /*
  This is an example of right associative:
  */

  a = b = c = d = e;
  std::cout << a << ' ' << b << ' ' << c << ' ' << d << ' ' << e << '\n';

  a = (b = (c = (d = e)));
  std::cout << a << ' ' << b << ' ' << c << ' ' << d << ' ' << e << '\n';

  return 0;
}
