#include "libscl.h"
#include <ctime>
#include <math.h>
#include <algorithm>
#include <numeric>  // textbook is wrong here
using namespace std;
using namespace scl;

namespace {
  inline double f(double x) { return log(x); }
  inline double g(double x) { return 2.0*x; }
}

int main(int argc, char** argp, char** envp)
{
  clock_t time_start, time_stop;
  
  typedef vector<double>::size_type vst;
  typedef vector<double>::iterator vitr;

  const vst n = 10000000;

  cout << starbox("/Memory allocation//")<<'\n';
  cout << "n = " << n << '\n';
  cout.flush();

  time_start = clock();

  vector<double> a(n);

  time_stop = clock();
  cout<<"time = "<<time_stop - time_start<< '\n';

  time_start = clock();

  vector<double> b(n);

  time_stop = clock();
  cout<<"time = "<<time_stop - time_start<< '\n';

  cout << starbox("/Initialization//")<<'\n';
  cout.flush();

  time_start = clock();

  for (vitr ai=a.begin(); ai!=a.end(); ++ai) {
    *ai = 0.1;
  }

  time_stop = clock();
  cout<<"time = "<<time_stop - time_start<< '\n';
  cout.flush();

  cout << starbox("/Accumulation//")<<'\n';
  cout.flush();

  double sum;

  time_start = clock();
  sum = 0.0;
  sum = accumulate(a.begin(), a.end(), sum);
  time_stop = clock();
  cout<<"1 of 2, sum = "<<sum<<", time = "<<time_stop - time_start<< '\n';
  cout.flush();

  time_start = clock();
  sum = 0.0;
  vitr ai = a.begin();
  while (ai!=a.end()) {
    sum += *ai++;
  }
  time_stop = clock();
  cout<<"2 of 2, sum = "<<sum<<", time = "<<time_stop - time_start<< '\n';
  cout.flush();

  cout << starbox("/Transformation//")<<'\n';
  cout.flush();

  time_start = clock();
  transform(a.begin(), a.end(), b.begin(), f);
  time_stop = clock();
  sum = 0.0;
  sum = accumulate(b.begin(), b.end(), sum);
  cout<<"1 of 4, sum = "<<sum<<", time = "<<time_stop - time_start<< '\n';
  cout.flush();

  time_start = clock();
  ai = a.begin();
  vitr bi = b.begin();
  while (ai!=a.end()) {
    *bi++ = log(*ai++);
  }
  time_stop = clock();
  sum = 0.0;
  sum = accumulate(b.begin(), b.end(), sum);
  cout<<"2 of 4, sum = "<<sum<<", time = "<<time_stop - time_start<< '\n';
  cout.flush();

  time_start = clock();
  transform(a.begin(), a.end(), b.begin(), g);
  time_stop = clock();
  sum = 0.0;
  sum = accumulate(b.begin(), b.end(), sum);
  cout<<"3 of 4, sum = "<<sum<<", time = "<<time_stop - time_start<< '\n';
  cout.flush();

  time_start = clock();
  ai = a.begin();
  bi = b.begin();
  while (ai!=a.end()) {
    *bi++ = g(*ai++);
  }
  time_stop = clock();
  sum = 0.0;
  sum = accumulate(b.begin(), b.end(), sum);
  cout<<"4 of 4, sum = "<<sum<<", time = "<<time_stop - time_start<< '\n';
  cout.flush();

  return 0;
}
