165 lines
5.0 KiB
C++
165 lines
5.0 KiB
C++
//
|
|
// Created by Patrick Maschek on 19.12.2023.
|
|
//
|
|
|
|
#ifndef UDIFF_IMMARRAY_H_
|
|
#define UDIFF_IMMARRAY_H_
|
|
|
|
#include <algorithm>
|
|
#include <initializer_list>
|
|
#include <iterator>
|
|
#include <utility>
|
|
#include "helper.h"
|
|
|
|
namespace cc {
|
|
|
|
template<typename T, std::size_t N>
|
|
class const_vector {
|
|
|
|
static_assert(N > 0, "Capacity of const_vector has to be greater than 0");
|
|
|
|
public:
|
|
|
|
using value_type = T;
|
|
using size_type = std::size_t;
|
|
using difference_type = std::ptrdiff_t;
|
|
using reference = value_type&;
|
|
using const_reference = const value_type&;
|
|
using pointer = value_type *;
|
|
using const_pointer = const value_type *;
|
|
using iterator = pointer;
|
|
using const_iterator = const_pointer;
|
|
using reverse_iterator = std::reverse_iterator<iterator>;
|
|
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
|
|
|
protected:
|
|
T _arr[N] = {};
|
|
static constexpr const size_type _len = N;
|
|
size_type _size = 0;
|
|
|
|
public:
|
|
|
|
constexpr const_vector() noexcept = default;
|
|
|
|
constexpr explicit const_vector(const value_type &value);
|
|
constexpr const_vector(size_type size, const value_type &value);
|
|
|
|
/*template <std::size_t aN, typename = std::enable_if<aN < N>>
|
|
constexpr const_vector(const T (&array)[aN]) noexcept;*/
|
|
constexpr explicit const_vector(const value_type (&array)[N]) noexcept;
|
|
|
|
constexpr const_vector(std::initializer_list<value_type> values) noexcept;
|
|
|
|
template<std::input_iterator InputIt>
|
|
constexpr const_vector(InputIt first, InputIt last);
|
|
|
|
constexpr const_vector(const const_vector& other) noexcept;
|
|
constexpr const_vector(const_vector&& other) noexcept;
|
|
|
|
constexpr const_vector<T, N>& operator=(const const_vector& other);
|
|
constexpr const_vector<T, N>& operator=(const_vector&& other) noexcept;
|
|
constexpr const_vector<T, N>& operator=(const value_type (&array)[N]) noexcept;
|
|
|
|
[[nodiscard]] constexpr size_type size() const noexcept { return _size; }
|
|
|
|
constexpr T& operator[](size_type pos) { return _arr[pos]; }
|
|
constexpr const T& operator[](size_type pos) const { return _arr[pos]; }
|
|
|
|
#ifdef UNIT_TEST
|
|
friend test_const_vector;
|
|
#endif
|
|
|
|
};
|
|
|
|
template<typename A>
|
|
const_vector(A[]) -> const_vector<A, helper::array_size<A>>;
|
|
|
|
template<typename ...T>
|
|
const_vector(T...) -> const_vector<std::common_type_t<T...>, sizeof...(T)>;
|
|
|
|
|
|
|
|
template<typename T, std::size_t N>
|
|
constexpr const_vector<T, N>::const_vector(const value_type &value)
|
|
: _size(N)
|
|
{
|
|
std::fill(std::begin(_arr), std::end(_arr), value);
|
|
}
|
|
|
|
template<typename T, std::size_t N>
|
|
constexpr const_vector<T, N>::const_vector(size_type size, const value_type &value)
|
|
{
|
|
if (size > N) size = N;
|
|
_size = size;
|
|
std::fill(_arr, _arr + _size, value);
|
|
}
|
|
|
|
template<typename T, std::size_t N>
|
|
constexpr const_vector<T, N>::const_vector(const value_type (&array)[N]) noexcept
|
|
: _size(N)
|
|
{
|
|
std::move(std::begin(array), std::end(array), _arr);
|
|
}
|
|
|
|
template<typename T, std::size_t N>
|
|
constexpr const_vector<T, N>::const_vector(std::initializer_list<value_type> values) noexcept
|
|
: _size(values.size())
|
|
{
|
|
std::move(values.begin(), values.end(), _arr);
|
|
}
|
|
|
|
template<typename T, std::size_t N>
|
|
template<std::input_iterator InputIt>
|
|
constexpr const_vector<T, N>::const_vector(InputIt first, InputIt last) {
|
|
//static_assert(std::distance(first, last) > N, "tried inserting more elements than const_vector is in size");
|
|
_size = std::distance(first, last);
|
|
std::copy(first, last, _arr);
|
|
}
|
|
|
|
template<typename T, std::size_t N>
|
|
constexpr const_vector<T, N>::const_vector(const const_vector &other) noexcept {
|
|
static_assert(N >= other._size, "size of other has to be equal to or smaller than this");
|
|
std::copy(other._arr, other._arr, _arr);
|
|
}
|
|
|
|
template<typename T, std::size_t N>
|
|
constexpr const_vector<T, N>::const_vector(const_vector &&other) noexcept {
|
|
static_assert(N == other.N, "size of const_vectors does not match");
|
|
std::move(other.begin(), other.end(), _arr);
|
|
}
|
|
|
|
template<typename T, std::size_t N>
|
|
constexpr const_vector<T, N> &const_vector<T, N>::operator=(const const_vector &other)
|
|
{
|
|
if (this == &other) return *this;
|
|
|
|
static_assert(N == other._len, "Cannot assign const_vector to other with different size");
|
|
if (N != other.N) throw std::exception();
|
|
|
|
std::copy(other.begin(), other.end(), _arr);
|
|
|
|
return *this;
|
|
}
|
|
|
|
template<typename T, std::size_t N>
|
|
constexpr const_vector<T, N> &const_vector<T, N>::operator=(const_vector &&other) noexcept
|
|
{
|
|
static_assert(N == other._len, "Cannot assign const_vector to other with different size");
|
|
if (N != other.N) throw std::exception();
|
|
|
|
std::move(other.begin(), other.end(), _arr);
|
|
|
|
return *this;
|
|
}
|
|
|
|
template<typename T, std::size_t N>
|
|
constexpr const_vector<T, N> &const_vector<T, N>::operator=(const value_type (&array)[N]) noexcept
|
|
{
|
|
*this = array;
|
|
return *this;
|
|
}
|
|
|
|
}; // cc
|
|
|
|
#endif //UDIFF_IMMARRAY_H_
|