/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Copyright 2019 Danny Robson <danny@nerdcruft.net> */ #pragma once #include "../debug/assert.hpp" #include <array> #include <cstddef> #include <iterator> namespace cruft { /// A view of a compile-time sized array. /// /// \tparam S the number of elements /// \tparam T the data type of the elements template <std::size_t S, typename T> class varray { public: using iterator_category = std::random_access_iterator_tag; using value_type = T; using reference_type = T&; using pointer = T*; using difference_type = std::size_t; using size_type = std::size_t; //--------------------------------------------------------------------- varray (varray const &rhs) : m_data (rhs.m_data) { ; } //------------------------------------------------------------------------- varray (std::array<T,S> &rhs) : m_data (std::data (rhs)) { ; } varray (std::array<T,S> &&) = delete; //------------------------------------------------------------------------- varray (T (&_data)[S]) : m_data (_data) { ; } template <typename ContainerT> varray (ContainerT &_container) : varray (_container.data ()) { CHECK_GE (_container.size (), size ()); } //--------------------------------------------------------------------- std::size_t size (void) const { return S; } T& operator[] (std::size_t i) { CHECK_INDEX (i, S); return m_data[i]; } const T& operator[] (std::size_t i) const { CHECK_INDEX (i, S); return m_data[i]; } auto data (void) { return m_data; } auto data (void) const { return m_data; } auto begin (void) { return data (); } auto end (void) { return data () + size (); } auto begin (void) const { return data (); } auto end (void) const { return data () + size (); } auto cbegin (void) const { return data (); } auto cend (void) const { return data () + size (); } private: T *m_data; }; template <typename T, std::size_t S> varray (T(&)[S]) -> varray<S,T>; }