new arrays

This commit is contained in:
L-Nafaryus 2022-10-17 11:12:52 +05:00
parent f43b2f4b44
commit 7a264e5680
6 changed files with 563 additions and 0 deletions

View File

@ -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)

View File

@ -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()

View File

@ -0,0 +1,16 @@
#pragma once
#include "dynamic_array.hpp"
#include "static_array.hpp"
namespace hpr
{
template <typename Type>
using darray = DynamicArray<Type>;
template <typename Type, size_t Size>
using sarray = StaticArray<Type, Size>;
}

View File

@ -0,0 +1,271 @@
#pragma once
#include "iterator.hpp"
#include <limits>
namespace hpr
{
template <typename Type>
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<Type>;
using const_pointer = Type const*;
using const_reference = Type const&;
using const_iterator = Iterator<Type> 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<value_type> 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<size_type>::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);
}
};
}

View File

@ -0,0 +1,86 @@
#pragma once
#include <iterator>
namespace hpr
{
template <typename Type, typename Category = std::forward_iterator_tag>
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;
}
};
}

View File

@ -0,0 +1,174 @@
#pragma once
#include "iterator.hpp"
#include <limits>
namespace hpr
{
template <typename Type, size_t Size>
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<Type>;
using const_pointer = Type const*;
using const_reference = Type const&;
using const_iterator = Iterator<Type> 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<value_type> 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);
}
};
}