blob: 065a58f9d7b4f081a9b8b67b8e1d0bbe526d9be1 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2017 protos software gmbh (http://www.protos.de).
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* CONTRIBUTORS:
* Henrik Rentz-Reichert (initial contribution)
*
*******************************************************************************/
#ifndef VECTOR_H_
#define VECTOR_H_
#include "etDatatypes.h"
#include <cstring>
namespace etRuntime {
/**
* common vector base class with counters for allocations and deallocations
*/
class VectorStats {
public:
static size_t getNAllocations() { return nallocs; }
static size_t getNDeallocations() { return ndeallocs; }
static size_t getNCreated() { return ncreated; }
static size_t getNDestroyed() { return ndestroyed; }
private:
template<class T> friend class Vector;
static size_t nallocs;
static size_t ndeallocs;
static size_t ncreated;
static size_t ndestroyed;
};
template<class Type>
class Vector {
public:
typedef Type* iterator;
typedef const Type* const_iterator;
class reverse_iterator {
public:
reverse_iterator(Type* d) : _current(d) {}
reverse_iterator(const reverse_iterator& rhs) : _current(rhs._current) {}
reverse_iterator& operator=(const reverse_iterator& rhs) {
_current = rhs._current;
return *this;
}
Type operator*() const {
Type* tmp = _current;
return *(--tmp);
}
Type* operator->() const {
return &(operator*());
}
reverse_iterator& operator++() {
--_current;
return *this;
}
reverse_iterator operator++(int) {
reverse_iterator tmp = *this;
--_current;
return tmp;
}
reverse_iterator& operator--() {
++_current;
return *this;
}
reverse_iterator operator--(int) {
reverse_iterator tmp = *this;
++_current;
return tmp;
}
bool operator==(const reverse_iterator& rhs) const {
return _current == rhs._current;
}
bool operator!=(const reverse_iterator& rhs) const {
return !(operator==(rhs));
}
private:
Type* _current;
};
/**
* default constructor
*/
Vector()
: _size(0)
, _capacity(0)
, _data(0)
{
++VectorStats::ncreated;
}
/**
* copy constructor
*/
Vector(const Vector<Type> &rhs)
: _size(rhs._size)
, _capacity(rhs._size)
, _data(new Type[rhs._size])
{
++VectorStats::ncreated;
++VectorStats::nallocs;
for (int i = 0; i < _size; i++) {
_data[i] = rhs[i];
}
}
/**
* initializes each vector element to t
*/
Vector(size_t size, const Type& t=Type())
: _size(size)
, _capacity(size)
, _data(new Type[size])
{
++VectorStats::ncreated;
++VectorStats::nallocs;
for (int i = 0; i < _size; i++) {
_data[i] = t;
}
}
/**
* virtual destructor
*/
virtual ~Vector(void) {
++VectorStats::ndestroyed;
if (_data) {
delete[] _data;
++VectorStats::ndeallocs;
}
}
/**
* Requests that the vector capacity be at least enough to contain n elements.
*
* If n is greater than the current vector capacity, the function causes the container
* to reallocate its storage increasing its capacity to n (or greater).
* In all other cases, the function call does not cause a reallocation and the vector
* capacity is not affected.
*
* This function has no effect on the vector size and cannot alter its elements.
*/
void reserve(size_t n) {
if (n > _capacity) {
_capacity = n;
Type* new_data = new Type[_capacity];
++VectorStats::nallocs;
if (_data) {
for (int i = 0; i < _size; i++) {
new_data[i] = _data[i];
}
delete[] _data;
++VectorStats::ndeallocs;
}
_data = new_data;
}
}
/**
* returns the _size of this vector
*/
int size(void) const {
return _size;
}
/**
* Returns whether the vector is empty (i.e. whether its size is 0).
* This function does not modify the container in any way.
* To clear the content of a vector, see Vector::clear.
*/
bool empty(void) const {
return _size==0;
}
void clear() {
_size = 0;
_capacity = 0;
if (_data) {
delete[] _data;
++VectorStats::ndeallocs;
}
_data = 0;
}
void push_back(const Type& t) {
if (_size>=_capacity) {
reserve(_size + const_grow_by);
}
_data[_size++] = t;
}
void pop_back() {
if (_size>0) {
--_size;
}
}
iterator erase (iterator position) {
if (_size>0 && (position >= _data) && (position < _data+_size)) {
// copy following elements one position down each
iterator curr = position;
iterator next = position + 1;
for (; next!=end(); ++curr, ++next) {
*curr = *next;
}
--_size;
}
return position;
}
/**
* returns a pointer to the _data of this vector (as a C array)
*/
Type* getData(void) {
return this->_data;
}
/**
* returns a const pointer to the _data of this vector (as a C array)
*/
const Type* getData(void) const {
return this->_data;
}
/**
* indexed access without range check
*/
Type& operator[](int index) {
return _data[index];
}
/**
* indexed access without range check
*/
const Type& operator[](int index) const {
return _data[index];
}
Type& front() {
return _data[0];
}
const Type& front() const {
return _data[0];
}
Type& back() {
return _data[_size-1];
}
const Type& back() const {
return _data[_size-1];
}
/**
* copy assignment makes a deep copy
*/
Vector<Type>& operator=(const Vector<Type> &rhs) {
if (&rhs!=this) {
_size = rhs._size;
if (_size > _capacity) {
_capacity = _size;
if (_data) {
delete[] _data;
++VectorStats::ndeallocs;
}
_data = new Type[_capacity];
++VectorStats::nallocs;
}
for (int i = 0; i < _size; i++) {
_data[i] = rhs[i];
}
}
return *this;
}
/**
* comparison operator based on memcmp()
*/
bool operator==(const Vector<Type> &rhs) const {
return _size!=rhs._size ? false : std::memcmp(this->_data, rhs._data, _size*sizeof(*_data)) == 0;
}
bool operator!=(const Vector<Type> &rhs) const {
return !(operator==(rhs));
}
const_iterator begin() const {
return _data;
}
const_iterator end() const {
return _data + _size;
}
iterator begin() {
return _data;
}
iterator end() {
return _data + _size;
}
reverse_iterator rbegin() {
return reverse_iterator(_data + _size);
}
reverse_iterator rend() {
return reverse_iterator(_data);
}
protected:
size_t _size;
size_t _capacity;
Type* _data; ///< the C array holding the _data
static const size_t const_grow_by = 4;
};
} /* namespace etRuntime */
#endif /* VECTOR_H_ */