The programs below are discussed in

   Ammeraal, L. (2000) C++ for Programmers, 3rd Edition,
      Chichester: John Wiley, ISBN 0-471-60697-9.

See also http://home.wxs.nl/~ammeraal/
For some programs (or header files) there are special versions for GNU C++ (gcc)
at the bottom of this document. (If you are using an editor, search for GNU.)



Chapter 1
=========

// example1.cpp: A program to compute the squares of both 
//               the sum and the difference of two given 
//               integers.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 3.
#include <iostream>
using namespace std;

int main()
{  cout << "Enter two integers: "; // Displays input request.
   int a, b;
   cin >> a >> b;                  // Reads a and b.
   int sum = a + b, diff = a - b,
   u = sum * sum, v = diff * diff;
   cout << "Square of sum       : " << u << endl;
   cout << "Square of difference: " << v << endl;
   return 0;
}




// twolines.cpp: Application of type string.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 15.
#include <iostream>
#include <string>
using namespace std;
int main()
{  cout << "  Enter two lines of text: \n";
   string s, t;
   getline(cin, s);
   getline(cin, t);
   cout << "  Output in alphabetic order:\n";
   if (s <= t)
      cout << s << endl << t << endl;
   else
      cout << t << endl << s << endl;
   return 0;
}




// introstl.cpp: Introduction to STL.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 16.
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;

int main()
{  vector<string> v;
   cout << "  Enter lines of text to be sorted,\n";
   cout << "  followed by the word stop:\n";
   for (;;)
   {  string s;
      getline(cin, s);
      if (s == "stop")
         break;
      v.push_back(s);
   }
   sort(v.begin(), v.end());
   cout << "  The same lines after sorting:\n";
   for (int i=0; i<v.size(); ++i)
      cout << v[i] << endl;
   return 0;
}




Chapter 2
=========

// typvar.cpp: Types and variables.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 27.
// There is version adapted for gcc below.
#include <iostream>
#include <iomanip>
using namespace std;

int main()
{  char ch = 'A';  
   double ff = 5.0/3;
   float f = ff;
   bool b = (f > 1);
   int i, j;
   j = 2 * (i = 5.0/3);  // i = 1, j = 2
   cout << "ch = " << ch 
        << "   ASCII value: " << int(ch) << endl;
   cout << fixed << setprecision(10);
   cout << "f = " << f << "   ff = " << ff << endl;
   cout << "i = " << i << "   j = " << j << endl;
   if (b) 
      cout << "The variable b is equal to true.\n";
   cout << "Number of bytes for type 'bool':   " 
        << sizeof(bool) << endl;
   cout << "Number of bytes for type 'char':   "
        << sizeof(char) << endl;
   cout << "Number of bytes for type 'int':    "
        << sizeof(int) << endl;
   cout << "Number of bytes for type 'float':  "
        << sizeof(float) << endl;
   cout << "Number of bytes for type 'double': "
        << sizeof(double) << endl;
   return 0;
}


// scope.cpp: Illustration of 'scope' and 'visibility'.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 34.
#include <iostream>
using namespace std;

int main()
{  double x = 3.4;
   {  cout << x << " ";     // 3.4
      int x = 7;
      {  cout << x << " ";  // 7
         char x = 'A';
         cout << x << " ";  // A
      }
      cout << x << " ";     // 7
   }
   cout << x << endl;       // 3.4
   return 0;
}




// table.cpp: This program produces a table.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 41.
// There is a version adapted for gcc below.
#include <iostream>
#include <iomanip>
using namespace std;

int main()
{  cout << " x         f(x)\n\n";
   cout << fixed;
   for (int i=20; i<=40; i+=2)
   {  double x = i/10.0;
      cout << setw(3) << setprecision(1) 
           << x << " "
           << setw(15) << setprecision(10)
           << x * x + x + 1/x << endl;
   }
   return 0;
}



// break.cpp: Demonstration of the break-statement.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 43.
#include <iostream>
using namespace std;

int main()
{  double s = 0, x;
   cout << "Enter numbers, separated by blanks.\n";
   cout << 
   "They are added up as long as they are positive.\n\n";
   for (;;)
   {  cin >> x;
      if (x <= 0) break;
      s += x;
   }
   cout << "Sum of the positive numbers that have "
           "been read: " << s << endl;
   return 0;
}




// even1.cpp: Solution without goto-statements.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 45.
#include <iostream>
using namespace std;

int main()
{  int x, s = 0;
   cout << "Enter positive integers, followed by -1:\n";
   for (;;)
   {  cin >> x;                 // Read x.
      if (x == -1) break;       // Exit if x is -1.
      if (x % 2 == 0) s += x;   // Use x only if it is even.
   }
   cout << "Sum of even integers: " << s << endl;
   return 0;
}



// even2.cpp: Solution with goto-statements.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 45.
#include <iostream>
using namespace std;

int main()
{   int x, s = 0;
    cout << "Enter positive integers, followed by -1:\n";
l1: cin >> x;                   // Read x.
    if (x == -1) goto l2;       // Exit if x is -1.
    if (x % 2 == 0) s += x;     // Use x only if it is even.
    goto l1;                    // Back to start of loop.
l2: cout << "Sum of even integers: " << s << endl;
    return 0;
}



Chapter 3
=========

// hexadec.cpp: Hexadecimal and decimal input and output.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 57.
#include <iostream>
using namespace std;

int main()
{  cout << "Enter a hexadecimal integer x (for example, 1F) and a "
           "decimal integer y:\n";
   int x, y;
   cin >> hex >> x >> dec >> y;
   cout << "0x" << hex << x << " = " << dec << x << endl;
   int s = x + y;
   cout << "Their sum (hexadecimal): " << hex << s << endl;
   cout << "Their sum (decimal):     " << dec << s << endl; 
   return 0;
}



// lifo.cpp: This program reads 30 integers and prints them
//           in the reverse order (Last In, First Out).
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 59.
#include <iostream>
#include <iomanip>
using namespace std;

int main()
{  const int n = 30;
   int i, a[n];
   cout << "Enter " << n << " integers:\n";
   for (i=0; i<n; ++i) 
      cin >> a[i];
   cout << "\nThe same integers, in reverse order:\n";
   for (i=0; i<n; ++i)
      cout << setw(6) << a[n-i-1] 
           << (i % 10 == 9 ? '\n' : ' ');
   return 0;
}


// assign.cpp: Assignment operators.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 61.
#include <iostream>
using namespace std;

int main()
{  int i = 20, j = 10, k, l, m;
   k = l = i += j += m = 1;
   cout << "m=" << m << "  j=" << j << "  i=" << i 
        << "  l=" << l << "  k=" << k << endl;
   return 0;
}



// signedch.cpp: This program finds out whether the leftmost 
//               bit of type char is a sign bit.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 69.
#include <iostream>
using namespace std;

int main()
{  signed char s_ch = '\xFF';
   unsigned char u_ch = '\xFF';
   char ch = '\xFF'; // Binary: s_ch = u_ch = ch = 11111111    
   int s, u, i;
   s = s_ch; // From signed char to int
   u = u_ch; // From unsigned char to int
   i = ch;   // From char to int (system dependent) 
   cout << "For this C++ implementation, type char has " <<
   ( i == s ? "a sign bit.\n" :
     i == u ? "no sign bit.\n" :
     "not been implemented correctly.\n"
   );
   return 0;
}



// beware.cpp: Can a negative value be equal to a 
//             positive one?
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 70.
#include <iostream>
using namespace std;

int main()
{  unsigned u = ~0x1; // u = 0xF...FE
   int i = u;         // i = -2 (same bit pattern as u)
   if (i == u) cout << "i == u\n";
   if (i < 0) cout << "i < 0\n";
   if (u > 0) cout << "u > 0\n";
   return 0;
}


Chapter 4
=========

// fdemo1.cpp: Demonstration program with a function.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 79.
#include <iostream>
using namespace std;

float fun(float x, float y, int i, int j)
{  float a = x - y;
   int b = i - j;
   return b != 0 ? a/b : 
      a > 0 ? +1e20F :
      a < 0 ? -1e20F : 0.0F;
}

int main()
{  int ii, jj;
   float xx, yy;
   cout << 
   "Enter two real numbers followed by two integers:\n";
   cin >> xx >> yy >> ii >> jj;
   cout << "Value returned by function: " 
        << fun(xx, yy, ii, jj) << endl;
   return 0;
}



// fdemo2.cpp: The function fun, called in main, is declared
//             before and defined after main.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 81.
#include <iostream>
using namespace std;

float fun(float x, float y, int i, int j); // declaration

int main()
{  int ii, jj;
   float xx, yy;
   cout << 
   "Enter two real numbers followed by two integers:\n";
   cin >> xx >> yy >> ii >> jj;
   cout << "Value returned by function: " 
        << fun(xx, yy, ii, jj) << endl;
   return 0;
}

float fun(float x, float y, int i, int j) // definition
{  float a = x - y;
   int b = i - j;
   return b != 0 ? a/b : 
      a > 0 ? +1e20 :
      a < 0 ? -1e20 : 0.0;
}



// recurs.cpp: Recursion.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 83.
#include <iostream>
using namespace std;

int f(int n)
{  int x = n - 1, y;
   if (n <= 1) 
      y = 1;
   else
      y = n * f(x);
   return y;
}
 
int main()
{  cout << f(3) << endl;
   return 0;
}



// prmax3.cpp: A function that prints the maximum of three 
//             integers.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 84.
#include <iostream>
using namespace std;

void prmax3(int x, int y, int z)
{  if (y > x) x = y;
   if (z > x) x = z;
   cout << "The maximum of these three is: " << x << endl;
}

int main()
{  int i, j, k;
   cout << "Enter three integers: ";
   cin >> i >> j >> k;
   prmax3(i, j, k);
   return 0;
}



// nopar.cpp: Using a function without parameters.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 85.
#include <iostream>
using namespace std;

double readreal()
{  double x;
   char ch;
   for (;;)
   {  cin >> x;
      if (!cin.fail())     // See Section 3.2
         break;
      cin.clear();         // See Section 3.2
      do ch = cin.get(); while (ch != '\n');
      // Rest of incorrect line has now been skipped.
      cout << "Incorrect. Enter a number:\n";
   }
   return x;
}

int main()
{  double xx;
   float x;
   cout << "Enter a real number: ";
   xx = readreal();
   cout << "Another one, please: ";
   x = readreal();
   cout << "The following numbers have been read: "
        << xx << " " << x << endl;
   return 0;
}



// globvar.cpp: A global variable.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 87.
#include <iostream>
using namespace std;
int i;

void print_i()
{  cout << i << endl;
}

int main()
{  i = 123;
   print_i();
   return 0;
}



// namespace.cpp: The namespace concept.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 89.
#include <iostream>
using namespace std;

namespace A
{  int i = 10;
}

namespace B
{  int i = 20;
}

void fA()
{  using namespace A;
   cout << "In fA:   " 
        <<  A::i << " " << B::i << " " 
        << i << endl;   // In namespace A, i is A::i.
}

void fB()
{  using namespace B;
   cout << "In fB:   " 
        << A::i << " " << B::i << " " 
        << i << endl;   // In namespace B, i is B::i.
}
  
int main()
{  fA(); fB();
   cout << "In main: " << A::i << " " << B::i << endl;
   return 0;
}


// confuse.cpp: Confusing because of two variables i.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 90.
#include <iostream>
namespace A {int i = 10;};

int main()
{  int i = 20;
   using namespace A;
   std::cout << i << std::endl; // Output: 20
   return 0;
}


// addtoloc.cpp: A::i is added to the local scope of main.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 91.
#include <iostream>
namespace A { int i = 10; };
int i = 20;  

int main()
{  using A::i;
   std::cout << i << std::endl; // Output: 10
   return 0;
}


// refvar.cpp: Demonstration of a reference variable.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 92.
#include <iostream>
using namespace std;

int main()
{  int i, &x = i;
   i = 2; x *= 100;
   cout << "The value of i is now " << i << ".\n";
   cout << "Using x, we also find i = " << x << ".\n";
   return 0;
}


// argconv.cpp: Argument conversion from int to float.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 94.
#include <iostream>
using namespace std;

float f(float x)
{  return x * x + 1;
}

int main()
{  cout << f(5) << endl;
   return 0;
}


// statvar.cpp: A local static variable.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 96.
#include <iostream>
using namespace std;

void f()
{  static int i = 1;
   cout << i++ << endl;
}

int main()
{  f(); f();
   return 0;
}




// func.h: Header used in mainfile.cpp and funcfile.cpp.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 100.
void setk(int kk);
int f(int x);
int getcounter();

// mainfile.cpp: Demonstration of separate compilation.
//    The file funcfile.cpp should be linked.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 100.
#include <iostream>
#include "func.h"
using namespace std;
int main()
{  extern int n;
   n = 10;
   setk(5);
   cout << "f(2) = " << f(2) << endl;
   cout << "f(3) = " << f(3) << endl;
   cout << "Function f was called " << getcounter() 
        << " times.\n";
   return 0;
}

// funfile.cpp: Definitions of functions setk, f, and 
//              getcounter.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 101.
#include "func.h"
int n;

namespace 
{  int k;
   int counter = 0;
}

void setk(int kk){k = kk;}

int f(int x)
{  counter++;
   return k * x + n;
}

int getcounter(){return counter;}



//reffun.cpp: Reference as return value.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 106.
#include <iostream>
using namespace std;

int &maxim(int &x, int &y)
{  return (x > y ? x : y);
}

int main()
{  int a = 23, b = 15;
   cout << "a = " << a << "  b = " << b << endl;
   // First call to maxim:
   cout << "The larger of these is " << maxim(a, b) 
        << endl;
   // Second call to maxim:
   maxim(a, b) = 0;  // A function call as left-hand side!
   cout << 
   "The larger of a and b is set to 0. Thus we now have \n";
   cout << "a = " << a << "  b = " << b << endl;
   return 0;
}


// recfun.cpp: Demonstration of a recursive function.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 114.
#include <iostream>
using namespace std;
     
void f(int n)
{  if (n > 0) 
   {  f(n-2); cout << n << " "; f(n-1);
   }
}

int main()
{  int k;
   cout << "Enter k: "; cin >> k;
   cout << "Output:\n";
   f(k);
   cout << endl;
   return 0;
}



Chapter 5
=========

// minimum.cpp: Finding the smallest element of an 
//              integer array.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 119.
#include <iostream>
using namespace std;

int minimum(const int *a, int n)
{  int small = *a;
   for (int i=1; i<n; ++i) 
      if (*(a+i) < small) small = *(a+i);
   return small;
}

int main()
{  int table[10];
   cout << "Enter 10 integers: \n";
   for (int i=0; i<10; ++i) 
      cin >> table[i];
   cout << "\nThe minimum of these values is "
        << minimum(table, 10) << endl;
   return 0;
}


// constcast.cpp: An application of const_cast.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 124.
#include <iostream>
using namespace std;

// First function maxim:
int &maxim(int &x, int &y)
{  return (x > y ? x : y);
}

// Second function maxim:
inline const int &maxim(const int &x, const int &y)
{  return maxim(const_cast<int &>(x), const_cast<int &>(y));
}

int main()
{  int a = 5, b = 6, t;
   maxim(a, b) = 0;  
   // Assign 0 to the larger of a and b, that is, to b.
   const int c = 7, d = 8;
   t = maxim(c, d);
   // Assign the larger of c and d, that is 8, to t.
   cout << b << " " << t << endl; // 0 8
   return 0;
}


// strings.cpp: Sorting an array of strings
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 131.
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

int main()
{  const int n = 5;
   string a[n];
   cout << "  Enter five lines of text:\n";
   int i;
   for (i=0; i<n; ++i)
      getline(cin, a[i]);
   sort(a, a + n);
   cout << "  Output in alphabetic order:\n";
   for (i=0; i<n; ++i)
      cout << a[i] << endl;
   return 0;
}


// lines.cpp:
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 133.
#include <iostream>
#include <string>
using namespace std;

int main()
{  cout << string(20, '*')  // Output: ********************
        << endl;
   return 0;
}


// align.cpp: Align strings.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 144.
// There is version adapted for gcc below.
#include <string>
#include <iostream>
#include <iomanip>
using namespace std;

int main()
{  string names[3] = {"John", "George", "Jim"};
   int ages[3] = {9, 100, 24};
   for (int i=0; i<3; ++i)
      cout << setw(10) << left << names[i]
           << setw(3)  << right << ages[i] << endl;
   return 0;
}


// ptrarray.cpp: Pointer to array.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 147.
#include <iostream>
using namespace std;

int main()
{  int a[5], (*p)[5];
   p = &a;
   (*p)[3] = 123;
   cout << (*p)[3] << endl;
   return 0;
}


// parfun.cpp: Pointer to array as function parameter.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 147.
#include <iostream>
using namespace std;
void f(int (*q)[5])
{  (*q)[3] = 123;
}

int main()
{  int a[5];
   int (*p)[5];
   p = &a;
   f(p);
   cout << (*p)[3] << endl; // Output: 123
   return 0;
}


// parray.cpp: Pointer to array that is element of 
//             another array.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 148.
#include <iostream>
using namespace std;

int main()
{  int i, j, a[2][3] = {{8, 3, 6}, {5, 7, 0}}, (*p)[3];
   p = a;
   for (i=0; i<2; ++i) 
   {  for (j=0; j<3; ++j) 
         cout << p[i][j] << " ";
      cout << endl;
   }
   cout << sizeof(a)/sizeof(int) 
        << " elements in array a.\n";
   cout << sizeof(*p)/sizeof(int) 
        << " elements in each row.\n";
   return 0;
}


// progparm.cpp: Demonstration of using program parameters.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 150.
#include <iostream>
using namespace std;

int main(int argc, char *argv[])
{  cout << "argc    = " << argc << endl;
   for (int i=1; i<argc; ++i)
      cout << "argv[" << i << "] = " << argv[i] << endl;
   return 0;
}


// convdemo.cpp: In-memory format conversion
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 152.
// There is version adapted for gcc below.
#include <iostream>
#include <sstream>
#include <iomanip>
using namespace std;

int main()
{  // From string s to numerical value x:
   string s("1.2e-3");
   istringstream istr(s);
   double x;
   istr >> x;              // x = 0.0012
   cout << x << endl;      

   // From numerical value y to string t:
   double y = 10.3456789;
   ostringstream ostr;
   ostr << fixed << setw(8) << setprecision(3) << y;
   string t = ostr.str();  // t = "  10.346"
   cout << t << endl;      
   return 0;
}


// pfun.cpp: A function with a function as its argument.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 154.
#include <iostream>
using namespace std;

double funsum(int n, double (*f)(int k))    
{  double s = 0;
   int i;
   for (i=1; i<=n; ++i) s += (*f)(i); 
   return s;
}

double reciprocal(int k)
{  return 1.0/k;
}

double square(int k)
{  return static_cast<double>(k) * k;
}

int main()
{  cout << "Sum of five reciprocals: " 
        << funsum(5, &reciprocal) << endl;
   cout << "Sum of three squares: "
        << funsum(3, &square) << endl;
   return 0;
}



// newint.cpp: A very simple use of new and delete.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 156.
#include <iostream>
using namespace std;

int main()
{  int *p = new int(123);
   cout << ++*p << endl;   // Output: 124
   delete p;
   return 0;
}


// newarray.cpp: A dynamically allocated array.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 157.
#include <iostream>
using namespace std;
int main()
{  int i, n;
   cout << "Enter the sequence length n: ";
   cin >> n;
   float *a = new float[n];
   cout << "Enter n numbers: \n";
   for (i=0; i<n; ++i)
      cin >> a[i];
   cout << "Here are the same numbers in reverse order:\n";
   for (i=n-1; i>=0; --i)
      cout << a[i] << endl;
   delete[] a;
   return 0;
}


// newplace.cpp: The operator new with placement syntax.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 158.
#include <iostream>
using namespace std;

void *operator new(unsigned int nbytes, char *p)
{  static char *pFree = p; 
      // Because of 'static', pFree is initialized only once.
   cout << "nbytes = " << nbytes << endl; 
      // Output inserted to show what happens.
   void *p1 = reinterpret_cast<void *>(pFree);
   pFree += nbytes;
   return p1;
}

int main()
{  int *pInt;
   double *pDouble;
   char a[1000];
   pInt = new (a) int;
   *pInt = 123;
   pDouble = new (a) double;
   *pDouble = 4.56;
   // Show that array a contains the values 123 and 4.56:
   int *pI = reinterpret_cast<int*>(a);
   double *pD = reinterpret_cast<double*>(a + sizeof(int));
   if (*pI == 123 && *pD == 4.56)
      cout << "Array a used to store 123 and 4.56\n";
   return 0;
}


Chapter 6
=========

// person.h: Header for the class Person.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 163.
// There is version adapted for gcc below.
#include <string>
#include <iostream>
#include <iomanip>
using namespace std;

class Person {
public:
   Person(const string &s = "", int yr = 0, bool m = true)
   {  name = s;
      yearOfBirth = yr;
      male = m;
   }
   
   void setName(const string &s){name = s;}
   void setYear(int yr){yearOfBirth = yr;}
   void setMF(bool m){male = m;}
   
   const string &getName()const 
   {  return name;
   }
   int getAgeAtEnd2000()const 
   {  return 2000 - yearOfBirth;
   }
   void print()const
   {  cout << setw(10) << left << name 
           << setw(4) << right << getAgeAtEnd2000()
           << (male ? " (M)" : " (F)") << endl;
   }
private:
   string name;
   int yearOfBirth;
   bool male;
};



// persdemo.cpp: Demonstration of class Person.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 164.
#include <string>
#include <iostream>
#include "person.h"
using namespace std;

int main()
{  Person a("Mary", 1980, false), b;
   b.setName("John");
   b.setYear(1975);
   b.setMF(true);
   string s = a.getName();
   cout << s << endl;     // Mary
   b.print();             // John        25 M
   return 0;
}


// initcons.cpp: A constructor using the 
//               initialization syntax.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 167.
#include <iostream>
using namespace std;

class TestInit {
public:
   TestInit(int i, float &x): ii(i), xx(x){}
   void print()const{cout << ii << " " << xx << endl;}
private:
   const int ii;
   float &xx;
};

int main()
{  float y = 8.5F;
   TestInit t(2, y);
   t.print();       // 2 8.5
   return 0;
}


// datetest.cpp: An application of class DateDM.
//               The file dateDM.cpp must be linked.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 168.
#include <iostream>
#include "dateDM.h"
using namespace std;

int main()
{  int d, m;
   cout << "Enter day and month numbers of date 1: ";
   cin >> d >> m;
   DateDM date1(d, m);
   cout << "Enter day and month numbers of date 2: ";
   cin >> d >> m;
   DateDM date2(d, m);
   cout << "Difference in a non-leap year: "
        << date1.difference(date2) << " days\n";
   return 0;
}


// dateDM.h: Header file for date,
//   restricted to day and month.
//   Both are dates of a non-leap year.         
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 169.
class DateDM { 
public:
   DateDM(int d = 1, int m = 1);
   int difference(const DateDM &date)const;
private:
   int day, month;
};



// dateDM.cpp: Implementation of class DateDM.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 170.
#include <iostream>
#include "dateDM.h"
using namespace std;

namespace {
int calendar[] = 
   {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
}

DateDM::DateDM(int d, int m)
{  if (m < 1 || m > 12)
   {  cout << 
         "Invalid month number. Value 1 used instead.\n";
      m = 1;
   }
   if (d < 1 || d > calendar[m-1])
   {  cout << "Invalid day number. Value 1 used instead.\n";
      d = 1;
   }
   day = d;
   month = m;
}

int DateDM::difference(const DateDM &date2)const
{  int precedingDays[12];
   precedingDays[0] = 0;   // 0 for January, etc.
   for (int i=1; i<12; ++i)
      precedingDays[i] = precedingDays[i-1] + calendar[i-1];
   int dayNr1 = precedingDays[month-1] + day,
       dayNr2 = precedingDays[date2.month-1] + date2.day;
   return dayNr2 - dayNr1;
}



// datetst.cpp: An application of class DateDM.
//              The file dateDM.cpp must be linked.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 173.
#include <iostream>
#include "dateDM.h"
using namespace std;

DateDM readDate(int i)
{  int d, m;
   cout << "Enter day and month numbers of date " 
        << i << ": ";
   cin >> d >> m;
   return DateDM(d, m);
}   

int main()
{  DateDM date1 = readDate(1),
          date2 = readDate(2);
   cout << "Difference in a non-leap year: "
        << date1.difference(date2) << " days\n";
   return 0;
}


// operator.cpp: Overloaded + and << operators.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 176.
#include <iostream>
using namespace std;

class vec { 
public:
   vec(float xx = 0, float yy = 0): x(xx), y(yy) {}
   void printvec(ostream &os)const
   {  os << "(" << x << ", " << y << ")";
   }
   vec operator+(const vec &b)const
   {  return vec(x + b.x, y + b.y);
   }
private:
   float x, y;
};

ostream &operator<<(ostream &os, const vec &v)
{  v.printvec(os);
   return os;
}

int main()
{  vec u(3, 1), v(1, 2), s;
   s = u + v;    // This is our own operator +
   cout << "The sum of (3, 1) and (1, 2) is " 
        << s     // This is our own operator <<
        << endl;
   return 0;
}


// mod24.cpp: Modulo 24 addition.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 181.
#include <iostream>
using namespace std;

class mod24 { 
public:
   mod24(int x = 0)
   {  t = x % 24;
      if (t < 0) t += 24;
   }
   int getvalue()const{return t;}
private:
   int t; // t = 0, 1, 2, ..., 23
};

mod24 operator+(const mod24 &a, const mod24 &b)
{  return mod24(a.getvalue() + b.getvalue());
}

ostream &operator<<(ostream &os, const mod24 &x)
{  os << x.getvalue();
   return os;
}

istream &operator>>(istream &is, mod24 &x)
{  int y;
   is >> y;
   x = mod24(y);
   return is;
}

int main()
{  mod24 x(23), y(5);
   cout << "23 + 5 modulo 24 = " << x + y << endl;
   cout << "Same result:       " << x + 5 << endl;
   cout << "Same result:       " << 23 + y << endl;
   cout << "Different result:  " << 23 + 5 << endl;
   cout << "Enter two integers: ";
   cin >> x >> y;
   cout << "Taken modulo 24, they are equal to "
        << x << " and " << y << endl;
   cout << "x + y modulo 24 =  " << x + y << endl;
   return 0;
}



// rows0.cpp: A class with a pointer, preliminary version.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 188.
#include <iostream>
#include <string>
using namespace std;

class row { 
public:
   row(int n = 3)
   {  len = n; ptr = new int[n];
      for (int i=0; i<n; ++i) ptr[i] = 10 * i;
   }
   ~row() {delete[] ptr;}
   void printrow(const string &str)const
   {  cout << str;
      for (int i=0; i<len; ++i) cout << ptr[i] << ' ';
      cout << endl;
   }
private:
   int *ptr, len;
};

void tworows()
{  row r, s(5);
   r.printrow("r: ");
   s.printrow("s: ");
}

int main()
{  tworows();
   return 0;
}


// rows.cpp: A class with a pointer.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 194.
#include <iostream>
#include <string>
using namespace std;

class row { 
public:
   row(int n = 3);                // Default constructor
   row(const row &r);             // Copy constructor
   ~row();                        // Destructor
   row &operator=(const row &r);  // Copy assignment operator
   void printrow(const string &str)const;
private:
   int *ptr, len;
};

row::row(int n)              // default = 3 not repeated here
{  len = n; ptr = new int[n];
   for (int i=0; i<n; ++i) ptr[i] = 10 * i;
}

row::row(const row &r)            // Copy constructor
{  len = r.len;
   ptr = new int[len];
   for (int i=0; i<len; ++i) ptr[i] = r.ptr[i];
}

row::~row() {delete[] ptr;}       // Destructor

row &row::operator=(const row &r) // Copy assignment operator
{  if (&r != this)
   {  delete[] ptr;
      len = r.len;
      ptr = new int[len];
      for (int i=0; i<len; ++i) ptr[i] = r.ptr[i];
   }
   return *this;
}

void row::printrow(const string &str)const
{  cout << str;
   for (int i=0; i<len; ++i) cout << ptr[i] << ' ';
   cout << endl;
}

int main()
{  row r, s(5), t(s);
   r = s;
   r.printrow("r: ");
   s.printrow("s: ");
   t.printrow("t: ");
   return 0;
}


// derived.cpp: Classes Circle and Square derived from 
//              class Shape.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 200.
#include <iostream>
using namespace std;

class Shape {
public:
   Shape(double x = 0, double y = 0): xC(x), yC(y){}
   void printcenter()const
   {  cout << xC << " " << yC << endl;
   }
protected:
   double xC, yC;
};
const double pi = 3.1415926535897932;
class Circle: public Shape {
public:
   Circle(double xC, double yC, double r)
   :Shape(xC, yC)
   {  radius = r;
   }
   double area()const {return pi * radius * radius;}
private:
   double radius;
};

class Square: public Shape {
public:
   Square(double xC, double yC, double xP, double yP)
   :Shape(xC, yC)
   {  this->xP = xP; 
      this->yP = yP;
   }
   double area()const
   {  double a = xP - xC, b = yP - yC; 
      return 2 * (a * a + b * b); // See Figure 6.5
   }
private:
   double xP, yP;
};

int main()
{  double xCircle = 2, yCircle = 2.5, radius = 2;
   Circle circle(xCircle, yCircle, radius);
   cout << "Center of circle: "; circle.printcenter();
   cout << "Radius: " << radius << endl;
   cout << "Area of circle:   " << circle.area() << endl 
        << endl;
   double xCsquare = 3, yCsquare = 3.5,
         xP = 4.37, yP = 3.85;
   Square square(xCsquare, yCsquare, xP, yP);
   cout << "Center of square: "; square.printcenter();
   cout << "xP = " << xP << "  yP = " << yP << endl;
   cout << "Area of square:   " << square.area() << endl;
   return 0;
}



// ovride.cpp: The principle of overriding.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 204.
#include <iostream>
using namespace std;

class B {
public:
   int i;
   int compute()const{return i * i;}
};

class D: public B {
public:
   int i;
   int compute()const{return i + B::i;}
};

int main()
{  D d; 
   d.i = 5; d.B::i = 6;
   cout << "d.compute()    = " << d.compute() << endl; 
   cout << "d.B::compute() = " << d.B::compute() << endl; 
   return 0;
}



// nohiding.cpp: The principle of overriding.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 204.
// There is version adapted for gcc below.
#include <iostream>
using namespace std;
class B {
public:
   int f()const{return 1;}
};

class D: public B {
public:
   using B::f;
   int f(int k)const{return k;}
};

int main()
{  D d; 
   cout << "d.f()  = " << d.f() << endl;
   return 0;
}


// convdb.cpp: Conversion from derived to base class.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 206.
#include <iostream>
using namespace std;

class B {  
public: 
   int i;
   B(int ii = 0): i(ii){}
};  

class D: public B {
public: 
   float x;
   D(float xx): B(1), x(xx){}
}; 

int main()
{  B b(2), *pb = &b;
   D d(3.4F), *pd = &d;
   b = d;      // From derived to base: OK
   cout << "b: " << b.i << endl;
   cout << "d: " << pd->i << " " << pd->x << endl;

   pb = pd;    // Corresponding pointer types: OK 
// d = b;      // Would be an error; nor is a cast possible
// pd = pb;    // Would be an error
   pd = reinterpret_cast<D*>(pb);  
               // With cast: OK (if pb points to a D object)
   cout << "After pb = pd; pd = reinterpret_cast<D*>(pb); "
           "we have\n";
   cout << "d (reached via pd): " << pd->i << " " << pd->x 
        << endl;
   return 0;
}


// virtual.cpp: A virtual function in action.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 210.
#include <iostream>
using namespace std;

class animal {
public:
   virtual void print()const   // Virtual print function
   {  cout << "Unknown animal type.\n";
   }
   virtual ~animal(){} // Virtual destructor, discussed below
protected:
   int nlegs;
};

class fish: public animal {
public:
   fish(int n) {nlegs = n;}
   void print()const
   {  cout << "A fish has " << nlegs << " legs.\n";
   }
};

class bird: public animal {
public:
   bird(int n){nlegs = n;}
   void print()const
   {  cout << "A bird has " << nlegs << " legs.\n";
   }
};

class mammal: public animal {
public:
   mammal(int n){nlegs = n;}
   void print()const
   {  cout << "A mammal has " << nlegs << " legs.\n";
   }
};

int main()
{  animal *p[4];
   int i;
   p[0] = new fish(0);
   p[1] = new bird(2);
   p[2] = new mammal(4);
   p[3] = new animal;
   for (i=0; i<4; ++i) p[i]->print();
   for (i=0; i<4; ++i) delete p[i];
   return 0;
}


// late.cpp: This program shows that a class with a virtual
//           function takes more memory than a similar class
//           in which no function is virtual.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 212.
#include <iostream>
using namespace std;

class late  {public: int i; virtual void f(){i=1;}};
class early {public: int i; void f(){i=1;}};       

int main()
{  cout << "late:   " << sizeof(late) << " bytes.\n";
   cout << "early:  " << sizeof(early) << " bytes.\n";
   return 0;
}


// virtdest.cpp: A virtual destructor.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 213.
#include <iostream>
using namespace std;

class B {
public:
   virtual ~B(){}
};

class D: public B {
public:
   D(){a = new int[100000];}
   ~D(){delete[] a; cout << "Memory released!\n";}   
private:
   int *a;
};

void f()
{  B *p = new D;   // Memory is allocated for 100000 integers
   delete p;  // Released again, thanks to virtual destructor
}

int main()
{  f();
   return 0;
} 


// purevirt.cpp: A pure virtual function.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 216.
#include <iostream>
using namespace std;
class animal {
public:
   virtual void print()const = 0;
   virtual ~animal(){}
protected:
   int nlegs;
};

class fish: public animal {
public:
   fish(int n) {nlegs = n;}
   void print()const
   {  cout << "A fish has " << nlegs << " legs.\n";
   }
};

class bird: public animal {
public:
   bird(int n){nlegs = n;}
   void print()const
   {  cout << "A bird has " << nlegs << " legs.\n";
   }
};

class mammal: public animal {
public:
   mammal(int n){nlegs = n;}
   void print()const
   {  cout << "A mammal has " << nlegs << " legs.\n";
   }
};

int main()
{  animal *p[3];
   p[0] = new fish(0);
   p[1] = new bird(2);
   p[2] = new mammal(4);
   int i;  // With this way of declaring i, the program
           // is accepted by both VC++ and gcc.
   for (i=0; i<3; ++i) p[i]->print();
   for (i=0; i<3; ++i) delete p[i];
   return 0;
}


// dyncast.cpp: Run-time type information and dynamic_cast.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 218.
#include <iostream>
using namespace std;

class B {
public:
   virtual int f() = 0;
};

class D: public B {
public:
   int f(){return 1;}
};

class E: public B {
public:
   int f(){return 2;}
}; 

int main()
{  B *p;
   D d;
   p = &d;
   if (dynamic_cast<D*>(p))
      cout << p->f() << endl;  // Output: 1
   if (dynamic_cast<E*>(p))
      cout << p->f() << endl;  // Not executed
   return 0;
}


// statmem.cpp: Using a static class member to
//     count how many times the constructor
//     Person() is called.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 219.
#include <iostream>
#include <string>
using namespace std;

class Person {
public:
   Person(const string &s): name(s)
   {  count++;
   }
   void print()const
   {  cout << name << endl;
   }
   static void printcount()
   {  cout << "There are " << count 
           << " persons." << endl;

   }
private:
   string name;
   static int count;
};

int Person::count=0;

int main()
{  Person a("Mary"), b("Peter"), c("Charles"), *p;
   p = new Person("Kate");
   a.print(); b.print(); c.print(); p->print();
   Person::printcount();
   delete p;
   return 0;
}



// ptrmem.cpp: Pointers to class members.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 223.
#include <iostream>
using namespace std;

class Example {
public:
   Example(int ii, int jj): i(ii), j(jj){}
   int ivalue(){return i;}
   int jvalue(){return j;}
   int i, j;
};

int main()
{  Example u(1, 2), v(3, 4), w(5, 6), *pobject = &w;

   cout << "Pointer to function members: ";
   int (Example::*pf)();
   pf = &Example::ivalue;
   cout << (u.*pf)() << "  ";   // 1
   pf = &Example::jvalue;
   cout << (v.*pf)() << "  ";   // 4
   cout << (pobject->*pf)() << endl;// 6

   cout << "Pointer to data members:     ";
   int Example::*pd;
   pd = &Example::i;
   cout << u.*pd << "  ";   // 1
   pd = &Example::j;
   cout << v.*pd << "  ";   // 4
   cout << pobject->*pd << endl;// 6
   return 0;
}


// charflo.cpp: An array of unions.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 225.
#include <iostream>
using namespace std;

union charfloat {char ch; float x;};

int main()
{  const int n = 100000;
   charfloat a[n];
   for (int i=0; i<n; ++i)
   {  if (i % 2 == 0)
         a[i].ch = 'A' + i % 26;
      else
         a[i].x = 1.0F/i;
   }
   cout << "a[0].ch = " << a[0].ch << endl;
   cout << "a[1].x  = " << a[1].x << endl;
   cout << "a[2].ch = " << a[2].ch << endl;
   cout << "a[3].x  = " << a[3].x << endl;
   cout << "sizeof(a[0]) = " << sizeof(a[0]) << endl;
   return 0;
}


// tempobj.cpp: A (not completely useless) temporary object.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 227.
#include <iostream>
using namespace std;

class Example {
public:
   void print(){cout << "Hello\n";}
};

int main()
{  Example().print();  // Output: Hello
   return 0;
}


// calloper.cpp: A call-operator
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 228.
#include <iostream>
using namespace std;

class iprint {
public:
   void operator()(int i)const{cout << i << endl;}
};

int main()
{  iprint x;
   x(123);           // Output: 123
   iprint()(456);    // Output: 456
   return 0;
}


// funobj.cpp: Function object used to pass functions to
//             another function.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 229.
#include <iostream>
using namespace std;

class fun {
public:
   virtual double operator()(int k)const = 0;
};

class reciprocal: public fun {
public:
   double operator()(int k)const
   {  return 1.0/k;
   }
};      

class square: public fun {
public:
   double operator()(int k)const
   {  return static_cast<double>(k) * k;
   }
};

double funsum(int n, const fun &f)
{  double s = 0;
   int i;
   for (i=1; i<=n; ++i) s += f(i); 
   return s;
}

int main()
{  cout << "Sum of five reciprocals: " 
        << funsum(5, reciprocal()) << endl;
   cout << "Sum of three squares: "
        << funsum(3, square()) << endl;
   return 0;
}


Chapter 7
=========

// ftempl.cpp: A function template for swapping the values
//             of two objects of a given, arbitrary type.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 233.
#include <iostream>
using namespace std;

template <class T>
void swapObjects(T &x, T &y){T w = x; x = y; y = w;}

int main()
{  int i = 1, j = 2;
   swapObjects(i, j);  // Now i = 2 and j = 1.
   float u = 3.4F, v = 5.6F;
   swapObjects(u, v); // Now u = 5.6 and v = 3.4.
   cout << i << " " << j << " " << u << " " << v << endl;
   return 0;
}



// swap.h: A header file defining the function template
//         swapObjects.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 235.
template <class T>
void swapObjects(T &x, T &y){T w = x; x = y; y = w;}


// swapdemo.cpp: Demonstration of a function template
//               defined in the header file swap.h.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 235.
#include <iostream>
#include "swap.h"
using namespace std;
int main()
{  int i = 1, j = 2; 
   swapObjects(i, j);
   float u = 3.4F, v = 5.6F; 
   swapObjects(u, v);
   cout << i << " " << j << "   " << u << " " << v << endl;
      // Output: 2 1   5.6 3.4
   return 0;
}


// ftempl2.cpp: Function templates with two parameters.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 235.
#include <iostream>
using namespace std;

template <class T, class U>
U multsum(T x, T y, U u, int n)
{  return x + y + n * u;
}

int main()
{  cout << multsum(4, 3, 0.5, 5) << endl; // Output: 9.5
   return 0;
}


// powers.cpp: Two power functions resulting from a template.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 236.
#include <iostream>
using namespace std;

template <class basetype, class resulttype>
resulttype power(basetype a, int n)
{  resulttype x = 1;
   for (int i=1; i<=n; ++i) 
      x *= a;
   return x;
}

int main()     
{  cout << power<int, long>(10, 9) << endl;
   cout << power<double, double>(10, 30) << endl;
   return 0;
}


// ptrpar.cpp: Template parameter used for pointer.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 237.
#include <iostream>
using namespace std;

template <class T>
T arraysum(const T *p, int n)
{  T s = 0;
   for (int i=0; i<n; ++i)
      s += p[i];
   return s;
}

int main()
{  int a[] = {1, 2, 3};
   double b[] = {4.5, 6.7};
   cout << arraysum(a, 3) << endl;  // Output: 6
   cout << arraysum(b, 2) << endl;  // Output: 11.2
   return 0;
}


// cltempl.cpp: A class template.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 237.
#include <iostream>
using namespace std;

template <class T>
class vec { 
public:
   vec(T xx = 0, T yy = 0): x(xx), y(yy) {}
   void printvec(ostream &os)const
   {  os << "(" << x << ", " << y << ")";
   }
   vec<T> operator+(const vec<T> &b)const
   {  return vec<T>(x + b.x, y + b.y);
   }
private:
   T x, y;
};

template <class T>
ostream &operator<<(ostream &os, const vec<T> &v)
{  v.printvec(os);
   return os;
}

int main()
{  vec<int> uInt(1, 2), vInt(3, 4), sInt;
   vec<float> uFloat(1.1F, 2.2F), vFloat(3.3F, 4.4F), sFloat;
   sInt = uInt + vInt;  
   sFloat = uFloat + vFloat;
   cout << sInt << endl;
   cout << sFloat << endl;
   return 0;
}


// sequence.cpp: A class template with three arguments.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 240.
#include <iostream>
using namespace std;

template <class T, int n = 5, class S = T>
class sequence {
public:   
   sequence(T start, T incr);
   S sum();
private:
   T r[n];
};

template <class T, int n, class S>
sequence<T, n, S>::sequence(T start, T incr)
{  for (int i=0; i<n; ++i) r[i] = start + i * incr;
}

template <class T, int n, class S>
S sequence<T, n, S>::sum()
{  S s = 0;
   for (int i=0; i<n; ++i) s += r[i];
   return s;
}

int main()
{  sequence<int, 4, long> a_int(1, 2);     // 4 elements
   sequence<float, 3> a_float(0.3F, 0.1F); // 3 elements
   sequence<double> a_double(1.0, 0.1);    // 5 elements 
   cout << a_int.sum() << " "      // 16
        << a_float.sum() << " "    // 1.2
        << a_double.sum() << endl; // 6
   return 0;
}


// istring.cpp: The template basic_string applied to 
//              integers.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 242.
// This program does not compile with gcc (see version below).
#include <string>
#include <iostream>
using namespace std;

typedef basic_string<int> istring; // int instead of char!

int main()
{  istring s;
   s += 123;
   s += 98;
   s += 45;
   for (int i=0; i<s.length(); ++i)
      cout << s[i] << endl;
   return 0;
}


// quadeq.cpp: Solving a quadratic equation with 
//             complex numbers.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 243.
#include <iostream>
#include <complex>
using namespace std;

int main()
{  complex<double> a, aa, b, c, D, sqrtD, x1, x2;
   cout << 
      "Enter the complex numbers a (nonzero), b, and c:\n";
   cin >> a >> b >> c;
   if (a == 0.0)
   {  cout << "a must be nonzero.\n";
      return 1;
   }
   D = b * b - 4.0 * a * c;
   sqrtD = sqrt(D);
   aa = 2.0 * a;
   x1 = (-b + sqrtD)/aa;
   x2 = (-b - sqrtD)/aa;
   cout << "Solution (complex):\n" 
        << x1 << " " << x2 << endl;
   return 0;
}




Chapter 8
=========

// except1.cpp: Example of exception handling
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 249.
#include <iostream>
using namespace std;
void detail(int k)
{  cout << "Start of detail function.\n";
   if (k == 0) throw 123;
   cout << "End of detail function.\n";
}

void compute(int i)
{  cout << "Start of compute function.\n";
   detail(i);
   cout << "End of compute function.\n";
}

int main()
{  int x;
   cout << "Enter x (0 will throw an exception): "; 
   cin >> x;
   try {compute(x);}
   catch (int i) {cout << "Exception: " << i << endl;}
   cout << "The End.\n";
   return 0;
}


// except2.cpp: Two handlers in a try-block.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 251.
#include <iostream>
using namespace std;

int main()
{  int i;
   char ch;
   cout << "Enter an integer, followed by some "
           "nonnumeric character:\n";
   try 
   {  cin >> i >> ch;
      if (i == 0) throw 0;
      if (ch == '?') throw '?';
   }
   catch (int) {cout << "Zero entered.\n";}
   catch (char) {cout << "Question mark entered.\n";}
   cout << "The End.\n";
   return 0;
}


// except3.cpp: Re-throwing an exception.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 253.
#include <iostream>
using namespace std;

void h()           // Lowest level
{  throw 0;
}

void g()           // Intermediate level
{  try {h();}
   catch(int)
   {  cout << "Catch in g\n"; 
      throw; // This statement re-throws the exception.
   }
}

int main()         // Highest level
{  try {g();}
   catch(int){cout << "Catch in main\n";}
   return 0;
}


// except4.cpp: The simplest possible exception class.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 254.
#include <iostream>
using namespace std;

class MyException { };

int main()
{  try
   {  throw MyException();
   } 
   catch (MyException)
   {  cout << "Exception thrown.\n"; // This text is displayed
   }
   return 0;
}


// except5.cpp: Catch with base class matches throw with
//              derived class.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 254.
#include <iostream>
using namespace std;

class B { };
class D: public B { };

int main()
{  try
   {  throw D();
   } 
   catch (B)
   {  cout << "Exception thrown.\n"; // This text is displayed
   }
   return 0;
}


// except6.cpp: Our own subscripting operator with
//              array-bounds checking.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 255.
#include <iostream>
using namespace std;

class OutOfBounds {
public:
   OutOfBounds(int ii): i(ii){}
   int indexValue(){return i;}
private:
   int i;
};
class Array {     // For int array of length 10.
public:
   int &operator[](int i)
   {  if (i < 0 || i >= 10) throw OutOfBounds(i);
      return a[i];
   }
private:
   int a[10];
};
int main()
{  Array a;
   try
   {  a[3] = 30;
      cout << "a[3] = " << a[3] << endl;
      a[100] = 1000;
      cout << "a[1000] = " << a[1000] << endl;
   }

   catch (OutOfBounds error)
   {  cout << "Subscript value " << error.indexValue()
           << " out of bounds.\n";
   }
   return 0;
}


// newtest1.cpp: Default exception for 'new'.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 256.
#include <iostream>
#include <climits>
#include <new>
using namespace std;

int main()
{  char *p;
   try
   {  for (;;) 
      {  p = new char[INT_MAX];
         if (p == NULL)
         {  cout << "The operator new returns NULL (= 0).\n";
            cout << 
            "This is not in accordance with Standard C++.\n";
            exit(1);
         }
      }
   }
   catch (bad_alloc) 
   {  cout << "A bad_alloc exception has been thrown, "
              "which is correct.\n";
   }
   return 0;
}



Chapter 9
=========

// itera.cpp: Iterator-based version of introstl.cpp.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 260.
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;

int main()
{  vector<string> v;
   cout << "Enter lines of text to be sorted,\n";
   cout << "followed by the word stop:\n";
   for (;;)
   {  string s;
      getline(cin, s);
      if (s == "stop")
         break;
      v.push_back(s);
   }
   sort(v.begin(), v.end());
   cout << "The same lines after sorting:\n";
   for (vector<string>::iterator i=v.begin(); i!=v.end(); ++i)
      cout << *i << endl;
   return 0;
}


// itdeque.cpp: Using a deque instead of a vector.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 262.
#include <iostream>
#include <string>
#include <deque>
#include <algorithm>
using namespace std;

int main()
{  deque<string> v;
   cout << "Enter lines of text to be sorted,\n";
   cout << "followed by the word stop:\n";
   for (;;)
   {  string s;
      getline(cin, s);
      if (s == "stop")
         break;
      v.push_front(s);
   }
   sort(v.begin(), v.end());
   cout << "The same lines after sorting:\n";
   for (deque<string>::iterator i=v.begin(); i!=v.end(); ++i)
      cout << *i << endl;
   return 0;
}


// insdel.cpp: Insertions and deletions in a list.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 264.
#include <string>
#include <iostream>
#include <list>          
using namespace std;

void showlist(const string &str, const list<int> &L)
{  list<int>::const_iterator i;
   cout << str << endl << "  ";
   for (i=L.begin(); i != L.end(); ++i)
      cout << *i << " ";
   cout << endl;
}          

int main()
{  list<int> L;                
   int x;
   cout << "Enter positive integers, followed by 0:\n";
   while (cin >> x, x != 0)
      L.push_back(x);
   showlist("Initial list:", L);
   L.push_front(123);
   showlist("After inserting 123 at the beginning:", L);
   list<int>::iterator i = L.begin();
   L.insert(++i, 456);
   showlist(
      "After inserting 456 at the second position:", L);
   i = L.end(); 
   L.insert(--i, 999);
   showlist(
      "After inserting 999 just before the end:", L);
   i = L.begin(); x = *i;
   L.pop_front(); 
   cout << "Deleted at the beginning: " << x << endl;
   showlist("After this deletion:", L);
   i = L.end(); x = *--i;
   L.pop_back();
   cout << "Deleted at the end: " << x << endl;
   showlist("After this deletion:", L);
   i = L.begin();
   x = *++i; cout << "To be deleted: " << x << endl;
   L.erase(i);
   showlist("After this deletion (of second element):", 
      L);
   return 0;
}


// stack1.cpp: Using a stack to read a number sequence
//    of arbitrary length and to display this sequence
//    in the reverse order.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 266.
#include <iostream>
#include <vector>
#include <stack>
using namespace std;

int main()
{  stack <int, vector<int> > S;
   int x;
   cout << 
      "Enter some integers, followed by a letter:\n";
   while (cin >> x) S.push(x);
   while (!S.empty())
   {  x = S.top();
      cout << "Size: " << S.size() 
         << "    Element at the top: " << x << endl;
      S.pop();
   }
   return 0;
}



// stackcmp.cpp: Stack assignments and comparisons.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 267.
#include <iostream>
#include <vector>
#include <stack>
using namespace std;
int main()
{  stack <int, vector<int> > S, T, U;
   S.push(10); S.push(20); S.push(30);
   cout << "Pushed onto S: 10 20 30\n";
   T = S;
   cout << "After T = S; we have ";
   cout << (S == T ? "S == T" : "S != T") << endl;
   U.push(10); U.push(21);
   cout << "Pushed onto U: 10 21\n";   
   cout << "We now have ";
   cout << (S < U ? "S < U" : "S >= U") << endl;
   return 0;
}



// queue.cpp: Using a queue; a demonstration of the
//            member functions push, pop, back, and front.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 269.
#include <iostream>
#include <list>
#include <queue>

using namespace std;

int main()
{  queue <int, list<int> > Q;
   Q.push(10); Q.push(20); Q.push(30);
   cout << "After pushing 10, 20 and 30:\n";
   cout << "Q.front() = " << Q.front() << endl;
   cout << "Q.back()  = " << Q.back() << endl;
   Q.pop();
   cout << "After Q.pop():\n";
   cout << "Q.front() = " << Q.front() << endl;
   return 0;
}



// prqueue.cpp: A priority queue; a demonstration of the
//              member functions push, pop, empty, and top.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 270.
#include <iostream>
#include <vector>
#include <functional>
#include <queue>
using namespace std;

int main()
{  priority_queue <int, vector<int> > P;
   int x;
   P.push(123); P.push(51); P.push(1000); P.push(17);
   while (!P.empty())
   {  x = P.top();
      cout << "Retrieved element: " << x << endl;
      P.pop();
   }
   return 0;
}



// lastdig.cpp: A priority queue; P.top() is the element
//              whose last digit is less than (or equal to) 
//              that of the other elements.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 270.
#include <iostream>
#include <vector>
#include <queue>
using namespace std;

class CompareLastDigits {
public:
   bool operator()(int x, int y)
   {  return x % 10 > y % 10;
   }
};

int main()
{  priority_queue <int, vector<int>, 
      CompareLastDigits> P;
   int x;
   P.push(123); P.push(51); P.push(1000); P.push(17);
   while (!P.empty())
   {  x = P.top();
      cout << "Retrieved element: " << x << endl;
      P.pop();
   }
   return 0;
}



// find1.cpp: Finding a given value in a list.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 272.
#include <iostream>
#include <list>
#include <algorithm>
using namespace std;
int main()
{  int x;
   list<int> v;
   v.push_back(2); v.push_back(5); v.push_back(8);
   cout << "Enter an integer to be found in {2, 5, 8}:\n";
   cin >> x;
   list<int>::iterator i = find(v.begin(), v.end(), x);
   if (i == v.end()) cout << "Not found.";
   else
   {  cout << "Found "; 
      if (i == v.begin()) 
         cout << "as the first element.";
      else cout << "after " << *--i;
   }
   cout << endl;
   return 0;
}



// copyio.cpp: Using the copy algorithm for I/O.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 275.
#include <fstream>
#include <iostream>
#include <iterator>
#include <vector>
using namespace std;
typedef istream_iterator<int> istream_iter;

int main()
{  vector<int> a;
   ifstream file("example.txt");
   if (file.fail())
   {  cout << "Cannot open file example.txt.\n";
      return 1;
   }
   copy(istream_iter(file), istream_iter(), 
      inserter(a, a.begin()));
   copy(a.begin(), a.end(), 
      ostream_iterator<int>(cout, " "));
   cout << endl;
   return 0;
}



// sortarr.cpp: Sorting an array.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 276.
#include <iostream>
#include <algorithm>
using namespace std;

int main()
{  int a[10], x, n = 0, *p;
   cout << "Enter at most 10 positive integers, "
      "followed by 0:\n";
   while (cin >> x, x != 0 && n < 10) a[n++] = x;
   sort(a, a+n);
   cout << "After sorting: \n";
   for (p=a; p != a+n; ++p) cout << *p << " ";
   cout << endl;
   return 0;
}



// list1.cpp: The list member functions sort and unique.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 280.
#include <iostream>
#include <list>
using namespace std;

void out(const char *s, const list<int> &L)
{  cout << s;
   copy(L.begin(), L.end(), 
      ostream_iterator<int>(cout, " "));
   cout << endl;
}

int main()
{  list<int> L(5, 123);
   L.push_back(100);
   L.push_back(123);
   L.push_back(123);
   out("Initial contents: ", L);
   L.unique();
   out("After L.unique(): ", L);
   L.sort();
   out("After L.sort():   ", L);
   return 0;
}


// splice.cpp: Splicing.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 281.
#include <iostream>
#include <list>
using namespace std;
int main()
{  list<int> L;
   list<int>::iterator i, j1, j2, j;
   for (int k = 10; k <= 80; k += 10)
   {  L.push_back(k);
      j = L.end(); 
      if (k == 20) j1 = --j; else
      if (k == 50) j2 = --j; else
      if (k == 70) i = --j;
   }
   L.splice(i, L, j1, j2);
   copy(L.begin(), L.end(), ostream_iterator<int>(cout, " "));
   cout << endl;
   return 0;
}



// removal.cpp: The remove algorithm.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 282.
#include <iostream>
#include <algorithm>
#include <list>
#include <iterator>
using namespace std;

int main()
{  int a[6] = {1, 4, 1, 3, 1, 2};
   list<int> L(a, a + 6);
   list<int>::iterator new_end = 
      remove(L.begin(), L.end(), 1);
   cout << L.size() << endl;  // 6 (still garbage at the end)
   L.erase(new_end, L.end()); // Remove last three elements
   cout << L.size() << endl;  // 3 (garbage removed)
   return 0;
}




// removemf.cpp: The list member function remove.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 283.
#include <iostream>
#include <list>
using namespace std;

void out(const char *s, const list<int> &L)
{  cout << s;
   copy(L.begin(), L.end(), 
      ostream_iterator<int>(cout, " "));
   cout << endl;
}

int main()
{  int a[6] = {1, 4, 1, 3, 1, 2};
   list<int> L(a, a + 6);
   out("Initial sequence L:\n", L);
   L.remove(1);
   out("After L.remove(1):\n", L);
   return 0;
}


// lstmerge.cpp: The list member function merge. 
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 284.
#include <iostream>
#include <list>
using namespace std;
void out(const char *s, const list<int> &L)
{  cout << s;
   copy(L.begin(), L.end(), ostream_iterator<int>(cout, " "));
   cout << endl;
}
int main()
{  list<int> L1, L2, L3;
   list<int>::iterator new_end;
   L1.push_back(10); L1.push_back(20); L1.push_back(30); 
   L2.push_back(15); L2.push_back(35);
   out("Initial sequence L1:\n", L1);
   out("Initial sequence L2:\n", L2);
   L1.merge(L2);
   out("After L1.merge(L2):\n", L1);
   return 0;
}



// mergealg.cpp: The merge algorithm.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 285.
#include <algorithm>
#include <list>
#include <vector>
#include <iostream>
using namespace std;

int main()
{  int a[3] = {10, 20, 30};
   list<int> L;
   L.push_back(15); L.push_back(35);
   vector<int> v;

   merge(a, a + 3, L.begin(), L.end(), 
      inserter(v, v.begin()));
   for (int i=0; i<v.size(); ++i)
      cout << v[i] << " ";  // 10 15 20 30 35
   cout << endl;
   return 0;
}


// set2.cpp: Two identical sets, created differently.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 287.
#include <iostream>
#include <set>
using namespace std;

int main()
{  set<int> S, T;
   S.insert(10); S.insert(20); S.insert(30); 
   S.insert(10);
   T.insert(20); T.insert(30); T.insert(10);
   if (S == T) cout << "Equal sets, containing:\n";
   for (set<int>::iterator i = T.begin(); 
      i != T.end(); ++i)
         cout << *i << " ";
   cout << endl;
   return 0;
}



// multiset.cpp: Two multisets.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 288.
#include <iostream>
#include <set> 
using namespace std;

int main()
{  multiset<int> S, T;
   S.insert(10); S.insert(20); S.insert(30);
   S.insert(10);
   T.insert(20); T.insert(30); T.insert(10);
   if (S == T) cout << "Equal multisets:\n"; else
               cout << "Unequal multisets:\n";
   cout << "S: ";
   copy(S.begin(), S.end(), ostream_iterator<int>(cout, " "));
   cout << endl;
   cout << "T: ";
   copy(T.begin(), T.end(), ostream_iterator<int>(cout, " "));
   cout << endl;
   return 0;
}



// map1.cpp: First application of a map.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 289.
#include <iostream>
#include <string>
#include <map>
using namespace std;

int main()
{  map<string, long> D;
   D["Johnson, J."]  = 12345;
   D["Smith, P."]    = 54321;
   D["Shaw, A."]     = 99999;
   D["Atherton, K."] = 11111;
   string GivenName;
   cout << "Enter a name: "; 
   getline(cin, GivenName);
   if (D.find(GivenName) != D.end())
      cout << "The number is " << D[GivenName]; 
   else
      cout << "Not found.";
   cout << endl;
   return 0;
}



// multimap.cpp: A multimap containing equal keys.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 290.
#include <iostream>
#include <string>
#include <map> 
using namespace std;

typedef multimap<string, long> mmtype;

int main()
{  mmtype D;
   D.insert(mmtype::value_type("Johnson, J.", 12345));
   D.insert(mmtype::value_type("Smith, P.", 54321));
   D.insert(mmtype::value_type("Johnson, J.", 10000));
   cout << "There are " << D.size() << " elements.\n";
   return 0;
}



// pairs.cpp: Operations on pairs.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 291.
#include <iostream>
#include <utility>
using namespace std;

int main()
{  pair<int, double> P(123, 4.5), Q; 
   Q = pair<int, double>(122, 4.5);
   cout << "P: " << P.first << " " << P.second << endl;
   cout << "Q: " << Q.first << " " << Q.second << endl;
   if (P > Q) cout << "P > Q\n";
   ++Q.first;
   cout << "After ++Q.first: ";
   if (P == Q) cout << "P == Q\n";
   return 0;
}



// rel_ops.cpp: Relational operators.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 292.
// There is a version adapted for gcc below.
#include <iostream>
#include <utility>
using namespace std;
using namespace std::rel_ops;

class Example {
public:
   Example(int i = 0, int j = 0): a(i), b(j){}
   int a, b;
   bool operator==(const Example &y)const
   {  return a == y.a && b == y.b;
   }

   bool operator<(const Example &y)const
   {  return a < y.a || a == y.a && b < y.b;
   }
};
int main()
{  Example u(1, 3), v(1, 2);
   if (u > v)  cout << "u > v\n";
   if (u >= v) cout << "u >= v\n";
   if (u != v) cout << "u != v\n";
   if (u <= v) cout << "u <= v\n";
   return 0;
}


// funobj1.cpp: A simple function object.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 294.
#include <iostream>
using namespace std;

struct sq {
   int operator()(int x)const {return x * x;}
};

int main()
{  cout << "5 * 5 = " << sq()(5) << endl; // 25
   return 0;
}



// funobj2.cpp: Function classes used as
//              template arguments.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 295.
#include <iostream>
using namespace std;

struct square {
   int operator()(int x)const {return x * x;}
};

struct cube {
   int operator()(int x)const {return x * x * x;}
};

template <class T>
class cont {
public:
   cont(int i): j(i){}
   void print()const {cout << T()(j) << endl;}
private:
   int j;
};

int main()
{  cont<square> sqobj(10);
   cont<cube> cubeobj(10);
   sqobj.print();   // Output (= area of square):    100 
   cubeobj.print(); // Output (= contents of cube): 1000
   return 0;
}



// funobj3.cpp: The operator() function is a
//              binary predicate.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 296.
// This program is not accepted by gcc (see version below).
#include <iostream>
using namespace std;

template <class T>
struct LessThan {
   bool operator()(const T &x, const T &y)const
   {  return x < y;
   }
};

struct CompareLastDigits {
   bool operator()(int x, int y)const
   {  return x % 10 < y % 10;
   }
};

template <class T, class Compare>
class PairSelect {
public:
   PairSelect(const T &x, const T &y): a(x), b(y){}
   void PrintSmaller()const
   {  cout << (Compare()(a, b) ? a : b) << endl;
   }
private:
   T a, b;
};

int main()
{  PairSelect<double, LessThan<double> > P(123.4, 98.7);
   P.PrintSmaller(); // Output: 98.7
   
   PairSelect<int, CompareLastDigits> Q(123, 98);
   Q.PrintSmaller(); // Output: 123 (because 3 < 8)
   return 0;
}



// binder.cpp: The bind2nd adaptor used to count how
//             many array elements are less than 100.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 299.
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
 
int main()    
{  int a[10] = {800, 3, 4, 600, 5, 6, 800, 71, 100, 2},
       n; 
   n = count_if(a, a + 10, bind2nd(less<int>(), 100));
   cout << n << endl; // Output: 6
   return 0;
}



// not2demo.cpp: The not2 adaptor demonstrated.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 300.
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;

int main()
{  int a[5] = {50, 30, 10, 40, 20};
   sort(a, a+5, not2(less<int>()));
   for (int i=0; i<5; ++i) cout << a[i] << " ";
   // Output: 50 40 30 20 10
   cout << endl;
   return 0;
}



// not1demo.cpp: The not1 adaptor demonstrated.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 300.
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;

int main()
{  int a[10] = {800, 3, 4, 600, 5, 6, 800, 71, 100, 2},
       n;       
   // Count how many elements are not less than 100:
   n = count_if(a, a + 10, 
      not1(bind2nd(less<int>(), 100)));
   cout << n << endl; // Output: 4
   return 0;
}



// not2own.cpp: The not2 adaptor applied to a function
//              object of our own.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 302.
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;

struct iLessThan: binary_function<int, int, bool> {
bool operator()(int x, int y)const {return x < y;}
};

int main()
{  int a[5] = {50, 30, 10, 40, 20};
   sort(a, a+5, not2(iLessThan()));
   for (int i=0; i<5; ++i) cout << a[i] << " ";
   // Output: 50 40 30 20 10
   cout << endl;
   return 0;
}



// not1own.cpp: The not1 adaptor applied to a
//              function object of our own.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 302.
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;

struct LessThan100: unary_function<int, bool> {
bool operator()(int x)const {return x < 100;}
};

int main()
{  int a[10] = {800, 3, 4, 600, 5, 6, 800, 71, 100, 2},
       n;       
   // Count how many elements are not less than 100:
   n = count_if(a, a+10, not1(LessThan100()));
   cout << n << endl; // Output: 4
   return 0;
}



// negate.cpp: The transform algorithm and negate<T>.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 303.
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
int main()
{  int a[5] = {10, 20, -18, 40, 50}, b[5];
   transform(a, a + 5, b, negate<int>());
   for (int i=0; i<5; ++i) cout << b[i] << "  ";
   // Output: -10  -20  18  -40  -50
   cout << endl;
   return 0;
}



// plus.cpp: The transform algorithm and plus<T>.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 304.
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
int main()
{  int a[5] = {10, 20, -18, 40, 50}, 
       b[5] = { 2,  2,   5,  3,  1}, s[5];
   transform(a, a + 5, b, s, plus<int>());
   for (int i=0; i<5; ++i) cout << s[i] << "  ";
    // Output: 12  22  -13  43  51
   cout << endl;
   return 0;
}



// compute.cpp: The transform algorithm and a 
//              function object of our own.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 305.
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
struct compute: binary_function<int, int, int> {
   int operator()(int x, int y)const{return x + 2 * y;}
};

int main()
{  int a[5] = {10, 20, -18, 40, 50}, 
       b[5] = { 2,  2,   5,  3,  1}, result[5];
   transform(a, a + 5, b, result, compute());
   for (int i=0; i<5; ++i) cout << result[i] << "  ";
      // Output: 14  24  -8  46  52
   cout << endl;
   return 0;
}



// compute1.cpp: Replacing a[i] with 1.0/(a[i]*a[i]+1). 
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 305.
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
struct compute1: unary_function<int, double> {
   double operator()(int x)const{return 1.0/(x*x + 1);}
};

int main()
{  int a[5] = {2, 0, 1, 3, 7};
   double b[5];
   transform(a, a + 5, b, compute1());
   for (int i=0; i<5; ++i) cout << b[i] << " ";
   // Output: 0.2 1 0.5 0.1 0.02
   cout << endl;
   return 0;
}



// copy3.cpp: Copying a vector using 'inserter'.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 306.
#include <iostream>
#include <vector>
#include <list>
using namespace std;

int main()
{  int a[4] = {10, 20, 30, 40};
   vector<int> v(a, a+4);
   list<int> L(2, 123);
   copy(v.begin(), v.end(), inserter(L, L.end()));
   list<int>::iterator i;
   for (i=L.begin(); i != L.end(); ++i)
      cout << *i << " "; // Output: 123 123 10 20 30 40
   cout << endl;
   return 0;
}



// c_iter.cpp: const_iterator and 
//             const_reverse_iterator.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 307.
#include <iostream>
#include <list>
using namespace std;

void showlist(const list<int> &x)
{  // Forward:
   list<int>::const_iterator i;
   for (i=x.begin(); i != x.end(); ++i)
      cout << *i << " ";
   cout << endl;   //  Output: 10 20 30
   // Backward:
   list<int>::const_reverse_iterator j;
   for (j=x.rbegin(); j != x.rend(); ++j)
      cout << *j << " ";
   cout << endl;   //  Output: 30 20 10
}          
int main()
{  list<int> L;
   L.push_back(10); L.push_back(20); L.push_back(30);
   showlist(L);
   return 0;
}



// outiter.cpp: Output iterator; assignment statements
//              reading data from a file.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 308.
#include <iostream>
#include <iterator>
using namespace std;

int main()
{  ostream_iterator<int> i(cout, "abc\n");
   *i++ = 123;
   *i++ = 456;
   cout << endl;
   return 0;
}


// initer.cpp: Input iterator; assignment statements
//             performing input from a file.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 308.
#include <iostream>
#include <fstream>
#include <iterator>
using namespace std;
int main()
{  ifstream file("num.txt");
   if (file)
   {  istream_iterator<int> i(file), eof;
      int x;
      while (i != eof)
      {  x = *i++;
         cout << x << " ";
      }
   }  else cout << "Cannot open file num.txt.";
   cout << endl;
   return 0;
}



// nonmodif.cpp: Nonmodifying algorithms.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 310.
#include <iostream>
#include <vector>
#include <functional>
#include <algorithm>
using namespace std;

void display_greater_than10(int x)
{  if (x > 10) cout << x << " ";
}

int main()
{  int a[8] = {10, 12, 7, 3, 17, 7, 7, 3};
   vector<int> v(a, a+8);
   typedef vector<int>::iterator itType;
   itType i;

   for_each(v.begin(), v.end(), display_greater_than10);
   cout << endl;                   // 12 17
   
   i = find(v.begin(), v.end(), 7);  
   cout << i - v.begin() << endl;  // 2 (v[2] = 7)

   i = find_if(v.begin(), v.end(), 
      bind2nd(greater<int>(), 13));
   cout << i - v.begin() << endl;  // 4 (v[4] > 13)

   int b[3] = {17, 7, 3};
   i = find_first_of(v.begin(), v.end(), b, b + 3);
   cout << i - v.begin() << endl;  // 2 (v[2] = 7 occurs in b)

   i = adjacent_find(v.begin(), v.end());
   cout << i - v.begin() << endl;  // 5 (v[5] = v[6])

   i = adjacent_find(v.begin(), v.end(), greater<int>());
   cout << i - v.begin() << endl;  // 1 (v[1] > v[2])

   int n = count(v.begin(), v.end(), 7);
   cout << n << endl;              // 3 (3 occurrences of 7) 

   n = count_if(v.begin(), v.end(), 
      bind2nd(greater<int>(), 10));
   cout << n << endl;              // 2 (2 elements > 10)
   bool eq = equal(v.begin(), v.end(), a);
   if (eq) cout << "v and a are equal\n";
   a[2]++;      // Now a[2] = 8 and v[2] = 7

   pair<itType, int*> itPair = 
      mismatch(v.begin(), v.end(), a);
   if (itPair.first != v.end())
      cout << *itPair.first << " != " 
      << *itPair.second << endl;    // 7 != 8

   a[2]--;      // Now a[2] = b[2] = 7 again. 
   i = search(v.begin(), v.end(), b + 1, b + 3);
   cout << i - v.begin() << endl;  // 2 (v[2]=b[1], v[3]=b[2])

   i = find_end(v.begin(), v.end(), b + 1, b + 3);
   cout << i - v.begin() << endl;  // 6 (v[6]=b[1], v[7]=b[2])

   i = search_n(v.begin(), v.end(), 2, 7);
   cout << i - v.begin() << endl;  // 5 (v[5] = v[6] = 7)
   i = search_n(v.begin(), v.end(), 2, 10, less<int>());
   cout << i - v.begin() << endl;  // 2 (v[2] < 10, v[3] < 10)
   return 0;
}




// modif.cpp: Modifying algorithms.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 314.
#include <iostream>
#include <algorithm>
#include <functional>
#include <string>
#include <cstdlib> 

using namespace std;

void show(int *first, int* last, const string s)
{  for (int* p = first; p != last; p++) cout << *p << " ";
   cout << "(" + s + ")\n";
}

class twopowers {    // Used with generate and generate_n
public:
   twopowers(): i(1){}
   int operator()(){int k = i; i *= 2; return k;}
private:
   int i;
};

class myrandom {    // Used with random_shuffle
public:
   myrandom(){srand(1234567U);}
   int operator()(int n){return rand() % n;}
};

bool differingAtMostOne(int x, int y) // Used with unique_copy
{  return y - x <= 1;
}

int main()
{  int a[8] = {1, 1, 2, 2, 3, 3, 4, 4},
       b[8], res[8];
   transform(a, a + 8, b, negate<int>());
   show(b, b + 8, "transform-1"); // -1 -1 -2 -2 -3 -3 -4 -4

   transform(a, a + 8, b, res, multiplies<int>());
   show(res, res + 8, "transform-2"); 
                                // -1 -1 -4 -4 -9 -9 -16 -16

   copy(a, a + 8, res);
   show(res, res + 8, "copy");  // 1 1 2 2 3 3 4 4

   // To shift all elements a position to the right, in the
   // same container, use copy_backward, not copy:
   copy_backward(res, res + 7, res + 8);
   show(res, res + 8, "copy_backward"); // 1 1 1 2 2 3 3 4

   int x = 5, y = 20;
   swap(x, y);
   cout << x << " " << y << endl;      // 20 5

   iter_swap(res, res + 7); // or: swap(res[0], res[7])
   show(res, res + 8, "iter_swap"); // 4 1 1 2 2 3 3 1

   swap_ranges(a, a + 8, res);
   show(res, res + 8, "swap_ranges"); // 1 1 2 2 3 3 4 4
   swap_ranges(res, res + 8, a); // Restore old situation
   show(res, res + 8, "swap_ranges (restore)"); 
                                      // 4 1 1 2 2 3 3 1
   replace_copy(a, a + 8, res, 3, 5);
      // Copy from a to res, but change each 3 into 5

   show(res, res + 8, "replace_copy"); // 1 1 2 2 5 5 4 4

   replace_copy_if(a, a + 8, res, bind2nd(less<int>(), 3), 0);
      // Copy from a to res, but change elements less than 3
      // into zero.
   show(res, res + 8, "replace_copy_if"); // 0 0 0 0 3 3 4 4
   // Algorithms 'replace' and 'replace_if' omitted. 

   fill(res, res + 8, 1);
   show(res, res + 8, "fill");        // 1 1 1 1 1 1 1 1

   fill_n(res, 8, 2);
   show(res, res + 8, "fill_n"); // 2 2 2 2 2 2 2 2

   generate(res, res + 8, twopowers());
   show(res, res + 8, "generate");    // 1 2 4 8 16 32 64 128


   generate_n(res, 8, twopowers());
   show(res, res + 8, "generate_n");  // 1 2 4 8 16 32 64 128

   int *new_end = remove_copy(a, a + 8, res, 3);
   show(res, new_end, "remove_copy"); // 1 1 2 2 4 4

   new_end = remove_copy_if(a, a + 8, res, 
      bind2nd(less<int>(), 3));
   show(res, new_end, "remove_copy_if"); // 3 3 4 4
   // Algorithms 'remove' and 'remove_if' omitted.

   new_end = unique_copy(a, a + 8, res);
   show(res, new_end, "unique_copy-1");  // 1 2 3 4

   new_end = unique_copy(a, a + 8, res, differingAtMostOne);
   show(res, new_end, "unique_copy-2");    // 1 3
   // Two versions of 'unique' omitted.
  
   reverse_copy(a, a + 8, res);
   show(res, res + 8, "reverse_copy");     // 4 4 3 3 2 2 1 1
   // Algorithm 'reverse' omitted.

   rotate_copy(a, a + 2, a + 8, res);
   show(res, res + 8, "rotate_copy");      // 2 2 3 3 4 4 1 1

   random_shuffle(res, res + 8);
   show(res, res + 8, "random_shuffle-1"); 
                          // 4 3 2 3 1 1 4 2 (in my test run)

   random_shuffle(a, a + 8, myrandom());
   show(a, a + 8, "random_shuffle-2");    
                          // 4 2 3 3 1 4 1 2 (in my test run)
   new_end = partition(a, a + 8, bind2nd(less<int>(), 3));
   show(a, a + 8, "partition-1");  // 2 2 1 1 3 4 3 4
   cout << new_end - a << " in first partition\n";  // 4

   // The algorithm stable_partition works similarly, but
   // preserves the relative order within each partition. 
   // This can be relevant with more complex elements
   // each consisting of a key and a value, and with
   // duplicated keys.
   return 0;
}



// sortdemo.cpp: Sorting related STL algorithms.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 318.
// There is a version adapted for gcc below.
#include <iostream>
#include <algorithm>
#include <string>
#include <functional>
#include <utility>
using namespace std;
using namespace std::rel_ops;  // See Section 9.9

class rectype {  
public:
   int nr;
   string name;
   rectype(int i = 0, string str = ""): nr(i), name(str){}

   bool operator==(const rectype &y)const
   {  return nr == y.nr;
   }
   bool operator<(const rectype &y)const
   {  return nr < y.nr;
   }
};

void show(rectype *first, rectype* last)
{  for (rectype* p = first; p != last; p++) 
   cout << p->nr << " " << p->name << "  ";
   cout << endl;
}

bool greaterthan(const rectype &x, const rectype &y)
{  return x > y; // or: y < x
}

int main()
{  rectype a[5] = {rectype(5, "John"), 
                   rectype(5, "Peter"),
                   rectype(3, "Mary"),
                   rectype(7, "Ann"),
                   rectype(2, "Tim")};
   rectype b[5];
   copy(a, a + 5, b);
   sort(b, b + 5);
   show(b, b + 5); 
   // Output: 2 Tim  3 Mary  5 John  5 Peter  7 Ann
   // (but Peter might have preceded John)

   // If preserving the order John Peter is essential,
   // use stable_sort instead of sort.
   copy(a, a + 5, b);
   //   stable_sort(b, b + 5, greater<rectype>()); 
   stable_sort(b, b + 5, greaterthan);  // descending
   show(b, b + 5);  
   // Output: 7 Ann  5 John  5 Peter  3 Mary  2 Tim

   copy(a, a + 5, b);
   partial_sort(b, b + 2, b + 5);
   show(b, b + 5); 
   // Output: 2 Tim  3 Mary  5 Peter  7 Ann  5 John
   rectype *p = partial_sort_copy(a, a + 5, b, b + 2);
   //  The two smallest elements of a appear in b,
   //  and p points to b[2], hence:
   show(b, p); 
   // Output: 2 Tim  3 Mary
   copy(a, a + 5, b);
   nth_element(b, b + 1, b + 5); 
   // Place b[1] where it belongs, as this output shows:
   show(b + 1, b + 2);  // Output: 3 Mary
   
   copy(a, a + 5, b);
   sort(b, b + 5);
   b[3] = b[2] = b[1];  
   // so [b+1, b+4) is a range of equal elements
   rectype *first = lower_bound(b, b + 5, b[2]);
   cout << "Lower bound: " << first - b << endl; 
   // Output: Lower bound: 1
   rectype *last = upper_bound(b, b + 5, b[2]);
   cout << "Upper bound: " << last - b << endl; 
   // Output: Upper bound: 4
   pair<rectype*, rectype*> itPair = 
      equal_range(b, b + 5, b[2]);
   cout << "itPair: " << itPair.first - b << " " 
                      << itPair.second - b << endl;
   // Output: itPair: 1 4
   
   cout << (binary_search(b, b + 5, rectype(3, "xxx")) ? 
      "Found\n" : "Not found");  // only the key 3 is used.
   // Output: Found 

   rectype c[3] = {rectype(3, "Charles"), 
                   rectype(4, "George"),
                   rectype(6, "Bill")};   
                               // Another sorted sequence
   rectype d[8];
   last = merge(b, b + 5, c, c + 3, d);
   show(d, last);
   // Output (on only line, not two):
   // 2 Tim  3 Mary  3 Mary  3 Mary  3 Charles  4 George  
   // 6 Bill  7 Ann
   copy(b, b + 5, d);
   copy(c, c + 3, d + 5);  // Concatenation of b and c in d
   inplace_merge(d, d + 5, d + 8);
   show(d, d + 8);   // Same output as with 'merge'.
   return 0;
}




// setopstr.cpp: Set operations on sorted structures.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 321.
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

void show(const string &s, const int *begin, 
          const int *end)
{  cout << s << " ";
   copy(begin, end, ostream_iterator<int>(cout, " "));
   cout << endl;
}

int main()
{  int a[4] = {1, 5, 7, 8}, b[3] = {2, 5, 8}, 
       sum[7], *pSumEnd, 
       prod[4], *pProdEnd,
       dif[3], *pDifEnd,
       symdif[7], *pSymDifEnd;
   pSumEnd = set_union(a, a+4, b, b+3, sum);
   pProdEnd = set_intersection(a, a+4, b, b+3, prod);
   pDifEnd = set_difference(a, a+4, b, b+3, dif);
   pSymDifEnd = set_symmetric_difference(a, a+4, b, b+3,
      symdif);
   show("a:     ", a, a+4);
   show("b:     ", b, b+3);   
   show("sum:   ", sum, pSumEnd);
   show("prod:  ", prod, pProdEnd);
   show("dif:   ", dif, pDifEnd);
   show("symdif:", symdif, pSymDifEnd);
   if (includes(a, a+4, b, b+3)) 
      cout << "a includes b.\n";
   else cout << "a does not include b.\n";
   if (includes(sum, pSumEnd, b, b+3)) 
      cout << "sum includes b.\n";
   else cout << "sum does not include b.\n";
   return 0;
}




// heapdemo.cpp: Demonstration of heap operations.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 324.
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

void show(const string &s, const int *begin, 
          const int *end)
{  cout << s << endl << "   ";
   copy(begin, end, ostream_iterator<int>(cout, " "));
   cout << endl;
}

int main()
{  cout << "  ";
   for (int i=0; i<10; ++i) cout << "  " << i;
   cout << endl;
   int a[10] = {20, 50, 40, 60, 80, 10, 30, 70, 25, 45};
   show("Initial contents of a:", a, a+10);
   random_shuffle(a, a+10);
   show("After random_shuffle(a, a+10):", a, a+10);
   make_heap(a, a+10);
   show("After make_heap(a, a+10):", a, a+10);
   int x = *a;         
   pop_heap(a, a+10); 
   show("After x = *a and pop_heap(a, a+10):", a, a+9);
   a[9] = x;
   push_heap(a, a+10);
   show("After a[9] = x and push_heap(a, a+10):", 
      a, a+10);
   sort_heap(a, a+10);
   show("After sort_heap(a, a+10):", a, a+10);
   return 0;
}



// minmax.cpp: The max algorithm (used with a special
//             comparison) and the min_element algorithm
//             applied to a list.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 326.
#include <iostream>
#include <algorithm>
#include <list>
using namespace std;

bool CompareLastDigit(int x, int y)
{  return x % 10 < y % 10;
}

int main()
{  int x = 123, y = 74, MaxLastDigit;
   // Out of x and y, choose the value with
   // the larger last decimal digit:
   MaxLastDigit = max(x, y, CompareLastDigit);
   cout << MaxLastDigit << endl;  // Output: 74
 
   int a[5] = {10, 30, 5, 40, 20};
   list<int> L;
   L.insert(L.begin(), a, a+5);
   list<int>::iterator i;
   i = min_element(L.begin(), L.end());
   cout << *i << endl;   // Output: 5 
   return 0;
}




// lexcomp.cpp: Lexicographical comparison.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 327.
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;

int main()
{  int a[4] = {1, 3, 8, 2},
       b[3] = {1, 3, 9};
   
   cout << "a: "; 
   copy(a, a+4, ostream_iterator<int>(cout, " "));
   
   cout << "\nb: "; 
   copy(b, b+3, ostream_iterator<int>(cout, " "));
   cout << endl;
   
   if (lexicographical_compare(a, a+4, b, b+3)) 
      cout << "Lexicographically, a precedes b.\n";
   
   if (!lexicographical_compare(a, a+4, b, b+3,
      greater<int>()))
      cout << 
      "Using the greater-than relation, we find:\n"
      "b lexicographically precedes a.\n";
   return 0;
}



// permgen.cpp: Permutation generator, generating all
//              permutations of the sequence 1 2 3.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 328.
// There is a version adapted for gcc below.
#include <iostream>
#include <algorithm>
using namespace std;

int main()
{  int a[3] = {1, 2, 3}, k;
   cout << "Six successive calls to next_permutation.\n"
      "Situation before call and value returned by " 
      "call:\n";
   
   for (k=0; k<6; ++k)
   {  copy(a, a+3, ostream_iterator<int>(cout, " "));
      bool b = next_permutation(a, a+3);
      cout << boolalpha << b << endl; 
         // As we will see in Section 10.2, b will appear
         // as true or false (not as 1 or 0) because of
         // the manipulator boolalpha.
   };
   cout << 
      "Three successive calls to prev_permutation.\n"
      "Situation before call and value returned by "
      "call:\n";
   for (k=0; k<3; ++k)
   {  copy(a, a+3, ostream_iterator<int>(cout, " "));
      bool b = prev_permutation(a, a+3);
      cout << boolalpha << b << endl;
   };
   return 0;
}




// numeric.cpp: Numerical algorithms.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 330.
// There is a version adapted for gcc below.
#include <iostream>
#include <numeric>
#include <algorithm>
#include <functional>
using namespace std;

double power(int x, int n)
{  double y = 1;
   for (int k=0; k<n; ++k) y *= x;
   return y;  // x raised to the power n
}

int main()
{  const int n = 3;
   int a[n] = {4, 2, 3}, sum = 0;
   sum = accumulate(a, a + n, sum);
   cout << "Sum of all elements: " << sum << endl; 
   // 4 + 2 + 3 = 9

   int prod = 1;
   prod = accumulate(a, a + n, prod, multiplies<int>());
   cout << "Product of all elements: " << prod << endl; 
   // 4 * 2 * 3 = 24


   int b[n] = {3, 4, 2}, inprod = 0;
   inprod = inner_product(a, a + n, b, inprod);
   cout << inprod << endl; 
   // 0 +  4 * 3  +  2 * 4  +  3 * 2  =  26

   int product=1;
   product = inner_product(a, a + n, b, product,
      multiplies<double>(), power); 
   cout << product << endl; 
   // 1 * power(4, 3) * power(2, 4) * power(3, 2) =
   // 1 * 64 * 16 * 9 = 9216

   int c[n], *iEnd;  // a = {4, 2, 3}
   iEnd = partial_sum(a, a + n, c);
   copy(c, iEnd, ostream_iterator<int>(cout, " "));
   cout << endl; // Output: 4 6 9
   int d[n];
   iEnd = adjacent_difference(c, c + n, d);
   copy(d, iEnd, ostream_iterator<int>(cout, " "));
   cout << endl; // Output: 4 2 3
   return 0;     
}



Chapter 10
==========

// manip.cpp: A demonstration of some manipulators.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 343.
// There is a version adapted for gcc below.
#include <iostream>
#include <iomanip>
using namespace std;

int main()
{  cout << showbase << uppercase
        << "Left              Right        Hexa-\n"
        << "justified     justified       decimal\n";
   for (int i=5; i<=10; i++)
   {  cout << dec << left
           << setw(5) << i << setw(8) << i * i * i

           << right
           << setw(2) << i << setw(8) << i * i * i

           << hex << setw(8) << i
           << setw(8) <<   i * i * i << endl;
   }
   return 0;
}


// booleans.cpp: The manipulators boolalpha and noboolalpha.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 344.
// This program does not compile with gcc.
#include <iostream>
using namespace std;

int main()
{  cout << true << " " << false << endl    // 1 0
        << boolalpha << true << endl;      // true
   cout << false << endl;                  // false
   cout << noboolalpha << true << endl;    // 1
   return 0;
}



// mymanip.cpp: A manipulator defined by ourselves.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 344 and 401.
// ios_base has been replaced with ios. The program now compiles 
// with both VC++ and gcc.
#include <iostream>
using namespace std;

ostream &hexadecimal(ostream &s)
{  s.setf(ios::hex, ios::basefield);
   return s;
}

int main()
{  cout << hexadecimal << 17 << endl; // Output: 11
   return 0;
}


// peekdemo.cpp: Looking ahead.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 347.
#include <iostream>
#include <cctype>
#include <string>
using namespace std;

int main()
{  cout << "Enter some letters, "
      "immediately followed by an integer: ";
   string s;
   for (;;)
   {  int ch = cin.peek();
      if (isdigit(ch)) break;
      ch = cin.get();
      s += ch;
   }
   int x;
   cin >> x;
   cout << "Letters: " << s << endl;
   cout << "Integer: " << x << endl;
   return 0;
}



// rword.cpp: Reading a word.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 351.
#include <iostream>
#include <string>
using namespace std;

int main()
{  string s;
   cout << "Enter some text: ";
   cin >> s;
   cout << "The following has been read: " << s << endl;
   return 0;
}



// copyaabb.cpp: 
//    This program copies characters from file aa to file bb.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 354.
#include <iostream>
#include <fstream>
using namespace std;

int main()
{  char ch;
   int n=0;
   ifstream ff("aa");
   if (!ff) 
   {  cout << "Cannot open aa for input\n"; 
      return 1;
   }
   ofstream gg("bb");
   if (!gg) 
   {  cout << "Cannot open bb for output\n"; 
      return 1;
   }
   while (ff.get(ch)) 
   {  gg.put(ch); 
      n++;
   }
   cout << n << " characters copied.\n";
   return 0;
}



// saveload.cpp: Writing and reading class objects
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 359.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

class article {
public:
   article(const string &ss = "", float xx = 0)
      : s(ss), x(xx){}
   void writeObject(ofstream &ff)const
   {  ff << s << endl;
      ff << x << endl;
   }
   bool readObject(ifstream &ff)
   {  getline(ff, s);
      ff >> x;
      char ch;
      ff.get(ch);
      return ff.good() && ch == '\n';
   }
   void show()const{cout << s << " " << x << endl;}
private:
   string s;
   float x;
};

int main()
{  ofstream ff("test.txt");
   article a("pencil", 1.23F), b("pen", 4.56F);
   a.writeObject(ff);
   b.writeObject(ff);
   ff.close();
   
   ifstream gg("test.txt");
   article a1, b1;
   if (!a1.readObject(gg) || !b1.readObject(gg))
      cout << "Could not read two articles.\n";
   else
   {  a1.show();   // pencil 1.23
      b1.show();   // pen 4.56
   }
   return 0;
}



// update.cpp: Updating a file by using random access.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 362.
// ios_base has been replaced with ios; the program now compiles
// with both VC++ and gcc.
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <string>
using namespace std;

void display(fstream &f)
{  long x;
   f.seekg(0);
   for (;;)
   {  f.read((char *)(&x), sizeof(x));
      if (f.eof()) break;
      cout << x << endl;
   }
   f.clear();
}

void check(fstream &f, const string &s)
{  if (! f.good())
   {  cout << "I/O error: " << s << endl; 
      exit(1);  // See Section 11.9
   }
}

int main()
{  long n, x, incr, i;
   cout << "Demonstration of updating a binary file.\n";
   cout << "How many long ints are to be written? "; 
   cin >> n;
   fstream f("info.bin", ios::in | ios::out | 
              ios::binary | ios::trunc); 
   check(f, "cannot open file info.bin");

   for (i=0; i<n; i++)
   {  x = 10 * i;
      f.write((char *)(&x), sizeof(x)); 
      check(f, "write fails");
   }
   display(f);

   do
   {  cout << 
      "Enter a nonnegative integer less than " << n << ": ";
      cin >> i;
   }  while (i < 0 || i >= n);
   f.seekg(i * sizeof(x), ios::beg);
   f.read((char *)(&x), sizeof(x)); 
   check(f, "read fails");
   cout << x << endl;
   cout << "Enter increment: "; cin >> incr;
   x += incr;
   f.seekp(i * sizeof(x), ios::beg);
   f.write((char *)(&x), sizeof(x)); 
   check(f, "write fails");
   display(f);
   return 0;
}


// failtest.cpp: Making a user-defined input
//               operator >> suitable for the 
//               usual test on success or failure.
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 365.
// ios_base has been replaced with ios. The program now compiles
// with both VC++ and gcc.
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
using std::istream;
using std::ostream;
using std::ios;

class price {
public:
   friend istream &operator>>(istream &is, price &pr);
     // requires dollar sign followed by a real number
   double getPrice()const{return x;}
private:
   double x;
};

istream &operator>>(istream &is, price &pr)
{  char ch;
   is >> ch >> pr.x;
   bool wrong = (is.fail() || ch != '$');
   is.clear();
   is.get(ch);
   wrong |= (ch != '\n');
   while (ch != '\n') is.get(ch);
   if (wrong) is.setstate(ios::failbit);
   return is;
}

int main()
{  cout << 
      "Enter a price (dollar sign, followed by number)\n";
   price pr;
   if (cin >> pr) 
      cout << "Price entered: " << pr.getPrice() << endl;
   else 
   {  cout << "Input incorrect\n";
      cin.clear();
   }
   cout << "Enter an integer: ";
   int i;
   cin >> i;
   cout << "Integer entered: " << i << endl;
   return 0;
}




// inmemfc.cpp: In-memory format conversion.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 367.
// There is a version adapted for gcc below.
#include <iostream>
#include <sstream>
#include <iomanip>
#include <string>
using namespace std;

int main()
{  float x = 2.5;
   // From binary to text (output to a string):
   ostringstream oo;
   oo << "Test:\n"                  // 6 characters 
      << setfill('*') << setw(8)
      << setprecision(3) << x * x   // 8 characters
      << endl;                      // 1 character ('\n')
   string s = oo.str();
   cout << s << "Length: " << s.length() << endl;
                       // 6 + 8 + 1 = 15 characters

   // From text to binary (input from a string):
   string t = "0.01234567 89";
   double y;
   int i;
   istringstream ii(t);
   ii >> y >> i;
   cout << "y + i = " << fixed
        << setprecision(10) << y + i << endl;
   return 0;
}



Chapter 11
==========

// assert.cpp: Assertion ineffective because of NDEBUG.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 374.
#define NDEBUG 1
#include <iostream>
#include <cassert>
using namespace std;
int main()
{  int x = 2000;
   assert(x < 1000); 
   cout << "Ready.\n";
   return 0;
}


// errno.cpp: Demonstration of errno.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 375.
#include <iostream>
#include <cerrno>
#include <cmath>
#include <string>
using namespace std;

int main()
{  double x = -1;
   double y = sqrt(x);  // Error since x is negative
   if (errno == EDOM) 
   {  cout << "EDOM\n"; // Output: EDOM
      cout << strerror(errno) << endl;
   }
   return 0;
}



// vararg.cpp: Variable-length argument lists.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 381.
#include <cstdarg>
#include <iostream>
using namespace std;
int main()
{  double sum(int n, ...); // Literal program text!
   cout << sum(1, 9.87) << endl;
   cout << sum(5, 10.0, 20.0, 30.0, 40.0, 50.0) << endl;
   return 0;
}
double sum(int n, ...)    // Literal program text!
// n is the number of arguments that follow.
{  va_list argp;
   double s = 0;
   va_start(argp, n);
   while (n--) s += va_arg(argp, double);
   va_end(argp);
   return s;
}



// asterisk.cpp: Asterisks in conversion specifications for
//               printf.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 384.
#include <stdio.h>

int main()
{  int width = 5, precision = 2, 
       k = 1234;
   double x = 9.87654321;
   printf("x =%*.*f   k =%*d\n", 
          width, precision, x, width, k);
   return 0;
}



// scanfadv.cpp: Some advanced conversion specifications
//               for scanf.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 386.
#include <stdio.h>

int main()
{  int k;
   char str[80], ch;
   printf("Enter a line of text, ending with a "
          "punctuation character:\n");
   scanf("%[^.,;?!]%c%n", str, &ch, &k);
   printf("str=%s  ch=%c  k=%d\n", str, ch, k);
   return 0;
}


// numio.cpp: This program reads integers from the file
//            num.txt and computes their sum. It terminates 
//            as soon as an invalid character is encountered 
//            or the end of the file is reached. The sum is 
//            displayed and also written to the file
//            outsum.txt.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 389.
#include <stdio.h>
#include <stdlib.h>

int main()
{  int sum = 0, x;
   FILE *fp = fopen("num.txt", "r");
   if (fp == NULL) 
   {  printf("File num.txt not available.\n");
      exit(1);
   }     
   while (fscanf(fp, "%d", &x) == 1) 
      sum += x;
   if (!feof(fp))
   {  printf("Invalid character read.\n");
   }
   fclose(fp);
   printf("The sum (also written to outsum.txt) is: %d\n", 
      sum);
   FILE *fpsum = fopen("outsum.txt", "w");
   fprintf(fpsum, "%d\n", sum);
   fclose(fpsum);
   return 0;
}



// sprintf.cpp: In-memory format conversion using
//              sprintf and sscanf.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 391.
#include <stdio.h>

int main()
{  float x = 2.5;
   // From binary to text (output to a C-style string):
   char s[100];
   sprintf(s, "The square of 2.5 is %f\n", x * x);
   // Show the result:
   printf(s);

   // From text to binary (input from a C-style string):
   char *t = "0.01234567 89";
   double y;
   int i;
   sscanf(t, "%lf %d", &y, &i);
   printf("y = %f  i = %d\n", y, i);
   return 0;
}


// atexit.cpp: A demonstration of atexit.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 392.
#include <iostream>
#include <cstdlib>
using namespace std;

void ready(void)
{  cout << "Ready.\n";
}
void almost_ready(void)
{  cout << "Almost ready.\n";
}
int main()
{  atexit(ready);
   atexit(almost_ready);   
   cout << "Not ready.\n";
   return 0;      
}



// timedemo.cpp: Demonstration of time and date functions.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 398.
#include <ctime>
#include <iostream>
using namespace std;
    
int main()
{  time_t t = time(NULL);
   tm s = *localtime(&t);
   cout << "Time in structure s (of type tm):\n";
   cout << " sec="   << s.tm_sec 
        << " min="   << s.tm_min 
        << " hour="  << s.tm_hour 
        << " mday="  << s.tm_mday
        << " mon="   << s.tm_mon
        << " year="  << s.tm_year << endl;
   cout << " wday="  << s.tm_wday
        << " yday="  << s.tm_yday
        << " isdst=" << s.tm_isdst << endl;
   cout << "Time obtained by asctime         : " 
        << asctime(&s);
   cout << "The same result obtained by ctime: "
        << ctime(&t);
   cout << "The following lines contain data "
          "obtained by using strftime:\n";
   char str[80];
   strftime(str, 80, 
      " Time: %M minutes after %I o'clock %p\n"
      " Day:  %A, %B %d, 20%y", &s);
   cout << str << endl;
   return 0;
}




Appendix A
==========


// mymanip1.cpp: A manipulator defined by using a special
//               class.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 402.
// ios_base has been replaced with ios. The program now compiles 
// with both VC++ and gcc.
#include <iostream>
using namespace std;
      
class ManipType {} hexadecimal;
      
ostream& operator<<(ostream& s, ManipType m)
{  s.setf(ios::hex, ios::basefield);
   return s;
}

int main()
{  cout << hexadecimal << 17 << endl; // Output: 11
   return 0;
}



// parmanip.cpp: Defining a manipulator with a parameter.
//               Both class 'horline' and operator<< are 
//               specific for this manipulator.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 403.
#include <iostream>
using namespace std;
class horline {
public:
   int n;
   horline(int nn):n(nn){}  // Use nn to initialize n.
};

ostream& operator<<(ostream& s, horline& h)
{  for (int i=0; i<h.n; i++) s << '-';
   return s;
}
      
int main()
{  cout << horline(5) << "Ready.\n";
   return 0;
}




Special versions of some programs for GNU C++ 
(gcc, version 2.91.66, Redhat Linux, egcs-1.1.2)
================================================

// typvar.cpp: Types and variables.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 27.
// Special version: gcc does not accept the manipulator 'fixed'.
#include <iostream>
#include <iomanip>
using namespace std;

int main()
{  char ch = 'A';  
   double ff = 5.0/3;
   float f = ff;
   bool b = (f > 1);
   int i, j;
   j = 2 * (i = 5.0/3);  // i = 1, j = 2
   cout << "ch = " << ch 
        << "   ASCII value: " << int(ch) << endl;
   cout << setiosflags(ios::fixed) << setprecision(10);
   cout << "f = " << f << "   ff = " << ff << endl;
   cout << "i = " << i << "   j = " << j << endl;
   if (b) 
      cout << "The variable b is equal to true.\n";
   cout << "Number of bytes for type 'bool':   " 
        << sizeof(bool) << endl;
   cout << "Number of bytes for type 'char':   "
        << sizeof(char) << endl;
   cout << "Number of bytes for type 'int':    "
        << sizeof(int) << endl;
   cout << "Number of bytes for type 'float':  "
        << sizeof(float) << endl;
   cout << "Number of bytes for type 'double': "
        << sizeof(double) << endl;
   return 0;
}


// table.cpp: This program produces a table.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 41.
// Special version: gcc does not accept the manipulator 'fixed'.
#include <iostream>
#include <iomanip>
using namespace std;

int main()
{  cout << " x         f(x)\n\n";
   cout << setiosflags(ios::fixed);
   for (int i=20; i<=40; i+=2)
   {  double x = i/10.0;
      cout << setw(3) << setprecision(1) 
           << x << " "
           << setw(15) << setprecision(10)
           << x * x + x + 1/x << endl;
   }
   return 0;
}


// align.cpp: Align strings.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 144.
// Special version: gcc does not accept some manipulators such as 'fixed'.
#include <string>
#include <iostream>
#include <iomanip>
using namespace std;

int main()
{  string names[3] = {"John", "George", "Jim"};
   int ages[3] = {9, 100, 24};
   for (int i=0; i<3; ++i)
      // Modified for gcc:
     cout << setiosflags(ios::left) << setw(10) << names[i]
           << setw(3)  << setiosflags(ios::right) << ages[i] << endl;

   return 0;
}


// convdemo.cpp: In-memory format conversion
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 152.
// Special version:
// gcc has problems with the header sstream and the manipulator 'fixed'.
#include <iostream>
#include <strstream>
#include <iomanip>
using namespace std;

int main()
{  // From string s to numerical value x:
   char s[80] = "1.2e-3";
   istrstream istr(s, 80);
   double x;
   istr >> x;              // x = 0.0012
   cout << x << endl;      

   // From numerical value y to string t:
   double y = 10.3456789;
   char t[80] = ""; // Initialized with null characters.
   ostrstream ostr(t, 80);
   ostr << setiosflags(ios::fixed) << setw(8) 
        << setprecision(3) << y;
   cout << t << endl;       // t = "  10.346"
   return 0;
}



// person.h: Header for the class Person.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 163.
// Special version:
// gcc does not accept the manipulator 'fixed'.
#include <string>
#include <iostream>
#include <iomanip>
using namespace std;

class Person {
public:
   Person(const string &s = "", int yr = 0, bool m = true)
   {  name = s;
      yearOfBirth = yr;
      male = m;
   }
   
   void setName(const string &s){name = s;}
   void setYear(int yr){yearOfBirth = yr;}
   void setMF(bool m){male = m;}
   
   const string &getName()const 
   {  return name;
   }
   int getAgeAtEnd2000()const 
   {  return 2000 - yearOfBirth;
   }
   void print()const
   {  // Modified for gcc:
      cout << setw(10) << setiosflags(ios::left) << name 
           << setw(4) << setiosflags(ios::right) << getAgeAtEnd2000()
           << (male ? " (M)" : " (F)") << endl;
   }
private:
   string name;
   int yearOfBirth;
   bool male;
};



// nohiding.cpp: The principle of overriding.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 204.
// Special version for gcc.
#include <iostream>
using namespace std;
class B {
public:
   int f()const{return 1;}
};

class D: public B {
public:
   // The following line is omitted for gcc:
   // using B::f;
   int f(int k)const{return k;}
};

int main()
{  D d; 

// cout << "d.f()  = " << d.f() << endl;
// The previous line has been replaced with this one:
   cout << "d.B::f()  = " << d.B::f() << endl;
   return 0;
}


// istring.cpp: The template basic_string applied to 
//              integers.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 242.
// gcc gives unclear error messages about a header bastring.h.
#include <string>
#include <iostream>
using namespace std;

//typedef basic_string<int> istring; // int instead of char!

int main()
{  cout << "This program does not work with gcc.\n";
/*
   istring s;
   s += 123;
   s += 98;
   s += 45;
   for (int i=0; i<s.length(); ++i)
      cout << s[i] << endl;
*/
   return 0;
}


// rel_ops.cpp: Relational operators.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 292.
// Special version for gcc: second using-directive commented.
#include <iostream>
#include <utility>
using namespace std;
// using namespace std::rel_ops;

class Example {
public:
   Example(int i = 0, int j = 0): a(i), b(j){}
   int a, b;
   bool operator==(const Example &y)const
   {  return a == y.a && b == y.b;
   }

   bool operator<(const Example &y)const
   {  return a < y.a || a == y.a && b < y.b;
   }
};
int main()
{  Example u(1, 3), v(1, 2);
   if (u > v)  cout << "u > v\n";
   if (u >= v) cout << "u >= v\n";
   if (u != v) cout << "u != v\n";
   if (u <= v) cout << "u <= v\n";
   return 0;
}



// funobj3.cpp: The operator() function is a
//              binary predicate.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 296.
// This use of a function object (see printSmaller) is not accepted by gcc.
#include <iostream>
using namespace std;

template <class T>
struct LessThan {
   bool operator()(const T &x, const T &y)const
   {  return x < y;
   }
};

struct CompareLastDigits {
   bool operator()(int x, int y)const
   {  return x % 10 < y % 10;
   }
};

template <class T, class Compare>
class PairSelect {
public:
   PairSelect(const T &x, const T &y): a(x), b(y){}
   void PrintSmaller()const
   {  // Not accepted by gcc:
      // cout << (Compare()(a, b) ? a : b) << endl;
   }
private:
   T a, b;
};

int main()
{  PairSelect<double, LessThan<double> > P(123.4, 98.7);
   P.PrintSmaller(); // Output: 98.7
   
   PairSelect<int, CompareLastDigits> Q(123, 98);
   Q.PrintSmaller(); // Output: 123 (because 3 < 8)
   return 0;
}



// sortdemo.cpp: Sorting related STL algorithms.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 318.
// Version adapted for gcc.
#include <iostream>
#include <algorithm>
#include <string>
#include <functional>
#include <utility>
using namespace std;
//The following line is deleted for the gcc compiler:
//using namespace std::rel_ops;  // See Section 9.9

class rectype {  
public:
   int nr;
   string name;
   rectype(int i = 0, string str = ""): nr(i), name(str){}

   bool operator==(const rectype &y)const
   {  return nr == y.nr;
   }
   bool operator<(const rectype &y)const
   {  return nr < y.nr;
   }
};

void show(rectype *first, rectype* last)
{  for (rectype* p = first; p != last; p++) 
   cout << p->nr << " " << p->name << "  ";
   cout << endl;
}

bool greaterthan(const rectype &x, const rectype &y)
{  return x > y; // or: y < x
}

int main()
{  rectype a[5] = {rectype(5, "John"), 
                   rectype(5, "Peter"),
                   rectype(3, "Mary"),
                   rectype(7, "Ann"),
                   rectype(2, "Tim")};


   rectype b[5];
   copy(a, a + 5, b);
   sort(b, b + 5);
   show(b, b + 5); 
   // Output: 2 Tim  3 Mary  5 John  5 Peter  7 Ann
   // (but Peter might have preceded John)

   // If preserving the order John Peter is essential,
   // use stable_sort instead of sort.
   copy(a, a + 5, b);

// gcc does not accept the following two lines:
 //   stable_sort(b, b + 5, greater<rectype>()); 
 //  stable_sort(b, b + 5, greaterthan);  // descending

//   show(b, b + 5);  
   // Output: 7 Ann  5 John  5 Peter  3 Mary  2 Tim

   copy(a, a + 5, b);
   partial_sort(b, b + 2, b + 5);
   show(b, b + 5); 
   // Output: 2 Tim  3 Mary  5 Peter  7 Ann  5 John
   rectype *p = partial_sort_copy(a, a + 5, b, b + 2);
   //  The two smallest elements of a appear in b,
   //  and p points to b[2], hence:
   show(b, p); 
   // Output: 2 Tim  3 Mary
   copy(a, a + 5, b);
   nth_element(b, b + 1, b + 5); 
   // Place b[1] where it belongs, as this output shows:
   show(b + 1, b + 2);  // Output: 3 Mary
   
   copy(a, a + 5, b);
   sort(b, b + 5);
   b[3] = b[2] = b[1];  
   // so [b+1, b+4) is a range of equal elements
   rectype *first = lower_bound(b, b + 5, b[2]);
   cout << "Lower bound: " << first - b << endl; 
   // Output: Lower bound: 1
   rectype *last = upper_bound(b, b + 5, b[2]);
   cout << "Upper bound: " << last - b << endl; 
   // Output: Upper bound: 4
   pair<rectype*, rectype*> itPair = 
      equal_range(b, b + 5, b[2]);
   cout << "itPair: " << itPair.first - b << " " 
                      << itPair.second - b << endl;
   // Output: itPair: 1 4
   
   cout << (binary_search(b, b + 5, rectype(3, "xxx")) ? 
      "Found\n" : "Not found");  // only the key 3 is used.
   // Output: Found 

   rectype c[3] = {rectype(3, "Charles"), 
                   rectype(4, "George"),
                   rectype(6, "Bill")};   
                               // Another sorted sequence
   rectype d[8];
   last = merge(b, b + 5, c, c + 3, d);
   show(d, last);
   // Output (on only line, not two):
   // 2 Tim  3 Mary  3 Mary  3 Mary  3 Charles  4 George  
   // 6 Bill  7 Ann

   copy(b, b + 5, d);
   copy(c, c + 3, d + 5);  // Concatenation of b and c in d

//  gcc does not accept the following line:
//   inplace_merge(d, d + 5, d + 8);

//   show(d, d + 8);   // Same output as with 'merge'.
   
   return 0;
}


// permgen.cpp: Permutation generator, generating all
//              permutations of the sequence 1 2 3.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 328.
// Version adapted for gcc (with regard to the manipulator boolalpha).
#include <iostream>
#include <algorithm>
using namespace std;

int main()
{  int a[3] = {1, 2, 3}, k;
   cout << "Six successive calls to next_permutation.\n"
      "Situation before call and value returned by " 
      "call:\n";
   
   for (k=0; k<6; ++k)
   {  copy(a, a+3, ostream_iterator<int>(cout, " "));
      bool b = next_permutation(a, a+3);

//  gcc does not accept the manipulator boolalpha on the following line:
//    cout << boolalpha << b << endl;

// We can obtain the same effect as follows:
      cout << (b ? "true" : "false") << endl;
 
         // As we will see in Section 10.2, b will appear
         // as true or false (not as 1 or 0) because of
         // the manipulator boolalpha.
   };
   cout << 
      "Three successive calls to prev_permutation.\n"
      "Situation before call and value returned by "
      "call:\n";
   for (k=0; k<3; ++k)
   {  copy(a, a+3, ostream_iterator<int>(cout, " "));
      bool b = prev_permutation(a, a+3);

// Once again, we avoid the boolalpha manipulator as follows for gcc:
      cout << (b ? "true" : "false") << endl;

   };
   return 0;
}



// numeric.cpp: Numerical algorithms.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 330.
// Version adapted for gcc.
#include <iostream>
#include <numeric>
#include <algorithm>
#include <functional>
using namespace std;

double power(int x, int n)
{  double y = 1;
   for (int k=0; k<n; ++k) y *= x;
   return y;  // x raised to the power n
}

int main()
{  const int n = 3;
   int a[n] = {4, 2, 3}, sum = 0;
   sum = accumulate(a, a + n, sum);
   cout << "Sum of all elements: " << sum << endl; 
   // 4 + 2 + 3 = 9

   int prod = 1;

// gcc does not accept the following line:
//   prod = accumulate(a, a + n, prod, multiplies<int>());

   cout << "Product of all elements: " << prod << endl; 
   // 4 * 2 * 3 = 24


   int b[n] = {3, 4, 2}, inprod = 0;
   inprod = inner_product(a, a + n, b, inprod);
   cout << inprod << endl; 
   // 0 +  4 * 3  +  2 * 4  +  3 * 2  =  26

   int product=1;

// gcc does not accept the following statement:
//   product = inner_product(a, a + n, b, product,
//      multiplies<double>(), power); 

   cout << product << endl; 
   // 1 * power(4, 3) * power(2, 4) * power(3, 2) =
   // 1 * 64 * 16 * 9 = 9216

   int c[n], *iEnd;  // a = {4, 2, 3}
   iEnd = partial_sum(a, a + n, c);
   copy(c, iEnd, ostream_iterator<int>(cout, " "));
   cout << endl; // Output: 4 6 9
   int d[n];
   iEnd = adjacent_difference(c, c + n, d);
   copy(d, iEnd, ostream_iterator<int>(cout, " "));
   cout << endl; // Output: 4 2 3
   return 0;     
}


// manip.cpp: A demonstration of some manipulators.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 343.
// Special version for gcc, which avoids the manipulators left, right,
// showbase, uppercase.
#include <iostream>
#include <iomanip>
using namespace std;

int main()
{  cout << setiosflags(ios::showbase | ios::uppercase)
        << "Left              Right        Hexa-\n"
        << "justified     justified       decimal\n";
   for (int i=5; i<=10; i++)
   {  cout << dec << setiosflags(ios::left)
           << setw(5) << i << setw(8) << i * i * i
           << resetiosflags(ios::left)
           << setw(2) << i << setw(8) << i * i * i
           << hex << setw(8) << i
           << setw(8) <<   i * i * i << endl;
   }
   return 0;
}


// booleans.cpp: The manipulators boolalpha and noboolalpha.
// Copied from:
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 344.
// gcc does not accept these two manipulators.
#include <iostream>
using namespace std;
int main()
{  cout << "This program in its original form does not work\n"
           "with gcc because this compiler does not accept the\n"
           "manipulators boolalpha and noboolalpha.\n";
   return 0;
}
//{  cout << true << " " << false << endl    // 1 0
//        << boolalpha << true << endl;      // true
//   cout << false << endl;                  // false
//   cout << noboolalpha << true << endl;    // 1
//   return 0;
//}



// inmemfc.cpp: In-memory format conversion.
//    Ammeraal, L. (2000) C++ for Programmers, 3rd Ed., Chichester: Wiley,
//    p. 367.
// For gcc, <sstream> has been replaced with <strstream>,
// ostringstream with ostrstream and istringstream with istrstream.
// Also, conventional C-strings have been used instead of the C++ 'string' type.
#include <iostream>
#include <strstream>
#include <iomanip>
#include <string>
using namespace std;

int main()
{  float x = 2.5;
   // From binary to text (output to a string):
   char s[80] = "";                 // initialized with 80 null characters
   ostrstream oo(s, 80);
   oo << "Test:\n"                  // 6 characters 
      << setfill('*') << setw(8)
      << setprecision(3) << x * x   // 8 characters
      << endl;                      // 1 character ('\n') 
  
   cout << s << "Length: " << strlen(s) << endl;
                       // 6 + 8 + 1 = 15 characters

   // From text to binary (input from a string):
   char t[80] = "0.01234567 89";
   double y;
   int i;
   istrstream ii(t, 80);
   ii >> y >> i;
   cout << "y + i = " << setiosflags(ios::fixed)
        << setprecision(10) << y + i << endl;
   return 0;
}
