#include<iostream>
#include<vector>
#include<algorithm>
#include<list>

#include "misc.h"

using namespace std;

void test01()
{
   // The merge Algorithm
   // Merges two sorted containers
   //   src and dest ranges shouldn't intersect

   vector<int> a(5);
   a[0]=2;  a[1]=3;  a[2]=8; a[3]=20; a[4]=25;

   int b[6] = {7,9,23,28,30, 33};

   vector<int> c;

   // merge assumes sequences are sorted
   merge(a.begin(),a.end(),b,b+6,back_inserter(c));

   printit<vector<int>&,vector<int>::iterator> prn(c);
   prn();
   
   // Same as above, this time sorting a vector first,
   // and merging into another container

   vector<int> a2(5);
   a2[0]=20; a2[1]=2; a2[2]=25; a2[3]=3; a2[4]=8;
   sort(a2.begin(),a2.end());
   list<int> c2;
   merge(a2.begin(),a2.end(),b,b+6,inserter(c2,c2.begin()));
   
   cout << "***" << endl;
   // output the vector to make sure its ordered
   (printit<vector<int>&,vector<int>::iterator>(a2))();

   printit<list<int>&,list<int>::iterator> prn2(c2);
   prn2();
}

void test02()
{
   // The copy Algorithm and an Insert Iterator

   int a[4] = {10,20,30,40};
   vector<int> v(a,a+4);
   list<int> w(5,123);  // A list of 5 elements
   (printit<list<int>&,list<int>::iterator>(w))();
   
   list<int>::iterator i = w.begin();
   ++i; 
   ++i;
   copy(v.begin(),v.end(), inserter(w,i));
   (printit<list<int>&,list<int>::iterator>(w))();

   // expected output
   // 123 123 123 123 123
   // 123 123 10 20 30 40 123 123 123
}

#include "rand.h"

class interval
{
public:
   double _a;
   double _b;
   
   interval(double a, double b) : _a(a), _b(b) {}

   bool operator()(double x)
   {
      return _a <= x && x <= _b;
   }
};


void test03()
{
   // Create a vector with random numbers between 0.0 and 1.0
   vector<double> v;
   f_rand_double r;
   generate_n(back_inserter(v),30,r);
   (printit<vector<double>&,vector<double>::iterator>(v))();

   
   interval ab(0.3,0.5);
   cout << "\nTesting interval class" << endl;
   cout << SHOW(ab(.4)) <<  endl;
   cout << SHOW(ab(.01)) << endl;
   // expected output
   // ab(.4)=1
   // ab(.01)=0
   
   // Find all elements within the interval ab in vector v

   vector<double>::iterator i=find_if(v.begin(),v.end(),ab);
   for ( ; i!=v.end(); ++i,i=find_if(i,v.end(),ab) )
      cout << *i << " ";
   // find_if finds the first element in the containers sequence
   // that satisfied by the conditional object.  Here the
   // iterator is incremented to point to the next element in the
   // vector, and the search continues
}

void test04()
{
   // Copy algorithm, make room

   double a[5] = {1.1,1.2,1.3,1.4,1.5};
   vector<double> v1(a,a+5);
   // Reserve the space necessary for copy
   vector<double> v2(v1.size());
   copy(v1.begin(),v1.end(),v2.begin());


   // backinserter inserts at end 

   vector<double> v3; // let back_inserter handle size, 
      // unless efficiency reasons which are often in my mind
   copy(v1.begin(),v1.end(),back_inserter(v3));

   // output copied vectors
   for (vector<double>::iterator i=v2.begin(); i!=v2.end(); ++i)
      cout << *i << endl;
   for (vector<double>::iterator i=v3.begin(); i!=v3.end(); ++i)
      cout << *i << endl;
}


void main()
{
   test04();

}

