#include <cassert>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

#include <print.h>
#include <aclock.h>


#include <dumbarray.h>

#include <dumbarraytest.h>



void dumbarraytest01()
{
  cout << "Testing the dumb array class" << endl;
  double a = 3.0;
  double b = 5.0;
  double c = 7.0;

  cout << SHOW(a) << endl;
  cout << SHOW(b) << endl;
  cout << SHOW(c) << endl;

  double ** v = new double * [3];

  dumbarray<double> vi(v,3,false);

  cout << "Set the pointers" << endl;
  vi(0) = & a;
  vi(1) = & b;
  vi(2) = & c;

  cout << SHOW(vi[0]) << endl;
  cout << SHOW(vi[1]) << endl;
  cout << SHOW(vi[2]) << endl;

  cout << SHOW((vi[1]=7.2)) << endl;

  cout << SHOW(b) << endl;

  cout << "Now have a second pointer v2 but without ownership." << endl;
  dumbarray<double> v2(vi);

  cout << SHOW(v2[1]) << endl;

  cout << "If this crashes on program termination there is a bug." << endl;
  cout << "ie I am testing that memory was not double deleted." << endl;

  delete[] v;
}


void dumbarraytest02()
{
  cout << "Testing dumbarray 2." << endl;
  cout << "This time have dumbarray own the pointer array." << endl;

  double a = 3.0;
  double b = 5.0;
  double c = 7.0;

  cout << SHOW(a) << endl;
  cout << SHOW(b) << endl;
  cout << SHOW(c) << endl;

  dumbarray<double> vi(3);
  vi(0) = &a;
  vi(1) = &b;
  vi(2) = &c;

  cout << SHOW(vi[0]) << endl;
  cout << SHOW(vi[1]) << endl;
  cout << SHOW(vi[2]) << endl;
}


void sumintarray( int & sum, int * v, uintc n)
{
  sum = 0;
  for (uint i=0; i<n; ++i)
  {
    sum += v[i];
  }
}


template< typename T >
void sumintarray( int & sum, T & v, uintc n, uintc n2)
{
  sum = 0;

  for (uint k=0; k<n2; ++k)
  {
    for (uint i=0; i<n; ++i)
    {
      sum += v[i];
    }
  }
}


void dumbarraytest03()
{
  cout << "Testing the timmes for accessing with a dumbarray rather" << endl;
  cout << "  than a contiguous pointer." << endl;

  cout << "For optimized code I got dumbarray taking twice as long as " << endl;
  cout << "  vector<int> and int* access. " << endl; 

  uint N=1000;
  //uintc N=10000;


  vector< int * > v1(N);

  vector<int> v2(N);

  for (uint i=0; i<N; ++i)
  {
    v2[i] = i;

    v1[i] = & v2[i];
  }

  random_shuffle(v1.begin(),v1.end());
  
  dumbarray<int> v3(& v1[0],N,false);


  aclock ac;

  int sum;
  ac.measure();
  sumintarray(sum,v2,N,N);
  ac.measure();
  cout << "vector<int>" << endl;
  cout << SHOW(sum) << endl;
  cout << SHOW(ac.diff_ms()) << endl;


  ac.measure();
  sumintarray(sum,v3,N,N);
  ac.measure();
  cout << "dumbarray<int>" << endl;
  cout << SHOW(sum) << endl;
  cout << SHOW(ac.diff_ms()) << endl;

  int * v4 = & v2[0];
  ac.measure();
  sumintarray(sum,v4,N,N);
  ac.measure();
  cout << "int *" << endl;
  cout << SHOW(sum) << endl;
  cout << SHOW(ac.diff_ms()) << endl;
} 




