From 7a264e56805a452c147694c1617bff51e5e5150d Mon Sep 17 00:00:00 2001 From: L-Nafaryus Date: Mon, 17 Oct 2022 11:12:52 +0500 Subject: [PATCH] new arrays --- CMakeLists.txt | 2 + source/hyporo/hyplib/CMakeLists.txt | 14 + source/hyporo/hyplib/array/array.hpp | 16 ++ source/hyporo/hyplib/array/dynamic_array.hpp | 271 +++++++++++++++++++ source/hyporo/hyplib/array/iterator.hpp | 86 ++++++ source/hyporo/hyplib/array/static_array.hpp | 174 ++++++++++++ 6 files changed, 563 insertions(+) create mode 100644 source/hyporo/hyplib/array/array.hpp create mode 100644 source/hyporo/hyplib/array/dynamic_array.hpp create mode 100644 source/hyporo/hyplib/array/iterator.hpp create mode 100644 source/hyporo/hyplib/array/static_array.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 937d465..a42f4d1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,6 +7,8 @@ project( LANGUAGES CXX ) +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") option(WITH_GTESTS "Enable GTest unit testing" ON) diff --git a/source/hyporo/hyplib/CMakeLists.txt b/source/hyporo/hyplib/CMakeLists.txt index 02d6dc7..923f88a 100644 --- a/source/hyporo/hyplib/CMakeLists.txt +++ b/source/hyporo/hyplib/CMakeLists.txt @@ -2,6 +2,7 @@ include_directories( integer scalar + array vector matrix ) @@ -11,10 +12,20 @@ add_library(hyporo-hyplib STATIC # Header files integer/integer.hpp scalar/scalar.hpp + + array/iterator.hpp + array/dynamic_array.hpp + array/static_array.hpp + array/array.hpp + + vector/vector_space.hpp + vector/VectorSpace.hpp vector/vector.hpp + matrix/MatrixSpace.hpp matrix/matrix.hpp + io/file.hpp io/io.hpp @@ -33,4 +44,7 @@ if(WITH_GTESTS) ) gtest_add_tests(TARGET hyporo-hyplib-test) + + add_executable(mytest + tests/mytest.cpp) endif() diff --git a/source/hyporo/hyplib/array/array.hpp b/source/hyporo/hyplib/array/array.hpp new file mode 100644 index 0000000..36eaf96 --- /dev/null +++ b/source/hyporo/hyplib/array/array.hpp @@ -0,0 +1,16 @@ +#pragma once + +#include "dynamic_array.hpp" +#include "static_array.hpp" + + +namespace hpr +{ + +template +using darray = DynamicArray; + +template +using sarray = StaticArray; + +} \ No newline at end of file diff --git a/source/hyporo/hyplib/array/dynamic_array.hpp b/source/hyporo/hyplib/array/dynamic_array.hpp new file mode 100644 index 0000000..acbd25b --- /dev/null +++ b/source/hyporo/hyplib/array/dynamic_array.hpp @@ -0,0 +1,271 @@ +#pragma once + +#include "iterator.hpp" +#include + +namespace hpr +{ + +template +class DynamicArray +{ + +public: + + using difference_type = std::ptrdiff_t; + using value_type = Type; + using size_type = size_t; + using pointer = Type*; + using reference = Type&; + using iterator = Iterator; + using const_pointer = Type const*; + using const_reference = Type const&; + using const_iterator = Iterator const; + +protected: + + size_type p_size; + size_type p_capacity; + pointer p_start; + pointer p_end; + pointer p_storage_end; + +public: + + inline + DynamicArray() : + p_size {0}, + p_capacity {1}, + p_start {new value_type[p_capacity]}, + p_end {p_start}, + p_storage_end {p_end + p_capacity} + {} + + inline + DynamicArray(const DynamicArray& arr) : + p_size {arr.p_size}, + p_capacity {arr.p_capacity}, + p_start {new value_type[arr.p_size]}, + p_end {p_start + p_size}, + p_storage_end {p_start + p_capacity} + { + std::copy(arr.p_start, arr.p_end, p_start); + } + + //! Move constructor + inline + DynamicArray(DynamicArray&& arr) noexcept : + DynamicArray {} + { + swap(*this, arr); + } + + inline + DynamicArray(std::initializer_list list) : + p_size {list.size()}, + p_capacity {list.size()}, + p_start {new value_type[p_capacity]}, + p_end {p_start + p_size}, + p_storage_end {p_start + p_capacity} + { + std::copy(list.begin(), list.end(), p_start); + } + + inline + DynamicArray& operator=(DynamicArray&& arr) noexcept + { + swap(*this, arr); + return *this; + } + + virtual + ~DynamicArray() + { + //std::destroy(p_start, p_end); + delete[] p_start; + } + + // Member functions + + virtual + iterator begin() + { + return iterator(p_start); + } + + [[nodiscard]] virtual + const_iterator begin() const + { + return const_iterator(p_start); + } + + virtual + iterator end() + { + return iterator(p_end); + } + + virtual + const_iterator end() const + { + return const_iterator(p_end); + } + + + [[nodiscard]] virtual + size_type size() const + { + return size_type(p_end - p_start); + } + + [[nodiscard]] virtual + size_type capacity() const + { + return size_type(p_storage_end - p_start); + } + + [[nodiscard]] virtual + bool is_empty() const + { + return begin() == end(); + } + + virtual + reference operator[](size_type n) + { + return *(p_start + n); + } + + virtual + const_reference operator[](size_type n) const + { + return *(p_start + n); + } + + virtual + reference front() + { + return *p_start; + } + + virtual + reference back() + { + return *(p_end - 1); + } + + virtual + pointer data() + { + return p_start; + } + + [[nodiscard]] virtual + const_pointer data() const + { + return p_start; + } + + virtual + void resize(size_type newCapacity) + { + if (newCapacity == p_capacity) + return; + if (std::numeric_limits::max() - size() < newCapacity) + throw std::length_error("Wrong capacity value passed (possibly negative)"); + + pointer newStart = new value_type[newCapacity]; + + if (newCapacity > p_capacity) + { + std::move(p_start, p_end, newStart); + } + else if (newCapacity < p_capacity) + { + if (newCapacity < p_size) { + std::move(p_start, p_start + newCapacity, newStart); + p_size = newCapacity; + } + else + { + std::move(p_start, p_end, newStart); + } + } + + delete[] p_start; + std::swap(p_start, newStart); + p_capacity = newCapacity; + p_end = p_start + p_size; + p_storage_end = p_start + p_capacity; + } + + virtual + void push(const value_type& val) + { + if (p_end == p_storage_end) + resize(p_capacity * 2); + *p_end = val; + ++p_end; + ++p_size; + } + + virtual + void push(value_type&& val) + { + if (p_end == p_storage_end) + resize(p_capacity * 2); + *p_end = std::move(val); + ++p_end; + ++p_size; + } + + virtual + value_type pop() + { + if (is_empty()) + throw std::length_error("Cannot pop element from empty array"); + value_type val = back(); + std::destroy_at(p_end); + --p_end; + --p_size; + return val; + } + + virtual + void insert(size_type position, const value_type& val) + { + if (p_end == p_storage_end) + resize(p_capacity * 2); + for (size_type n = p_size; n > position; --n) + *(p_start + n) = std::move(*(p_start + n - 1)); + *(p_start + position) = val; + ++p_size; + ++p_end; + } + + virtual + void insert(size_type position, value_type&& val) + { + if (p_end == p_storage_end) + resize(p_capacity * 2); + for (size_type n = p_size; n > position; --n) + *(p_start + n) = std::move(*(p_start + n - 1)); + *(p_start + position) = std::move(val); + ++p_size; + ++p_end; + } + + // Friend functions + + friend + void swap(DynamicArray& lhs, DynamicArray& rhs) + { + std::swap(lhs.p_size, rhs.p_size); + std::swap(lhs.p_capacity, rhs.p_capacity); + std::swap(lhs.p_start, rhs.p_start); + std::swap(lhs.p_end, rhs.p_end); + std::swap(lhs.p_storage_end, rhs.p_storage_end); + } +}; + +} \ No newline at end of file diff --git a/source/hyporo/hyplib/array/iterator.hpp b/source/hyporo/hyplib/array/iterator.hpp new file mode 100644 index 0000000..f84faf9 --- /dev/null +++ b/source/hyporo/hyplib/array/iterator.hpp @@ -0,0 +1,86 @@ +#pragma once + +#include + + +namespace hpr +{ + +template +class Iterator +{ +public: + using iterator_category = Category; + using difference_type = std::ptrdiff_t; + using value_type = Type; + using pointer = Type*; + using reference = Type&; + using iterator = Iterator; + using const_pointer = Type const*; + using const_reference = Type const&; + using const_iterator = Iterator const; + +protected: + pointer p_ptr; + +public: + + Iterator() : + p_ptr {nullptr} + {} + + Iterator(pointer ptr) : + p_ptr {ptr} + {} + + reference operator*() + { + return *p_ptr; + } + + const_reference operator*() const + { + return *p_ptr; + } + + pointer operator->() + { + return p_ptr; + } + + const_pointer operator->() const + { + return p_ptr; + } + + iterator& operator++() + { + p_ptr++; + return *this; + } + + const_iterator& operator++() const + { + p_ptr++; + return *this; + } + + iterator operator++(int) + { + iterator temp {*this}; + ++(*this); + return temp; + } + + friend bool operator==(const iterator& lhs, const iterator& rhs) + { + return lhs.p_ptr == rhs.p_ptr; + } + + friend bool operator!=(const iterator& lhs, const iterator& rhs) + { + return lhs.p_ptr != rhs.p_ptr; + } +}; + +} diff --git a/source/hyporo/hyplib/array/static_array.hpp b/source/hyporo/hyplib/array/static_array.hpp new file mode 100644 index 0000000..1b01095 --- /dev/null +++ b/source/hyporo/hyplib/array/static_array.hpp @@ -0,0 +1,174 @@ +#pragma once + +#include "iterator.hpp" +#include + +namespace hpr +{ + +template +class StaticArray +{ + +public: + + using difference_type = std::ptrdiff_t; + using value_type = Type; + using size_type = size_t; + using pointer = Type*; + using reference = Type&; + using iterator = Iterator; + using const_pointer = Type const*; + using const_reference = Type const&; + using const_iterator = Iterator const; + +protected: + + const size_type p_size; + pointer p_start; + pointer p_end; + +protected: + + inline + StaticArray(size_type size, pointer start, pointer end) : + p_size {size}, + p_start {start}, + p_end {end} + {} + +public: + + inline + StaticArray() : + p_size {Size}, + p_start {new value_type[p_size] {}}, + p_end {p_start + p_size} + {} + + inline + StaticArray(const StaticArray& arr) : + p_size {arr.p_size}, + p_start {new value_type[arr.p_size]}, + p_end {p_start + p_size} + { + std::copy(arr.p_start, arr.p_end, p_start); + } + + //! Move constructor + inline + StaticArray(StaticArray&& arr) noexcept : + StaticArray {} + { + swap(*this, arr); + } + + inline + StaticArray(std::initializer_list list) : + p_size {Size}, + p_start {new value_type[p_size]}, + p_end {p_start + p_size} + { + std::copy(list.begin(), list.end(), p_start); + } + + inline + StaticArray& operator=(StaticArray&& arr) noexcept + { + swap(*this, arr); + return *this; + } + + virtual + ~StaticArray() + { + //std::destroy(p_start, p_end); + delete[] p_start; + } + + // Member functions + + virtual + iterator begin() + { + return iterator(p_start); + } + + [[nodiscard]] virtual + const_iterator begin() const + { + return const_iterator(p_start); + } + + virtual + iterator end() + { + return iterator(p_end); + } + + virtual + const_iterator end() const + { + return const_iterator(p_end); + } + + [[nodiscard]] virtual + size_type size() const + { + return size_type(p_end - p_start); + } + + [[nodiscard]] virtual + bool is_empty() const + { + return begin() == end(); + } + + virtual + reference operator[](size_type n) + { + return *(p_start + n); + } + + virtual + const_reference operator[](size_type n) const + { + return *(p_start + n); + } + + virtual + reference front() + { + return *p_start; + } + + virtual + reference back() + { + return *(p_end - 1); + } + + virtual + pointer data() + { + return p_start; + } + + [[nodiscard]] virtual + const_pointer data() const + { + return p_start; + } + + // Friend functions + + friend + void swap(StaticArray& lhs, StaticArray& rhs) + { + lhs.p_size = rhs.p_size; + std::swap(lhs.p_start, rhs.p_start); + std::swap(lhs.p_end, rhs.p_end); + } +}; + +}