//: C07:Stash3.cpp {O}
// From Thinking in C++, 2nd Edition
// Available at http://www.BruceEckel.com
// (c) Bruce Eckel 2000
// Copyright notice in Copyright.txt
// Function overloading

#include "Stash3.h"
#include "../require.h"
#include <iostream>
#include <cassert>
using namespace std;
const int increment = 100;

/* Questo esempio è simile a quello già proposto a lezione con il nome di Clib.cpp.
In questo caso però si hanno 2 diversi costruttori: Stash(int) e Stash(int, int) Il compilatore distinguere l'uno dall'altro a seconda del numero di paramentri passati*/

Stash::Stash(int sz)
{

size = sz;
quantity = 0;
next = 0;
storage = 0;

}


/* Questo costruttore oltre che assegnare "size = sz", passa la variabile "initQuantity", allocando la memoria per lo "storage" (attributo della classe). */

Stash::Stash(int sz, int initQuantity)
{

size = sz;
quantity = 0;
next = 0;
storage = 0;
inflate(initQuantity);

}

/* Il distruttore "~Stash" libera il collegamento tra l'attributo "storage"
e la zona di memoria precedentemente allocata. */

Stash::~Stash()
{

if(storage != 0)
{

cout << "freeing storage" << endl;
delete []storage;

}

}

int Stash::add(void* element)
{

/* Enough space left? */
if(next >= quantity)

inflate(increment);

/* Copy element into storage, starting at next empty space: */

int startBytes = next * size;
unsigned char* e = (unsigned char*)element;
for(int i = 0; i < size; i++)

storage[startBytes + i] = e[i];

next++;

/* Index number */

return(next - 1); 

}


void* Stash::fetch(int index)
{

/* La funzione di libreria "require" se non soddisfatta stampa la stringa che ha come argomento.*/

require(0 <= index, "Stash::fetch (-)index");
if(index >= next)

/* To indicate the end */
return 0; 

/* Produce pointer to desired element: */
return &(storage[index * size]);

}


int Stash::count()
{

/* Number of elements in CStash */
return next; 

}

void Stash::inflate(int increase)
{

/* La funzione di libreria "assert" se non soddisfatta termina l'esecuzione. */
assert(increase >= 0);
if(increase == 0) return;
int newQuantity = quantity + increase;
int newBytes = newQuantity * size;
int oldBytes = quantity * size;
unsigned char* b = new unsigned char[newBytes];
for(int i = 0; i < oldBytes; i++)

/* Copy old to new */
b[i] = storage[i]; 

/* Release old storage */
delete [](storage); 

/* Point to new memory */
storage = b; 

/* Adjust the size */
quantity = newQuantity; 

} ///:~