// // Created by Patrick Maschek on 19.12.2023. // #ifndef UDIFF_IMMARRAY_H_ #define UDIFF_IMMARRAY_H_ #include #include #include #include #include "helper.h" namespace cc { template 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; using const_reverse_iterator = std::reverse_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 > constexpr const_vector(const T (&array)[aN]) noexcept;*/ constexpr explicit const_vector(const value_type (&array)[N]) noexcept; constexpr const_vector(std::initializer_list values) noexcept; template 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& operator=(const const_vector& other); constexpr const_vector& operator=(const_vector&& other) noexcept; constexpr const_vector& 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 const_vector(A[]) -> const_vector>; template const_vector(T...) -> const_vector, sizeof...(T)>; template constexpr const_vector::const_vector(const value_type &value) : _size(N) { std::fill(std::begin(_arr), std::end(_arr), value); } template constexpr const_vector::const_vector(size_type size, const value_type &value) { if (size > N) size = N; _size = size; std::fill(_arr, _arr + _size, value); } template constexpr const_vector::const_vector(const value_type (&array)[N]) noexcept : _size(N) { std::move(std::begin(array), std::end(array), _arr); } template constexpr const_vector::const_vector(std::initializer_list values) noexcept : _size(values.size()) { std::move(values.begin(), values.end(), _arr); } template template constexpr const_vector::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 constexpr const_vector::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 constexpr const_vector::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 constexpr const_vector &const_vector::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 constexpr const_vector &const_vector::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 constexpr const_vector &const_vector::operator=(const value_type (&array)[N]) noexcept { *this = array; return *this; } }; // cc #endif //UDIFF_IMMARRAY_H_