/** This file is a part of rexy's general purpose library Copyright (C) 2020 rexy712 This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ #ifndef REXY_CX_VECTOR_HPP #define REXY_CX_VECTOR_HPP #include //size_t #include //move, forward #include "utility.hpp" //swap namespace rexy::cx{ template class vector { public: using value_type = T; using size_type = size_t; using difference_type = ptrdiff_t; using iterator = T*; using const_iterator = const T*; using reference = T&; using const_reference = const T&; using pointer = T*; using const_pointer = const T*; static constexpr size_type max_elements = N; private: T m_elements[N] = {}; size_type m_size = 0; public: constexpr vector(void) = default; constexpr vector(const vector&) = default; constexpr vector(vector&&) = default; constexpr vector(size_type count, const T& value){ for(size_type i = 0;i < min(count, max_elements);++i){ m_elements[i] = value; } } ~vector(void) = default; constexpr vector& operator=(const vector&) = default; constexpr vector& operator=(vector&&) = default; constexpr reference at(size_type pos){ return m_elements[pos]; } constexpr const_reference at(size_type pos)const{ return m_elements[pos]; } constexpr reference operator[](size_type pos){ return m_elements[pos]; } constexpr const_reference operator[](size_type pos)const{ return m_elements[pos]; } constexpr reference front(void){ return m_elements[0]; } constexpr const_reference front(void)const{ return m_elements[0]; } constexpr reference back(void){ return m_elements[m_size-1]; } constexpr const_reference back(void)const{ return m_elements[m_size-1]; } constexpr const_pointer data(void)const{ return m_elements; } constexpr iterator begin(void){ return m_elements; } constexpr const_iterator begin(void)const{ return m_elements; } constexpr const_iterator cbegin(void)const{ return m_elements; } constexpr iterator end(void){ return m_elements+max_elements; } constexpr const_iterator end(void)const{ return m_elements+max_elements; } constexpr const_iterator cend(void)const{ return m_elements+max_elements; } constexpr bool empty(void)const{ return m_size == 0; } constexpr size_type size(void)const{ return m_size; } constexpr size_type max_size(void)const{ return max_elements; } constexpr size_type capacity(void)const{ return max_elements; } constexpr void clear(void){ m_size = 0; } constexpr iterator insert(iterator pos, const T& value){ auto start = pos; auto it = pos; ++pos; for(;pos != end();++it,++pos){ *pos = std::move(*it); } *start = value; return start; } constexpr iterator insert(const_iterator pos, T&& value){ auto start = pos; auto it = pos; ++pos; for(;pos != end();++it,++pos){ *pos = std::move(*it); } *start = std::move(value); return start; } template constexpr iterator emplace(const_iterator pos, Args&&... args){ auto start = pos; auto it = pos; ++pos; for(;pos != end();++it,++pos){ *pos = std::move(*it); } *start = T{std::forward(args)...}; return start; } constexpr iterator erase(const_iterator pos){ auto start = pos; auto it = pos; ++pos; for(;pos != end();++it,++pos){ *it = std::move(*pos); } return start; } constexpr iterator push_back(const T& value){ m_elements[m_size] = value; return m_elements+(m_size++); } template constexpr iterator emplace_back(Args&&... args){ m_elements[m_size++] = T{std::forward(args)...}; return m_elements+(m_size++); } constexpr void pop_back(void){ --m_size; } constexpr void resize(size_type count){ if(count <= max_size()) m_size = count; } constexpr void resize(size_type count, const value_type& value){ if(count > m_size){ if(count <= max_size()){ for(size_type i = m_size;i < count;++i){ m_elements[i] = value; } } }else{ m_size = count; } } constexpr void fill(const T& value){ for(auto it = begin();it != end();++it){ *it = value; } } constexpr void swap(vector& other){ size_type i = 0; for(;i < m_size;++i){ swap(m_elements[i], other.m_elements[i]); } for(;i < other.m_size;++i){ swap(m_elements[i], other.m_elements[i]); } swap(m_size, other.m_size); } }; } #endif