Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/org.eclipse.etrice.runtime.cpp/src/common/containers/Vector.h')
-rw-r--r--runtime/org.eclipse.etrice.runtime.cpp/src/common/containers/Vector.h334
1 files changed, 334 insertions, 0 deletions
diff --git a/runtime/org.eclipse.etrice.runtime.cpp/src/common/containers/Vector.h b/runtime/org.eclipse.etrice.runtime.cpp/src/common/containers/Vector.h
new file mode 100644
index 000000000..065a58f9d
--- /dev/null
+++ b/runtime/org.eclipse.etrice.runtime.cpp/src/common/containers/Vector.h
@@ -0,0 +1,334 @@
+/*******************************************************************************
+ * 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_ */
+

Back to the top