Driver Example


#include <iostream>
#include <cstdlib>
#include "Functions.h"

using std::cout;
using std::endl;

// generate random numbers between low and high 
int RandomInt(int low, int high)
{
  int number = std::rand() % (high - low + 1) + low;
  return number;
}

struct Student
{
  char login[9];
  int age;
  int year;
  double GPA;
};

std::ostream& operator<<(std::ostream& os, const Student& s)
{
  os << "(login) " << s.login << ", ";
  os << "(age) " << s.age << ", ";
  os << "(year) " << s.year << ", ";
  os << "(GPA) " << s.GPA << endl;
  return os;
}

bool operator>(const Student& lhs, const Student& rhs)
{
  return lhs.GPA > rhs.GPA;
}

bool operator<(const Student& lhs, const Student& rhs)
{
  return lhs.GPA < rhs.GPA;
}

void print_students(const Student *s, int size)
{
  for (int i = 0; i < size; i++)
    cout << s[i];
}

static void TestSwap1(void)
{
  cout << "***** TestSwap1 *****" << endl;

  int a = 5, b = 8;

  cout << "a = " << a << ", b = " << b << endl;
  CS170::swap(a, b);
  cout << "a = " << a << ", b = " << b << endl;
}

static void TestSwap2(void)
{
  cout << "***** TestSwap2 *****" << endl;
  Student s1 = {"jdoe", 20, 3, 3.82};
  Student s2 = {"fbar", 22, 1, 1.28};

  cout << "s1: " << s1;
  cout << "s2: " << s2;
  CS170::swap(s1, s2);
  cout << "s1: " << s1;
  cout << "s2: " << s2;
}

static void TestSwapRanges1(void)
{
  cout << "***** SwapRanges *****" << endl;
  int i1[] = {-1, 2, 6, -1, 9, 5, 7, -1, -1, 8, -1};
  int i2[] = {3, 6, 8, 0, -1, 5, -3, -9, 3, 5, 8};

  int size = sizeof(i1) / sizeof(int);

  CS170::display(i1, i1 + size);
  CS170::display(i2, i2 + size);
  CS170::swap_ranges(i1, i1 + size, i2);
  CS170::display(i1, i1 + size);
  CS170::display(i2, i2 + size);
}

static void TestRemove1(void)
{
  cout << "***** Remove1 *****" << endl;
  int i1[] = {5, -7, 4, 10, -21, 15, 9};

  int size = sizeof(i1) / sizeof(int);
  CS170::display(i1, i1 + size);
  int item = -1;
  int *newend = CS170::remove(i1, i1 + size,  item);
  cout << "remove " << item << ", new list: ";
  CS170::display(i1, newend);
}

static void TestRemove2(void)
{
  cout << "***** Remove2 *****" << endl;
  int i1[] = {5, -7, 4, 10, -7, 15, 9};

  int size = sizeof(i1) / sizeof(int);
  CS170::display(i1, i1 + size);
  int item = -7;
  int *newend = CS170::remove(i1, i1 + size,  item);
  cout << "remove " << item << ", new list: ";
  CS170::display(i1, newend);
}

static void TestRemove3(void)
{
  cout << "***** Remove3 *****" << endl;
  int i1[] = {-1, -1, -1, -1, -1, -1, -1};

  int size = sizeof(i1) / sizeof(int);
  CS170::display(i1, i1 + size);
  int item = -1;
  int *newend = CS170::remove(i1, i1 + size,  item);
  cout << "remove " << item << ", new list: ";
  CS170::display(i1, newend);
}

static void TestCount1(void)
{
  cout << "***** Count1 *****" << endl;
  int i1[] = {-1, 2, 6, -1, 9, 5, 7, -1, -1, 8, -1};

  int size = sizeof(i1) / sizeof(int);
  CS170::display(i1, i1 + size);
  int item = -1;
  int c = CS170::count(i1, i1 + size, item);
  cout << "Count of " << item << " is " << c << endl;
}

static void TestCount2(void)
{
  cout << "***** Count2 *****" << endl;
  int i1[] = {-1, 2, 6, -1, 9, 5, 7, -1, -1, 8, -1};

  int size = sizeof(i1) / sizeof(int);
  CS170::display(i1, i1 + size);
  int item = 50;
  int c = CS170::count(i1, i1 + size, item);
  cout << "Count of " << item << " is " << c << endl;
}

static void TestFind1(void)
{
  cout << "***** Find1 *****" << endl;
  const int i1[] = {-1, 2, 6, -1, 9, 5, 7, -1, -1, 8, -1};

  int size = sizeof(i1) / sizeof(int);
  const int *end = i1 + size;
  CS170::display(i1, end);
  const int item = 9;
  const int *pos = CS170::find(i1, end, item);
  if (pos != end)
    cout << "Item " << item << " is " << *pos << endl;
  else
    cout << "Item " << item << " was not found" << endl;
}


static void TestFind2(void)
{
  cout << "***** Find2 *****" << endl;
  int i1[] = {-1, 2, 6, -1, 9, 5, 7, -1, -1, 8, -1};

  int size = sizeof(i1) / sizeof(int);
  int *end = i1 + size;
  CS170::display(i1, end);
  const int item = 9;
  int *pos = CS170::find(i1, end, item);
  
  if (pos != end)
  {
    cout << "Changing " << item << " to 100" << endl;
    *pos = 100;
  }
  else
    cout << "Item " << item << " was not found" << endl;

  CS170::display(i1, end);
}

static void TestFind3(void)
{
  cout << "***** Find3 *****" << endl;
  const int i1[] = {-1, 2, 6, -1, 9, 5, 7, -1, -1, 8, -1};

  int size = sizeof(i1) / sizeof(int);
  const int *end = i1 + size;
  CS170::display(i1, end);
  const int item = 19;
  const int *pos = CS170::find(i1, end, item);
  if (pos != end)
    cout << "Item " << item << " is " << *pos << endl;
  else
    cout << "Item " << item << " was not found" << endl;
}

static void TestCopy1(void)
{
  cout << "***** Copy1 *****" << endl;
  const short i1[] = {-1, 2, 6, -1, 9, 5, 7, -1, -1, 8, -1};
  int size = sizeof(i1) / sizeof(short);
  short i2[20] = {0};

  CS170::display(i1, i1 + size);
  short *i2end = CS170::copy(i1, i1 + size, i2);
  CS170::display(i2, i2end);
}

static void TestFill1(void)
{
  cout << "***** Fill1 *****" << endl;
  int i1[10];
  int size = 10;

  CS170::fill(i1, i1 + size, 12);
  CS170::display(i1, i1 + size);
}

static void TestReplace1(void)
{
  cout << "***** Replace1 *****" << endl;
  int i1[] = {-1, 2, 6, -1, 9, 5, 7, -1, -1, 8, -1};
  int size = sizeof(i1) / sizeof(int);

  CS170::display(i1, i1 + size);
  int olditem = -1;
  int newitem = -8;
  cout << "Replacing " << olditem << " with " << newitem << endl;
  CS170::replace(i1, i1 + size, olditem, newitem);
  CS170::display(i1, i1 + size);
}

static void TestMin1(void)
{
  cout << "***** Min1 *****" << endl;
  const int i1[] = {-1, 2, 6, -31, 9, 5, 7, -21, -1, 8, -10};
  int size = sizeof(i1) / sizeof(int);

  CS170::display(i1, i1 + size);
  const int *pos = CS170::min_element(i1, i1 + size);

  cout << "The min element is: " << *pos << endl;
}

static void TestMin2(void)
{
  cout << "***** Min2 *****" << endl;
  int i1[] = {-1, 2, 6, -31, 9, 5, 7, -21, -1, 8, -10};
  int size = sizeof(i1) / sizeof(int);

  CS170::display(i1, i1 + size);
  int *pos = CS170::min_element(i1, i1 + size);

  cout << "The min element is: " << *pos << endl;
}

static void TestMin3(void)
{
  cout << "***** Min3 *****" << endl;
  Student s1[] = { {"jdoe", 20, 3, 3.82},
                   {"fbar", 22, 1, 1.28},
                   {"wxyz", 19, 3, 1.59},
                   {"abcd", 20, 1, 1.99},
                   {"jbar", 22, 2, 3.38}
                 };

  int size = sizeof(s1) / sizeof(*s1);
  Student *end = s1 + size;

  print_students(s1, size);
  Student *pos = CS170::min_element(s1, end);

  cout << "The min element is: " << *pos;
}


static void TestMax1(void)
{
  cout << "***** Max1 *****" << endl;
  const int i1[] = {-1, 2, 6, -31, 9, 5, 7, -21, -1, 8, -10};
  int size = sizeof(i1) / sizeof(int);

  CS170::display(i1, i1 + size);
  const int *pos = CS170::max_element(i1, i1 + size);

  cout << "The max element is: " << *pos << endl;
}

static void TestMax2(void)
{
  cout << "***** Max2 *****" << endl;
  int i1[] = {-1, 2, 6, -31, 9, 5, 7, -21, -1, 8, -10};
  int size = sizeof(i1) / sizeof(int);

  CS170::display(i1, i1 + size);
  int *pos = CS170::max_element(i1, i1 + size);

  cout << "The max element is: " << *pos << endl;
}

static void TestMax3(void)
{
  cout << "***** Max3 *****" << endl;
  Student s1[] = { {"jdoe", 20, 3, 3.82},
                   {"fbar", 22, 1, 1.28},
                   {"wxyz", 19, 3, 1.59},
                   {"abcd", 20, 1, 1.99},
                   {"jbar", 22, 2, 3.38}
                 };

  int size = sizeof(s1) / sizeof(*s1);
  Student *end = s1 + size;

  print_students(s1, size);
  Student *pos = CS170::max_element(s1, end);

  cout << "The max element is: " << *pos;
}

static void TestEqual1(void)
{
  cout << "***** Equal1 *****" << endl;
  int i1[] = {-1, 2, 6, -1, 9, 5, 7, -1, -1, 8, -1};
  short i2[] = {-1, 2, 6, -1, 9, 5, 7, -1, -1, 8, -1};

  int size = sizeof(i1) / sizeof(int);

  CS170::display(i1, i1 + size);
  CS170::display(i2, i2 + size);
  bool same = CS170::equal(i1, i1 + size, i2);
  if (same)
    std::cout << "Arrays are equal\n";
  else
    std::cout << "Arrays are not equal\n";
}

static void TestEqual2(void)
{
  cout << "***** Equal2 *****" << endl;
  int i1[] = {-1, 2, 6, -1, 9, 5, 7};
  short i2[] = {-1, 2, 6, -1, 9, 5, 7, -1, -1, 8, -1};

  int size1 = sizeof(i1) / sizeof(int);
  int size2 = sizeof(i2) / sizeof(int);

  CS170::display(i1, i1 + size1);
  CS170::display(i2, i2 + size2);
  bool same = CS170::equal(i1, i1 + size1, i2);
  if (same)
    std::cout << "Arrays are equal\n";
  else
    std::cout << "Arrays are not equal\n";
}

static void TestEqual3(void)
{
  cout << "***** Equal3 *****" << endl;
  int i1[] = {-1, 2, 6, -1, 9, 5, 7};
  short i2[] = {-1, 2, 6, -1, 9, 6, 7};

  int size1 = sizeof(i1) / sizeof(int);
  int size2 = sizeof(i2) / sizeof(short);

  CS170::display(i1, i1 + size1);
  CS170::display(i2, i2 + size2);
  bool same = CS170::equal(i1, i1 + size1, i2);
  if (same)
    std::cout << "Arrays are equal\n";
  else
    std::cout << "Arrays are not equal\n";
}

static void TestSum1(void)
{
  cout << "***** Sum1 *****" << endl;
  int i1[] = {3, 6, 8, 0, -1, 5, -3, -9, 3, 5, 8, -20, -5};

  int size = sizeof(i1) / sizeof(int);

  CS170::display(i1, i1 + size);
  int total = CS170::sum(i1, i1 + size);
  std::cout << "Sum is " << total << std::endl;
}

/*
static void TestStress1(void)
{
  cout << "***** Stress1 *****" << endl;
  
  int size = 100;
  int *array = new int[size];
  int low = 1;
  int high = 9;
  for (int i = 0; i < size; i++)
    array[i] = RandomInt(1, 9);

  int *begin = array;
  int *end = array + size;
  CS170::display(begin, end);

  int *newend = end;
  for (int i = low; i <= high; i++)
  {
    int item = i;
    newend = CS170::remove(begin, newend, item);
    cout << "remove " << item << ", new list: ";
    CS170::display(begin, newend);
  }
}
*/

static void TestStress2(void)
{
  cout << "***** Stress2 *****" << endl;
  
  int size = 10000000;
  int *array = new int[size];
  int low = -10;
  int high = 10;
  for (int i = 0; i < size; i++)
    array[i] = RandomInt(low, high);

  int *begin = array;
  int *end = array + size;
  //CS170::display(begin, end);

  int sum = CS170::sum(begin, end);
  std::cout << "Sum is " << sum << std::endl;

  int *newend = end;
  for (int i = low; i <= high; i++)
  {
    int item = i;
    newend = CS170::remove(begin, newend, item);
    sum = CS170::sum(begin, newend);
    cout << "remove " << item << ", sum is " << sum << std::endl;
    //std::cout << "new list: ";
    //CS170::display(begin, newend);
  }
}

static void TestStress3(void)
{
  cout << "***** Stress3 *****" << endl;
  
  int size = 10000000;
  int *array = new int[size];
  for (int i = 0; i < size; i++)
    array[i] = 1;

  for (int i = 1; i < size; i *= 10)
    array[i] = 5;

  int *begin = array;
  int *end = array + size;
  //CS170::display(begin, end);

  int sum = CS170::sum(begin, end);
  std::cout << "Sum is " << sum << std::endl;

  int *newend = end;
  int item = 1;
  newend = CS170::remove(begin, newend, item);
  sum = CS170::sum(begin, newend);
  cout << "remove " << item << ", sum is " << sum << std::endl;
  //std::cout << "new list: ";
  //CS170::display(begin, newend);
}

//***********************************************************************
//***********************************************************************
//***********************************************************************

typedef void (*TestFn)(void);

#define WATCHDOGx
#if defined(WATCHDOG) && !defined(_DEBUG)

#ifdef _MSC_VER
  #include <process.h>
  #include <stdlib.h>
  #include <windows.h>
  #include <time.h>
#endif

static bool Completed = false;

unsigned __stdcall ThreadTest(void *fn)
{
  Completed = false;

  clock_t start, end;
  try
  {
    TestFn testFn = reinterpret_cast<TestFn>(fn);
    start = clock();
    testFn();
    end = clock();
    Completed = true;
  }
  catch(...)
  {
    printf("Unexpected exception thrown in ThreadTest.\n");
  }

  return 0;
}

//typedef unsigned int (*TestFn) __stdcall (void *);

void ExecuteTest(TestFn fn, int maxwait = 1000, int safewait = 1000, int announce_level = 0)
{
#ifdef _MSC_VER
  HANDLE thread;
  unsigned threadID;

  thread = (HANDLE) _beginthreadex(NULL, 0, &ThreadTest, fn, 0, &threadID);

  clock_t start = clock();
  WaitForSingleObject(thread, maxwait);
  clock_t end = clock();
  CloseHandle(thread);

  if (!Completed)
    printf("\n********** Test test took too long to complete (over %i ms). **********\n", maxwait);
  else if (end - start > safewait)
    printf("\n********** Test took %i ms. (Inefficient) **********\n", end - start);
  else if (announce_level)
  {
    if (announce_level == 1)
      printf("\nTest completed within efficient time limit. (%i ms)\n", safewait);
    else
      printf("\nTest completed within efficient time limit. (%i ms, max=%i ms)\n", end - start, safewait);
  }

  printf("\n");
#endif
}
//***********************************************************************
//***********************************************************************
//***********************************************************************

#else // WATCHDOG

void ExecuteTest(TestFn fn, int maxwait = 1000, int safewait = 1000)
{
  if (maxwait + safewait > 0)
    fn();
}

#endif

int main(int argc, char **argv)
{
  int test_num = 0;
  if (argc > 1)
    test_num = std::atoi(argv[1]);

  struct TimedTest
  {
    void (*test)(void);
    int safewait;
    int maxwait;
  };

  TimedTest Tests[] = {
                       {TestSwap1,       100,  100}, //  1   
                       {TestSwap2,       100,  100}, //  2
                       {TestSwapRanges1, 100,  100}, //  3   
                       {TestRemove1,     100,  100}, //  4   
                       {TestRemove2,     100,  100}, //  5   
                       {TestRemove3,     100,  100}, //  6   
                       {TestCount1,      100,  100}, //  7   
                       {TestCount2,      100,  100}, //  8   
                       {TestFind1,       100,  100}, //  9   
                       {TestFind2,       100,  100}, // 10   
                       {TestFind3,       100,  100}, // 11   
                       {TestCopy1,       100,  100}, // 12   
                       {TestFill1,       100,  100}, // 13   
                       {TestReplace1,    100,  100}, // 14   
                       {TestMin1,        100,  100}, // 15   
                       {TestMin2,        100,  100}, // 16   
                       {TestMin3,        100,  100}, // 17   
                       {TestMax1,        100,  100}, // 18   
                       {TestMax2,        100,  100}, // 19   
                       {TestMax3,        100,  100}, // 20   
                       {TestEqual1,      100,  100}, // 21   
                       {TestEqual2,      100,  100}, // 22   
                       {TestEqual3,      100,  100}, // 23   
                       {TestSum1,        100,  100}, // 24   
                       {TestStress2,    3000, 6000}, // 25   
                       {TestStress3,     400, 1000}  // 26
                      };

  int num = sizeof(Tests) / sizeof(*Tests);
  if (test_num == 0)
  {
    for (int i = 0; i < num; i++)
      ExecuteTest(Tests[i].test, Tests[i].maxwait, Tests[i].safewait);
  }
  else if (test_num > 0 && test_num <= num)
  {
    ExecuteTest(Tests[test_num - 1].test, Tests[test_num - 1].maxwait, Tests[test_num - 1].safewait);
  }
  return 0;
}