#ifndef ARRAY_HPP #define ARRAY_HPP #include #include #include #include #include const size_t INCREASE_FACTOR = 10; /* Arreglo (vector): region continua de memoria que almacena valores del mismo tipo Registro de memoria (record): region continua de memoria que puede almacenar valores (campos) de diferente tipo. No es Registro de CPU (register) Subrutina: region continua de memoria que almacena instrucciones que pueden ser ejecutadas (invocadas, llamadas) */ namespace ecci { /** * @brief * */ template class Array { private: /** * @brief * */ size_t count; size_t capacity; DataType* elements; public: /// Default constructor and NOT conversion constructor explicit Array(size_t initialCount = 0) : count(initialCount) , capacity(initialCount ? initialCount : initial_capacity) , elements(new DataType[this->capacity]()) { if (this->elements == nullptr) { this->capacity = 0; throw std::runtime_error("no memory to create dynamic array"); } // new operator: // Type* ptr = new Type calls constructor if Type is a record // Type* ptr = new Type() calls constructor always, eg double() // new[] operator: // Type* arr = new Type[capacity] calls constructor if Type is a record // Type* arr = new Type[capacity]() calls constructor always, eg double() } /// Copy constructor Array(const Array& other) : count(other.count) , capacity(other.capacity) , elements(new DataType[other.capacity]) { if (this->elements == nullptr) { this->capacity = 0; throw std::runtime_error("no memory to create copy of dynamic array"); } this->copy(other); } /// Move constructor Array(Array&& other) : count(other.count) , capacity(other.capacity) , elements(other.elements) { other.count = other.capacity = 0; other.elements = nullptr; } /// Destructor ~Array() { // delete ptr // delete[] arr delete[] this->elements; } /// Copy assignment operator Array& operator=(const Array& other) { if (this != &other) { if (this->capacity != other.capacity) { delete[] this->elements; this->elements = new DataType[other.capacity]; if (this->elements == nullptr) { throw std::runtime_error("no memory to copy existing dynamic array"); } this->capacity = other.capacity; } this->count = other.count; this->copy(other); } return *this; } /// Move assignment operator Array& operator=(Array&& other) { if (this != &other) { std::swap(this->count, other.count); std::swap(this->capacity, other.capacity); std::swap(this->elements, other.elements); } return *this; } public: // Accessors inline size_t getCount() const { return this->count; } inline const DataType& operator[](size_t index) const { return this->elements[index]; } inline DataType& operator[](size_t index) { return this->elements[index]; } public: /// Add an element to the rightmost empty space in the array void append(const DataType& value) { if (this->count == this->capacity) { this->increaseCapacity(); } this->elements[this->count++] = value; } void resize(size_t newCount) { if (newCount > this->capacity) { this->increaseCapacity(newCount); } this->count = newCount; } public: friend std::ostream& operator<<(std::ostream& out, const Array& array) { for (size_t index = 0; index < array.count; ++index) { out << array.elements[index] << (index < array.count - 1 ? "," : ""); } return out; } private: void increaseCapacity(size_t newCapacity = 0) { if (newCapacity == 0) { newCapacity = INCREASE_FACTOR * this->capacity; } DataType* newElements = new DataType[newCapacity]; if (newElements) { for (size_t index = 0; index < this->count; ++index) { newElements[index] = this->elements[index]; // copy semantics } delete[] this->elements; this->capacity = newCapacity; this->elements = newElements; } else { throw std::runtime_error("no memory to increase dynamic array capacity"); } } /// ... void copy(const Array& other) { assert(this->capacity >= other.capacity); for (size_t index = 0; index < other.count; ++index) { this->elements[index] = other.elements[index]; } } }; } // namespace ecci #if 0 template int increase_capacity(array_t* array) { assert(array); int error = EXIT_SUCCESS; size_t new_capacity = INCREASE_FACTOR * array->capacity; DataType* new_elements = (DataType*) realloc(array->elements, new_capacity * sizeof(DataType)); if (new_elements) { array->capacity = new_capacity; array->elements = new_elements; } else { error = EXIT_FAILURE; } return error; } #endif #endif // ARRAY_HPP