/** 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_ARRAY_HPP #define REXY_CX_ARRAY_HPP #include //size_t #include "../utility.hpp" //swap #include "detail/bool_specialize_base.hpp" #include namespace rexy::cx{ template class array { public: using value_type = T; using size_type = size_t; using difference_type = ptrdiff_t; using reference = T&; using const_reference = const T&; using pointer = T*; using const_pointer = const T*; using iterator = T*; using const_iterator = const T*; static constexpr size_type max_elements = N; private: T m_elements[N] = {}; public: constexpr reference at(size_type pos)noexcept{ return m_elements[pos]; } constexpr const_reference at(size_type pos)const noexcept{ return m_elements[pos]; } constexpr reference operator[](size_type pos)noexcept{ return m_elements[pos]; } constexpr const_reference operator[](size_type pos)const noexcept{ return m_elements[pos]; } constexpr reference front(void)noexcept{ return m_elements[0]; } constexpr const_reference front(void)const noexcept{ return m_elements[0]; } constexpr reference back(void)noexcept{ return m_elements[max_elements-1]; } constexpr const_reference back(void)const noexcept{ return m_elements[max_elements-1]; } constexpr pointer data(void)noexcept{ return m_elements; } constexpr const_pointer data(void)const noexcept{ return m_elements; } constexpr iterator begin(void)noexcept{ return m_elements; } constexpr const_iterator begin(void)const noexcept{ return m_elements; } constexpr const_iterator cbegin(void)const noexcept{ return m_elements; } constexpr iterator end(void)noexcept{ return m_elements+max_elements; } constexpr const_iterator end(void)const noexcept{ return m_elements+max_elements; } constexpr const_iterator cend(void)const noexcept{ return m_elements+max_elements; } constexpr bool empty(void)const noexcept{ if constexpr(max_elements == 0){ return true; }else{ return false; } } constexpr size_type size(void)const noexcept{ return max_elements; } constexpr size_type max_size(void)const noexcept{ return max_elements; } constexpr void fill(const T& value) noexcept(std::is_nothrow_copy_assignable::value) { for(auto it = begin();it != end();++it){ *it = value; } } constexpr void swap(array& other) noexcept(noexcept(swap(m_elements[0], other.m_elements[0]))) { for(size_type i = 0;i < max_size();++i){ swap(m_elements[i], other.m_elements[i]); } } }; template class array : public detail::bool_specialize_base { public: using value_type = bool; using size_type = bool_specialize_base::size_type; using difference_type = bool_specialize_base::difference_type; using reference = boolean; using const_reference = bool; using iterator = bool_iter; using const_iterator = const_bool_iter; static constexpr size_type max_elements = N; private: static constexpr size_type arr_size = (N / bits_per_byte) + (N % bits_per_byte == 0 ? 0 : 1); booleans m_elements[arr_size] = {}; public: constexpr reference at(size_type pos)noexcept{ auto [byte_count,bits_count] = convert_to_byte_bit_pair(pos); return m_elements[byte_count][bits_count]; } constexpr const_reference at(size_type pos)const noexcept{ auto [byte_count,bits_count] = convert_to_byte_bit_pair(pos); return m_elements[byte_count][bits_count]; } constexpr reference operator[](size_type pos)noexcept{ auto [byte_count,bits_count] = convert_to_byte_bit_pair(pos); return m_elements[byte_count][bits_count]; } constexpr const_reference operator[](size_type pos)const noexcept{ auto [byte_count,bits_count] = convert_to_byte_bit_pair(pos); return m_elements[byte_count][bits_count]; } constexpr reference front(void)noexcept{ return m_elements[0][0]; } constexpr const_reference front(void)const noexcept{ return m_elements[0][0]; } constexpr reference back(void)noexcept{ auto [byte_count,bits_count] = convert_to_byte_bit_pair(max_elements); return m_elements[byte_count][bits_count]; } constexpr const_reference back(void)const noexcept{ auto [byte_count,bits_count] = convert_to_byte_bit_pair(max_elements); return m_elements[byte_count][bits_count]; } constexpr iterator begin(void)noexcept{ return bool_iter{m_elements[0], 0}; } constexpr const_iterator begin(void)const noexcept{ return const_bool_iter{m_elements[0], 0}; } constexpr const_iterator cbegin(void)const noexcept{ return const_bool_iter{m_elements[0], 0}; } constexpr iterator end(void)noexcept{ auto [byte_count,bits_count] = convert_to_byte_bit_pair(max_elements); return bool_iter{m_elements[byte_count], bits_count}; } constexpr const_iterator end(void)const noexcept{ auto [byte_count,bits_count] = convert_to_byte_bit_pair(max_elements); return const_bool_iter{m_elements[byte_count], bits_count}; } constexpr const_iterator cend(void)const noexcept{ auto [byte_count,bits_count] = convert_to_byte_bit_pair(max_elements); return const_bool_iter{m_elements[byte_count], bits_count}; } constexpr bool empty(void)const noexcept{ if constexpr(max_elements == 0){ return true; }else{ return false; } } constexpr size_type size(void)const noexcept{ return max_elements; } constexpr size_type max_size(void)const noexcept{ return max_elements; } constexpr void fill(const value_type& value)noexcept{ for(auto it = begin();it != end();++it){ *it = value; } } constexpr void swap(array& other)noexcept{ for(size_type i = 0;i < arr_size;++i){ swap(m_elements[i], other.m_elements[i]); } } }; template array(T, Us...) -> array; } #endif