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

int get_rand()
{
    double rnorm = ((double)rand())/((double)RAND_MAX);
    return (int)(rnorm*1000.0);
}

class select_func {
    int m_min, m_max;
public:
    select_func(int min, int max) : m_min(min), m_max(max) {}
    ~select_func() {}
    bool operator()(int x) { return x >= m_min && x < m_max; }
};

class CpuHog {
    vector<int> m_data;
public:

    void fill_data() {
        for (int i = 0; i < 1e6; ++i) {
            m_data.push_back(get_rand());
        }
    }
    void sort_data() {
        sort(m_data.begin(),m_data.end());
    }
    void select_data(int min, int max) {
        typedef vector<int> VI;

        VI::iterator first=m_data.begin(), last = m_data.end();
        VI::iterator middle = partition(first,last,
                                                 select_func(min,max));
        VI new_data;
        back_insert_iterator<VI> vii(new_data);
        copy(first,middle,vii);
        m_data = new_data;
    }
    void dump_data() {
        cout << "There are " << m_data.size() << " data elements\n";
    }
};

void cpu_hog(int min, int max)
{
    CpuHog ch;

    ch.fill_data();

#ifdef OPTIMIZE
    ch.select_data(min,max);
    ch.sort_data();
#else
    ch.sort_data();
    ch.select_data(min,max);
#endif
    ch.dump_data();
}

void runner1()
{
    int x1 = get_rand(), x2 = get_rand();
    if (x1 < x2) cpu_hog(x1,x2);
    else cpu_hog(x2,x1);
}
void runner2()
{
    int x1 = get_rand(), x2 = get_rand();
    if (x1 < x2) cpu_hog(x1,x2);
    else cpu_hog(x2,x1);
}

void run_it()
{
    vector<int> blah;
    for (int i = 0; i < 1e6; ++i) blah.push_back(get_rand());
    sort(blah.begin(),blah.end());
    cout << "Uselessly sorted 1e6 ints\n";

    for (int run = 0; run < 10; ++run) {
        if (run%2) runner1();
        else runner2();
    }
}

int main (int argc, char *argv[])
{
    run_it();
} // end of main()
