#pragma once #include #include #include namespace BAN { template class Array { public: using size_type = decltype(S); using value_type = T; using iterator = IteratorSimple; using const_iterator = ConstIteratorSimple; public: constexpr Array() = default; constexpr Array(const T&); iterator begin() { return iterator(m_data); } iterator end() { return iterator(m_data + size()); } const_iterator begin() const { return const_iterator(m_data); } const_iterator end() const { return const_iterator(m_data + size()); } constexpr const T& operator[](size_type) const; constexpr T& operator[](size_type); constexpr const T& back() const; constexpr T& back(); constexpr const T& front() const; constexpr T& front(); Span span() { return Span(m_data, size()); } const Span span() const { return Span(m_data, size()); } constexpr size_type size() const; constexpr const T* data() const { return m_data; } constexpr T* data() { return m_data; } private: T m_data[S] {}; }; template constexpr Array::Array(const T& value) { for (size_type i = 0; i < S; i++) m_data[i] = value; } template constexpr const T& Array::operator[](size_type index) const { ASSERT(index < S); return m_data[index]; } template constexpr T& Array::operator[](size_type index) { ASSERT(index < S); return m_data[index]; } template constexpr const T& Array::back() const { ASSERT(S != 0); return m_data[S - 1]; } template constexpr T& Array::back() { ASSERT(S != 0); return m_data[S - 1]; } template constexpr const T& Array::front() const { ASSERT(S != 0); return m_data[0]; } template constexpr T& Array::front() { ASSERT(S != 0); return m_data[0]; } template constexpr typename Array::size_type Array::size() const { return S; } }