// final/test_extra.cpp

#include <assert.h>
#include <stdlib.h>
#include <time.h>
#include <new>
#include <memory>
#include <iostream>
#include "static_mem_pool.h"

#ifndef LOOPS
#define LOOPS 5000
#endif

#ifndef SEQUENCES
#define SEQUENCES 5000
#endif

#ifndef ITEMS
#define ITEMS 997
#endif

#ifndef BLKSIZE
#define BLKSIZE 100
#endif

using namespace std;

struct A {
    char buf[BLKSIZE];
};

struct B {
    char buf[BLKSIZE];
    DECLARE_STATIC_MEM_POOL(A);
};

struct C {
    char buf[BLKSIZE];
    DECLARE_STATIC_MEM_POOL_GROUPED__NOTHROW(A, 0);
};

A* a[ITEMS];
B* b[ITEMS];
C* c[ITEMS];
int r[SEQUENCES];

template <typename T>
void test(T* p[])
{
    clock_t t;
    int i, j, k;

    t = clock();
    for (i = 0; i < LOOPS; ++i) {
        for (j = 0; j < SEQUENCES; ++j) {
            k = r[j];
            if (p[k] == NULL) {
                p[k] = new T;
            } else {
                delete p[k];
                p[k] = NULL;
            }
        }
    }
    cout << (clock() - t) * 1.0 / CLOCKS_PER_SEC << endl;
}

int main()
{
    cout << "Generating random numbers...                               "
         << flush;
    for (int i = 0; i < SEQUENCES; ++i) {
        r[i] = rand() % ITEMS;
    }
    cout << "Done" << endl;

    cout << "Testing (de)allocation with system routines...             "
         << flush;
    test(a);
    cout << "Testing (de)allocation with default static_mem_pool...     "
         << flush;
    test(b);
    cout << "Testing (de)allocation with initialized static_mem_pool... "
         << flush;
    PREPARE_MEMORY_POOL_GROUPED(C, 0);
    test(c);

    return 0;
}