#include "Mem.h"
#include "Err.h"
#include "Commun.h"
#include <iostream>
using namespace std;

void Mem::Test(int k){
	int i;
	cout<<"Mem::Test : ";
	for(i=0;i<k;i++) TestMalloc();
 	for(i=0;i<k;i++) TestCalloc();
  	for(i=0;i<k;i++) TestRealloc();
 	for(i=0;i<k;i++) TestFree();
	cout<<"OK"<<endl;
}

void Mem::TestMalloc(){
	const int b_ = 10;
	const int n_ = 1000;

	struct{int* p; int v; int t;} M[n_];
	for(int i=0;i<n_;i++)M[i].v=0;
	for(int i=0;i<n_;i++){
		int j=lrand(0,n_-1);
		if (M[j].v) {Mem::Free(M[j].p,M[j].t); M[j].v=0;}
		else {
			int v=lrand(); while (!v) v=lrand(); 
			int tb=lrand(1,b_);
			M[j].t=tb;M[j].v=v;
			M[j].p=Mem::Malloc(M[j].t);
			for(int k=0;k<M[j].t;k++) M[j].p[k]=v+k; 
		}
	}
	for(int i=0;i<n_;i++) if (M[i].v) for(int k=0;k<M[i].t;k++) EI("Mem::TestMalloc",M[i].p[k]==M[i].v+k);
}

void Mem::TestCalloc(){
	const int b_ = 10;
	const int n_ = 1000;

	struct{int* p; int v; int t;} M[n_];
	for(int i=0;i<n_;i++)M[i].v=0;
	for(int i=0;i<n_;i++){
		int j=lrand(0,n_-1);
		if (M[j].v) {Mem::Free(M[j].p,M[j].t); M[j].v=0;}
		else {
			int v=lrand(); while (!v) v=lrand(); 
			int tb=lrand(1,b_);
			M[j].t=tb;M[j].v=v;
			M[j].p=Mem::Calloc(M[j].t);
			for(int k=0;k<M[j].t;k++) EI("Mem::TestCalloc : different de zéro", M[j].p[k]==0);
			for(int k=0;k<M[j].t;k++) M[j].p[k]=v+k; 
		}
	}
	for(int i=0;i<n_;i++) if (M[i].v) for(int k=0;k<M[i].t;k++) EI("Mem::TestCalloc",M[i].p[k]==M[i].v+k);
}

void Mem::TestRealloc(){
	const int b_ = 10;
	const int n_ = 1000;

	struct{int* p; int v; int t;} M[n_];
	for(int i=0;i<n_;i++)M[i].v=0;
	for(int i=0;i<n_;i++){
		int j=lrand(0,n_-1);
		if (M[j].v) {
			int t1=M[j].t;
			int v=M[j].v;
			int tb=lrand(1,b_);
			M[j].t=tb;
			M[j].p=Mem::Realloc(M[j].p,t1,M[j].t);
			for(int k=t1;k<M[j].t;k++) M[j].p[k]=v+k;
		}
		else {
			int v=lrand(); while (!v) v=lrand(); 
			int tb=lrand(1,b_);
			M[j].t=tb;M[j].v=v;
			M[j].p=Mem::Malloc(M[j].t);
			for(int k=0;k<M[j].t;k++) M[j].p[k]=v+k; 
		}
	}
	for(int i=0;i<n_;i++) if (M[i].v) for(int k=0;k<M[i].t;k++) EI("Mem::TestRealloc",M[i].p[k]==M[i].v+k);
}
	
void Mem::TestFree(){
	const int b_ = 10;
	const int n_ = 1000;
	
	int Qi0 = Mem::Qi();

	struct{int* p; int v; int t;} M[n_];
	for(int i=0;i<n_;i++)M[i].v=0;
	for(int i=0;i<n_;i++){
		int j=lrand(0,n_-1);
		if (M[j].v) {Mem::Free(M[j].p,M[j].t); M[j].v=0;}
		else {
			int v=lrand(); while (!v) v=lrand(); 
			int tb=lrand(1,b_);
			M[j].t=tb;M[j].v=v;
			M[j].p=Mem::Malloc(M[j].t);
			for(int k=0;k<M[j].t;k++) M[j].p[k]=v+k; 
		}
	}
	for(int i=0;i<n_;i++) if (M[i].v) Mem::Free(M[i].p,M[i].t);
	EI("Land::TestFree",Mem::Qi()==Qi0);
}


