/*
    template.cpp templated functions allows code to be generated for
    many variable types automatically.
    
    Here we write a function to swap two variables. The code of
    swapping does not depend on the type of variable, hence we
    can template it.
    
    You already used this e.g.
        vector<double> ..        vector does not depend on the type of variable stored.
        complex<float> ..        complex numbers could be build with int, float, double, or any number.
        map<double,string> ..    map needs operator< to be defined for the first type.

    See Nyhoff P370 for swapping.393
*/

#include <iostream>           // Include cin / cout streams for input/output
#include <string>             // include string type
using namespace std;

/*
  This function can swap two integers because it uses call-by-reference semantics.
  BUT it is limited to integers, but we could equally well use the identical code
  for strings, doubles, bools ..
*/
void swap_integers(int &n, int &m)
{
   int tmp=n;  // we need this!
   n=m;
   m=tmp;
}

/*
  Function templates allows types to become "variables". The compiler automatically
  generates a specific swap_anything function, for all the types that it is called with.
*/

template <typename TYPE>
void swap_anything(TYPE &n, TYPE &m)
{
   TYPE tmp=n;   // TYPE is now the type of the variable
   n=m;          // that the compiler knows the function will
   m=tmp;        // be called with
}


int main()
{         
// Sample example with integers.
   int i=0;
   int j=42;
   
   cout << "i=" << i << "  j=" << j << "\n";
   swap_integers(i,j);                

   cout << "i=" << i << "  j=" << j << "\n";
   swap_anything(i,j);                

   cout << "i=" << i << "  j=" << j << "\n";

// Sample example with strings.
   string s1("Fisk");
   string s2("Hest");

   cout << "s1=" << s1 << "  s2=" << s2 << "\n";
   swap_anything(s1,s2);                
   cout << "s1=" << s1 << "  s2=" << s2 << "\n";

   return 0;
}
