/* Lecture code 17.1
 *
 * Time trial pitting a regular C++ function against a C++ functor.
 * (Hint: the functor wins!)  Make sure you enable compiler optimization
 * before running this program; otherwise the results won't be
 * particularly impressive.
 */
#include <iostream>
#include <vector>
#include <ctime>
#include <algorithm>
using namespace std;

const size_t kNumElems = 100000; // Number of elements to check
const size_t kNumTests = 500;    // Number of comparisons

/* Function which compares two integers in reverse. */
bool CompareBackwards(int one, int two) {
	return two < one;
}

/* Tests out the function for sorting. */
void RunFunctionTest(const vector<int>& source) {
	vector<int> myContainer = source;
	
	clock_t start = clock();

	for(size_t h = 0; h < kNumTests; h++)
		sort(myContainer.begin(), myContainer.end(), CompareBackwards);

	start = clock() - start;

	cout << "Regular function finished in ";
	cout << ((double)(start) / CLOCKS_PER_SEC);
	cout << " seconds." << endl;
}

/* Functor class which compares backwards. */
class CompareBackwardsFunctor {
public:
	bool operator() (int one, int two) const {
		return two < one;
	}
};

/* Time the functor sorting data. */
void RunFunctorTest(const vector<int>& source) {
	vector<int> myContainer = source;

	clock_t start = clock();

	for(size_t h = 0; h < kNumTests; h++)
		sort(myContainer.begin(), myContainer.end(), CompareBackwardsFunctor());

	start = clock() - start;

	cout << "Custom functor finished in ";
	cout << ((double)(start) / CLOCKS_PER_SEC);
	cout << " seconds." << endl;
}

int main() {
	/* Make a random vector. */
	vector<int> sourceVector(kNumElems);
	generate(sourceVector.begin(), sourceVector.end(), rand);

	/* Pit the two against one another. */
	RunFunctionTest(sourceVector);
	RunFunctorTest(sourceVector);

	return 0;
}