/**
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