Container.hh 2.49 KB
/*
 * Container.hh
 *
 *  Created on: Dec 10, 2012
 *      Author: f.casimir
 */

#ifndef CONTAINER_HH_
#define CONTAINER_HH_

#define NB_DATA_BY_BLOCK 100

namespace AMDA {
namespace Parameters {
/**
 * @brief To contain Data of an implementation of paramData
 * @detail use for stored time and data in ParamData
 * @see ParamData
 */
template <typename T>
class Container {
public:
	/**
	 * Constructor.
	 */
	Container() : _size(0) {}

	/**
	 * Destructor.
	 */
	virtual ~Container() {
		for(typename BlockDataTab::iterator it = _dataBlock.begin(); it != _dataBlock.end(); ++it) {
				if(*it) delete[] (*it);
				*it = NULL;
		}
	}

	/**
	 * @return the number of element of the container.
	 */
	unsigned int size() const { return _size; }

	/**
	 * @return element at index.
	 */
	const T& operator [] (unsigned int index) const {
		return _dataBlock[index / NB_DATA_BY_BLOCK][index % NB_DATA_BY_BLOCK];
	}

	/**
	 * @return element at index.
	 */
	const T& at(unsigned int index) const {
		return _dataBlock.at(index / NB_DATA_BY_BLOCK)[index % NB_DATA_BY_BLOCK];
	}

	/**
	 * To add one Element.
	 */
	void push_back(const T& data) {
		resize(1);
		unsigned int indexBlock = _size / (NB_DATA_BY_BLOCK );
		unsigned int indexinBlock = _size % (NB_DATA_BY_BLOCK );
		*(_dataBlock[indexBlock] + indexinBlock) = data;
		++_size;
	}

	void replace(const T& data, unsigned int index) {
		unsigned int indexBlock = index / (NB_DATA_BY_BLOCK );
		unsigned int indexinBlock = index % (NB_DATA_BY_BLOCK );
		*(_dataBlock[indexBlock] + indexinBlock) = data;
	}

	/**
	 * To increase the container capacity.
	 */
	void resize(unsigned int dataNumber) {
		///while reallocation is necessary
		while(_dataBlock.size() * NB_DATA_BY_BLOCK < (_size + dataNumber) ) {
			T *pt = new T[NB_DATA_BY_BLOCK];
			_dataBlock.push_back(pt);
		}
	}

	/**
	 * To release data bloc previous the index.
	 */
	void freeBefore(unsigned int pIndexMin) {
		//LOG4CXX_DEBUG(_logger, "freeBefore of ParamData: "<< (void *)this << " before index : "<< pIndexMin << " nb Data " << size());
		unsigned int lIndexBlock = 0;
		unsigned lIndexBlockMin = pIndexMin  / NB_DATA_BY_BLOCK;
		while(lIndexBlock  < lIndexBlockMin ) {
			if(_dataBlock[lIndexBlock]) delete[] _dataBlock[lIndexBlock];
			_dataBlock[lIndexBlock] = NULL;
			++lIndexBlock;
		}
	}

	void pop() { --_size; }

private:
	/**
	 * number of data
	 */
	unsigned int _size;
	typedef std::vector<T*> BlockDataTab;
	BlockDataTab _dataBlock;
};

} /* namespace Parameters */
} /* namespace AMDA */
#endif /* CONTAINER_HH_ */